Skip to content

Commit

Permalink
added Scenario.MaxFailCount
Browse files Browse the repository at this point in the history
removed NBomberRunner.MaxFailCount
  • Loading branch information
AntyaDev committed Oct 30, 2022
1 parent 26775e1 commit 6006cbb
Show file tree
Hide file tree
Showing 19 changed files with 48 additions and 60 deletions.
14 changes: 7 additions & 7 deletions src/NBomber/Api/CSharp.fs
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,13 @@ type Scenario =
static member WithResetIterationOnFail(scenario: ScenarioProps, shouldReset: bool) =
scenario |> FSharp.Scenario.withResetIterationOnFail shouldReset

/// Sets and overrides the default max fail count.
/// When a scenario reaches max fail count, NBomber will stop the whole load test.
/// By default MaxFailCount = 5_000
[<Extension>]
static member WithMaxFailCount(scenario: ScenarioProps, failCount: int) =
scenario |> FSharp.Scenario.withMaxFailCount failCount

[<Extension>]
type NBomberRunner =

Expand Down Expand Up @@ -171,13 +178,6 @@ type NBomberRunner =
static member EnableHintsAnalyzer(context: NBomberContext, enable: bool) =
context |> FSharp.NBomberRunner.enableHintsAnalyzer enable

/// Sets and overrides the default max fail count.
/// In case of any scenario is reaching max fail count, then NBomber will stop the whole load test.
/// By default MaxFailCount = 5_000
[<Extension>]
static member WithMaxFailCount(context: NBomberContext, failCount: int) =
context |> FSharp.NBomberRunner.withMaxFailCount failCount

[<Extension>]
static member Run(context: NBomberContext) =
match FSharp.NBomberRunner.run context with
Expand Down
18 changes: 10 additions & 8 deletions src/NBomber/Api/FSharp.fs
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,8 @@ module Scenario =
Run = Some run
WarmUpDuration = Some Constants.DefaultWarmUpDuration
LoadSimulations = [LoadSimulation.KeepConstant(copies = Constants.DefaultCopiesCount, during = Constants.DefaultSimulationDuration)]
ResetIterationOnFail = true }
ResetIterationOnFail = true
MaxFailCount = Constants.ScenarioMaxFailCount }

/// Creates empty scenario.
/// An empty scenario is useful when you want to create the scenario to do only initialization or cleaning and execute it separately.
Expand All @@ -68,7 +69,8 @@ module Scenario =
Run = None
WarmUpDuration = None
LoadSimulations = [LoadSimulation.KeepConstant(copies = Constants.DefaultCopiesCount, during = Constants.DefaultSimulationDuration)]
ResetIterationOnFail = true }
ResetIterationOnFail = true
MaxFailCount = Constants.ScenarioMaxFailCount }

/// Initializes scenario.
/// You can use it to for example to prepare your target system or to parse and apply configuration.
Expand Down Expand Up @@ -102,6 +104,12 @@ module Scenario =
let withResetIterationOnFail (shouldReset: bool) (scenario: ScenarioProps) =
{ scenario with ResetIterationOnFail = shouldReset }

/// Sets and overrides the default max fail count.
/// When a scenario reaches max fail count, NBomber will stop the whole load test.
/// By default MaxFailCount = 5_000
let withMaxFailCount (failCount: int) (scenario: ScenarioProps) =
{ scenario with MaxFailCount = failCount }

/// NBomberRunner is responsible for registering and running scenarios.
/// Also it provides configuration points related to infrastructure, reporting, loading plugins.
[<RequireQualifiedAccess>]
Expand Down Expand Up @@ -228,12 +236,6 @@ module NBomberRunner =
let enableHintsAnalyzer (enable: bool) (context: NBomberContext) =
{ context with EnableHintsAnalyzer = enable }

/// Sets and overrides the default max fail count.
/// In case of any scenario is reaching max fail count, then NBomber will stop the whole load test.
/// By default MaxFailCount = 5_000
let withMaxFailCount (failCount: int) (context: NBomberContext) =
{ context with MaxFailCount = failCount }

let internal executeCliArgs (args) (context: NBomberContext) =

let loadConfigFn (loadConfig) (configPath) (context) =
Expand Down
2 changes: 1 addition & 1 deletion src/NBomber/Configuration.fs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ type ScenarioSetting = {
WarmUpDuration: TimeSpan option
LoadSimulationsSettings: LoadSimulation list option
[<JsonField(AsJson = true)>] CustomSettings: string option
MaxFailCount: int option
}

type GlobalSettings = {
Expand All @@ -19,7 +20,6 @@ type GlobalSettings = {
ReportFormats: ReportFormat list option
ReportingInterval: TimeSpan option
EnableHintsAnalyzer: bool option
MaxFailCount: int option
}

type NBomberConfig = {
Expand Down
2 changes: 1 addition & 1 deletion src/NBomber/Constants.fs
Original file line number Diff line number Diff line change
Expand Up @@ -67,4 +67,4 @@ let EmptyInfraConfig = ConfigurationBuilder().Build() :> IConfiguration
[<Literal>]
let StatsRounding = 2
[<Literal>]
let DefaultMaxFailCount = 5_000
let ScenarioMaxFailCount = 5_000
3 changes: 0 additions & 3 deletions src/NBomber/Contracts.fs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ type NBomberContext = {
WorkerPlugins: IWorkerPlugin list
EnableHintsAnalyzer: bool
TargetScenarios: string list option
MaxFailCount: int
} with

[<CompiledName("Empty")>]
Expand All @@ -47,7 +46,6 @@ type NBomberContext = {
WorkerPlugins = List.empty
EnableHintsAnalyzer = false
TargetScenarios = None
MaxFailCount = Constants.DefaultMaxFailCount
}

namespace NBomber.Contracts.Internal
Expand Down Expand Up @@ -83,7 +81,6 @@ type SessionArgs = {
member this.GetReportingInterval() = this.NBomberConfig.GlobalSettings.Value.ReportingInterval.Value
member this.GetReportFolder() = this.NBomberConfig.GlobalSettings.Value.ReportFolder.Value
member this.GetTargetScenarios() = this.NBomberConfig.TargetScenarios.Value
member this.GetMaxFailCount() = this.NBomberConfig.GlobalSettings.Value.MaxFailCount.Value

member this.SetTargetScenarios(targetScenarios) =
let nbConfig = { this.NBomberConfig with TargetScenarios = Some targetScenarios }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ type ScenarioScheduler(scnCtx: ScenarioContextArgs, scenarioClusterCount: int) =
_oneTimeScheduler.Stop()

let execScheduler () =
if _isWorking && scnCtx.ScenarioStatsActor.ScenarioFailCount > scnCtx.MaxFailCount then
if _isWorking && scnCtx.ScenarioStatsActor.ScenarioFailCount > _scenario.MaxFailCount then
stop()
scnCtx.ExecStopCommand(StopCommand.StopTest $"Stopping test because of too many fails. Scenario '{_scenario.ScenarioName}' contains '{scnCtx.ScenarioStatsActor.ScenarioFailCount}' fails.")

Expand Down
1 change: 1 addition & 0 deletions src/NBomber/Domain/DomainTypes.fs
Original file line number Diff line number Diff line change
Expand Up @@ -40,4 +40,5 @@ type Scenario = {
IsEnabled: bool // used for stats in the cluster mode
IsInitialized: bool
ResetIterationOnFail: bool
MaxFailCount: int
}
22 changes: 12 additions & 10 deletions src/NBomber/Domain/Scenario.fs
Original file line number Diff line number Diff line change
Expand Up @@ -76,20 +76,21 @@ let createScenarioInfo (scenarioName: string, duration: TimeSpan, threadNumber:

let createScenario (scn: ScenarioProps) = result {
let! timeline = scn.LoadSimulations |> LoadTimeLine.createWithDuration
let! scenario = Validation.validate scn
let! scnProps = Validation.validate scn

return { ScenarioName = scenario.ScenarioName
Init = scenario.Init
Clean = scenario.Clean
Run = scenario.Run
return { ScenarioName = scnProps.ScenarioName
Init = scnProps.Init
Clean = scnProps.Clean
Run = scnProps.Run
LoadTimeLine = timeline.LoadTimeLine
WarmUpDuration = scenario.WarmUpDuration
WarmUpDuration = scnProps.WarmUpDuration
PlanedDuration = timeline.ScenarioDuration
ExecutedDuration = None
CustomSettings = String.Empty
IsEnabled = true
IsInitialized = false
ResetIterationOnFail = scn.ResetIterationOnFail }
ResetIterationOnFail = scnProps.ResetIterationOnFail
MaxFailCount = scnProps.MaxFailCount }
}

let createScenarios (scenarios: ScenarioProps list) = result {
Expand Down Expand Up @@ -125,13 +126,14 @@ let applySettings (settings: ScenarioSetting list) (scenarios: Scenario list) =
{ scenario with LoadTimeLine = timeLine.LoadTimeLine
WarmUpDuration = settings.WarmUpDuration
PlanedDuration = timeLine.ScenarioDuration
CustomSettings = settings.CustomSettings |> Option.defaultValue "" }
CustomSettings = settings.CustomSettings |> Option.defaultValue ""
MaxFailCount = settings.MaxFailCount |> Option.defaultValue Constants.ScenarioMaxFailCount }

scenarios
|> List.map(fun scn ->
settings
|> List.tryPick(fun x ->
if x.ScenarioName = scn.ScenarioName then Some(scn, x)
|> List.tryPick(fun setting ->
if setting.ScenarioName = scn.ScenarioName then Some(scn, setting)
else None
)
|> Option.map updateScenario
Expand Down
1 change: 0 additions & 1 deletion src/NBomber/Domain/ScenarioContext.fs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ type ScenarioContextArgs = {
ScenarioOperation: ScenarioOperation
ScenarioStatsActor: ScenarioStatsActor
ExecStopCommand: StopCommand -> unit
MaxFailCount: int
}

type ScenarioContext(scenarioInfo, args: ScenarioContextArgs) =
Expand Down
14 changes: 0 additions & 14 deletions src/NBomber/DomainServices/NBomberContext.fs
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,7 @@

open System
open System.IO

open FsToolkit.ErrorHandling

open NBomber
open NBomber.Extensions.Internal
open NBomber.Configuration
Expand Down Expand Up @@ -105,16 +103,6 @@ let getEnableHintAnalyzer (context: NBomberContext) =
|> tryGetFromConfig
|> Option.defaultValue context.EnableHintsAnalyzer

let getMaxFailCount (context: NBomberContext) =
let tryGetFromConfig (ctx: NBomberContext) = option {
let! config = ctx.NBomberConfig
let! settings = config.GlobalSettings
return! settings.MaxFailCount
}
context
|> tryGetFromConfig
|> Option.defaultValue context.MaxFailCount

let private getReportFolder (context: NBomberContext) =
let tryGetFromConfig (ctx: NBomberContext) = option {
let! config = ctx.NBomberConfig
Expand Down Expand Up @@ -171,7 +159,6 @@ let createSessionArgs (testInfo: TestInfo) (scenarios: DomainTypes.Scenario list
let! reportingInterval = context |> getReportingInterval
let! scenariosSettings = context |> getScenariosSettings scenarios
let enableHintsAnalyzer = context |> getEnableHintAnalyzer
let maxFailCount = context |> getMaxFailCount

let nbConfig = {
TestSuite = Some testInfo.TestSuite
Expand All @@ -184,7 +171,6 @@ let createSessionArgs (testInfo: TestInfo) (scenarios: DomainTypes.Scenario list
ReportFormats = Some reportFormats
ReportingInterval = Some reportingInterval
EnableHintsAnalyzer = Some enableHintsAnalyzer
MaxFailCount = Some maxFailCount
}
}

Expand Down
1 change: 0 additions & 1 deletion src/NBomber/DomainServices/TestHost/TestHost.fs
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,6 @@ type internal TestHost(dep: IGlobalDependency, regScenarios: Scenario list) as t
ScenarioOperation = operation
ScenarioStatsActor = createStatsActor _log scn (_sessionArgs.GetReportingInterval())
ExecStopCommand = execStopCommand
MaxFailCount = _sessionArgs.GetMaxFailCount()
}
let count = getScenarioClusterCount scn.ScenarioName
new ScenarioScheduler(scnDep, count)
Expand Down
2 changes: 1 addition & 1 deletion src/NBomber/NBomber.fsproj
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@
</ItemGroup>

<ItemGroup>
<PackageReference Include="NBomber.Contracts" Version="[4.0.0-beta4]" />
<PackageReference Include="NBomber.Contracts" Version="[4.0.0-beta5]" />
<PackageReference Include="CommandLineParser" Version="2.8.0" />
<PackageReference Include="CsvHelper" Version="27.2.1" />
<PackageReference Include="FSharp.UMX" Version="1.1.0" />
Expand Down
5 changes: 3 additions & 2 deletions src/NBomber/Resources/HtmlReport/assets/js/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -196,8 +196,9 @@ const initApp = (appContainer, viewModel) => {
props: ['stepStats', 'showCharts'],
template: '#status-codes-template',
data: function() {
const allOkStatuses = this.stepStats.flatMap(x => x.Ok.StatusCodes);
const allFailStatuses = this.stepStats.flatMap(x => x.Fail.StatusCodes);
const globalInfo = this.stepStats.find(x => x.StepName === 'global information');
const allOkStatuses = globalInfo.Ok.StatusCodes;
const allFailStatuses = globalInfo.Fail.StatusCodes;

const okReqCount = this.stepStats.reduce((acc, val) => acc + val.Ok.Request.Count, 0);
const failReqCount = this.stepStats.reduce((acc, val) => acc + val.Fail.Request.Count, 0);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,6 @@ let internal baseScnDep = {
ScenarioOperation = ScenarioOperation.Bombing
ScenarioStatsActor = ScenarioStatsActor(logger, baseScenario, Constants.DefaultReportingInterval)
ExecStopCommand = fun _ -> ()
MaxFailCount = Constants.DefaultMaxFailCount
}

[<Fact>]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,6 @@ let internal baseScnDep = {
ScenarioOperation = ScenarioOperation.Bombing
ScenarioStatsActor = ScenarioStatsActor(logger, baseScenario, Constants.DefaultReportingInterval)
ExecStopCommand = fun _ -> ()
MaxFailCount = Constants.DefaultMaxFailCount
}

[<Fact>]
Expand Down
7 changes: 4 additions & 3 deletions tests/NBomber.IntegrationTests/Configuration/test_config.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,9 @@
"TargetHost": "localhost",
"MsgSizeInBytes": 1000,
"PauseMs": 100
}
},

"MaxFailCount": 500
}
],

Expand All @@ -33,7 +35,6 @@
"ReportFormats": ["Html", "Txt"],
"ReportingInterval": "00:00:30",
"EnableHintsAnalyzer": false,
"DefaultStepTimeoutMs" : 200,
"MaxFailCount": 500
"DefaultStepTimeoutMs" : 200
}
}
2 changes: 1 addition & 1 deletion tests/NBomber.IntegrationTests/NBomberContextTests.fs
Original file line number Diff line number Diff line change
Expand Up @@ -26,14 +26,14 @@ let baseGlobalSettings = {
ReportFormats = None
ReportingInterval = None
EnableHintsAnalyzer = None
MaxFailCount = None
}

let baseScenarioSetting = {
ScenarioName = "test_scenario"
WarmUpDuration = None
LoadSimulationsSettings = None
CustomSettings = None
MaxFailCount = None
}

let baseScenario =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,7 @@ let ``Test execution should be stopped if too many errors`` () =
|> NBomberRunner.run
|> Result.getOk
|> fun stats ->
test <@ stats.ScenarioStats[0].Fail.Request.Count >= Constants.DefaultMaxFailCount @>
test <@ stats.ScenarioStats[0].Fail.Request.Count >= Constants.ScenarioMaxFailCount @>

[<Fact>]
let ``withMaxFailCount should configure MaxFailCount`` () =
Expand All @@ -197,14 +197,14 @@ let ``withMaxFailCount should configure MaxFailCount`` () =
})
|> Scenario.withoutWarmUp
|> Scenario.withLoadSimulations [InjectPerSec(1, duration)]
|> Scenario.withMaxFailCount maxFailCount

NBomberRunner.registerScenarios [scenario1]
|> NBomberRunner.withoutReports
|> NBomberRunner.withMaxFailCount maxFailCount
|> NBomberRunner.run
|> Result.getOk
|> fun stats ->
test <@ stats.ScenarioStats[0].Fail.Request.Count <> Constants.DefaultMaxFailCount @>
test <@ stats.ScenarioStats[0].Fail.Request.Count <> Constants.ScenarioMaxFailCount @>
test <@ stats.ScenarioStats[0].Fail.Request.Count = 2 @>

[<Fact>]
Expand All @@ -225,10 +225,10 @@ let ``MaxFailCount should be tracked only for scenarios failures, not steps fail
|> Scenario.withoutWarmUp
|> Scenario.withResetIterationOnFail false
|> Scenario.withLoadSimulations [KeepConstant(10, duration)]
|> Scenario.withMaxFailCount maxFailCount

NBomberRunner.registerScenarios [scenario1]
|> NBomberRunner.withoutReports
|> NBomberRunner.withMaxFailCount maxFailCount
|> NBomberRunner.run
|> Result.getOk
|> fun stats ->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ let ``applyScenariosSettings() should override initial settings if the scenario
WarmUpDuration = Some warmUp1
LoadSimulationsSettings = Some [LoadSimulation.KeepConstant(10, duration1)]
CustomSettings = Some "some data"
MaxFailCount = Some Constants.ScenarioMaxFailCount
}

let originalScenarios =
Expand Down Expand Up @@ -58,6 +59,7 @@ let ``applyScenariosSettings() should skip applying settings when scenario name
WarmUpDuration = Some warmUp1
LoadSimulationsSettings = Some [LoadSimulation.RampConstant(5, duration1)]
CustomSettings = None
MaxFailCount = Some Constants.ScenarioMaxFailCount
}

let scenario =
Expand Down

0 comments on commit 6006cbb

Please sign in to comment.