Skip to content

Commit 9960ae0

Browse files
committed
- separated Response API for F# and C#
- moved Response.API to NBomber project
1 parent 6006cbb commit 9960ae0

16 files changed

+172
-24
lines changed

examples/CSharpDev/Features/CustomSettings/config.json

+2-2
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
"ScenariosSettings": [
99
{
1010
"ScenarioName": "my_scenario",
11-
"WarmUpDuration": "00:00:00",
11+
"WarmUpDuration": "00:00:05",
1212

1313
"LoadSimulationsSettings": [
1414
{ "RampConstant": [10, "00:00:05"] },
@@ -25,7 +25,7 @@
2525
],
2626

2727
"ReportFileName": "my_report_name",
28-
"ReportFolder": "./my_reports",
28+
"ReportFolder": "./reports",
2929
"ReportFormats": [ "Html", "Md", "Txt", "Csv" ]
3030
}
3131
}

examples/CSharpDev/HelloWorld/EmptyScenario.cs

-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
using System;
22
using System.Threading.Tasks;
3-
using NBomber.Contracts;
43
using NBomber.CSharp;
54

65
namespace CSharpDev.HelloWorld;

examples/CSharpDev/HelloWorld/HelloWorldExample.cs

-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
using System;
22
using System.Threading.Tasks;
3-
using NBomber.Contracts;
43
using NBomber.CSharp;
54

65
namespace CSharpDev.HelloWorld;

examples/CSharpDev/HelloWorld/ParallelScenarios.cs

-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
using System;
22
using System.Threading.Tasks;
3-
using NBomber.Contracts;
43
using NBomber.CSharp;
54

65
namespace CSharpDev.HelloWorld;

examples/CSharpDev/HelloWorld/ScenarioWithInit.cs

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
using System;
22
using System.Threading.Tasks;
3-
using NBomber.Contracts;
43
using NBomber.CSharp;
54

65
namespace CSharpDev.HelloWorld;
@@ -18,11 +17,13 @@ public void Run()
1817
.WithLoadSimulations(Simulation.KeepConstant(copies: 1, during: TimeSpan.FromSeconds(10)))
1918
.WithInit(context =>
2019
{
20+
// You can do here any initialization logic: populate the database, etc.
2121
context.Logger.Information("MY INIT");
2222
return Task.CompletedTask;
2323
})
2424
.WithClean(context =>
2525
{
26+
// You can do here any cleaning logic: clearing the database, etc.
2627
context.Logger.Information("MY CLEAN");
2728
return Task.CompletedTask;
2829
});

examples/CSharpDev/HelloWorld/ScenarioWithStepRetry.cs

-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
using System;
22
using System.Threading.Tasks;
3-
using NBomber.Contracts;
43
using NBomber.CSharp;
54

65
namespace CSharpDev.HelloWorld;

examples/CSharpDev/HelloWorld/ScenarioWithSteps.cs

-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
using System;
22
using System.Threading.Tasks;
3-
using NBomber.Contracts;
43
using NBomber.CSharp;
54

65
namespace CSharpDev.HelloWorld;

examples/CSharpDev/HelloWorld/ScenarioWithTimeout.cs

-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
using System;
22
using System.Threading;
33
using System.Threading.Tasks;
4-
using NBomber.Contracts;
54
using NBomber.CSharp;
65

76
namespace CSharpDev.HelloWorld;

examples/CSharpDev/Http/SimpleHttpTest.cs

-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
using System;
22
using System.Net.Http;
3-
using NBomber.Contracts;
43
using NBomber.CSharp;
54

65
namespace CSharpDev.Http;

examples/CSharpDev/Mqtt/SimpleMqttTest.cs

+3-2
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
using MQTTnet.Client;
55
using MQTTnet.Client.Connecting;
66
using MQTTnet.Client.Options;
7-
using NBomber.Contracts;
87
using NBomber.CSharp;
98

109
namespace CSharpDev.Mqtt;
@@ -31,7 +30,9 @@ public void Run()
3130
return result.ResultCode == MqttClientConnectResultCode.Success
3231
? Response.Ok()
3332
: Response.Fail(
34-
$"MQTT connection code is: {result.ResultCode}, reason: {result.ReasonString}");
33+
statusCode: MqttClientConnectResultCode.Success.ToString(),
34+
message: $"MQTT connection code is: {result.ResultCode}, reason: {result.ReasonString}"
35+
);
3536
});
3637

3738
var subscribe = await Step.Run("subscribe", ctx, async () =>

src/NBomber/Api/CSharp.fs

+88
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,94 @@ open NBomber
1111
open NBomber.Contracts
1212
open NBomber.Contracts.Stats
1313

14+
type Response() =
15+
16+
static let _okEmpty = { StatusCode = ""; IsError = false; SizeBytes = 0; Message = ""; LatencyMs = 0; Payload = None }
17+
static let _failEmpty = { StatusCode = ""; IsError = true; SizeBytes = 0; Message = ""; LatencyMs = 0; Payload = None }
18+
19+
static member Ok() = _okEmpty
20+
static member Fail() = _failEmpty
21+
22+
static member Ok(
23+
[<Optional;DefaultParameterValue("")>] statusCode: string,
24+
[<Optional;DefaultParameterValue(0)>] sizeBytes: int,
25+
[<Optional;DefaultParameterValue("")>] message: string,
26+
[<Optional;DefaultParameterValue(0.0)>] latencyMs: float) : Response<obj> =
27+
28+
{ StatusCode = statusCode
29+
IsError = false
30+
SizeBytes = sizeBytes
31+
Message = if isNull message then String.Empty else message
32+
LatencyMs = latencyMs
33+
Payload = None }
34+
35+
static member Ok<'T>(
36+
[<Optional;DefaultParameterValue("")>] statusCode: string,
37+
[<Optional;DefaultParameterValue(0)>] sizeBytes: int,
38+
[<Optional;DefaultParameterValue("")>] message: string,
39+
[<Optional;DefaultParameterValue(0.0)>] latencyMs: float) : Response<'T> =
40+
41+
{ StatusCode = statusCode
42+
IsError = false
43+
SizeBytes = sizeBytes
44+
Message = if isNull message then String.Empty else message
45+
LatencyMs = latencyMs
46+
Payload = None }
47+
48+
static member Ok<'T>(
49+
payload: 'T,
50+
[<Optional;DefaultParameterValue("")>] statusCode: string,
51+
[<Optional;DefaultParameterValue(0)>] sizeBytes: int,
52+
[<Optional;DefaultParameterValue("")>] message: string,
53+
[<Optional;DefaultParameterValue(0.0)>] latencyMs: float) : Response<'T> =
54+
55+
{ StatusCode = statusCode
56+
IsError = false
57+
SizeBytes = sizeBytes
58+
Message = if isNull message then String.Empty else message
59+
LatencyMs = latencyMs
60+
Payload = Some payload }
61+
62+
static member Fail(
63+
[<Optional;DefaultParameterValue("")>] statusCode: string,
64+
[<Optional;DefaultParameterValue("")>] message: string,
65+
[<Optional;DefaultParameterValue(0)>] sizeBytes: int,
66+
[<Optional;DefaultParameterValue(0.0)>] latencyMs: float) : Response<obj> =
67+
68+
{ StatusCode = statusCode
69+
IsError = true
70+
SizeBytes = sizeBytes
71+
Message = if isNull message then String.Empty else message
72+
LatencyMs = latencyMs
73+
Payload = None }
74+
75+
static member Fail<'T>(
76+
[<Optional;DefaultParameterValue("")>] statusCode: string,
77+
[<Optional;DefaultParameterValue("")>] message: string,
78+
[<Optional;DefaultParameterValue(0)>] sizeBytes: int,
79+
[<Optional;DefaultParameterValue(0.0)>] latencyMs: float) : Response<'T> =
80+
81+
{ StatusCode = statusCode
82+
IsError = true
83+
SizeBytes = sizeBytes
84+
Message = if isNull message then String.Empty else message
85+
LatencyMs = latencyMs
86+
Payload = None }
87+
88+
static member Fail<'T>(
89+
payload: 'T,
90+
[<Optional;DefaultParameterValue("")>] statusCode: string,
91+
[<Optional;DefaultParameterValue("")>] message: string,
92+
[<Optional;DefaultParameterValue(0)>] sizeBytes: int,
93+
[<Optional;DefaultParameterValue(0.0)>] latencyMs: float) : Response<'T> =
94+
95+
{ StatusCode = statusCode
96+
IsError = true
97+
SizeBytes = sizeBytes
98+
Message = if isNull message then String.Empty else message
99+
LatencyMs = latencyMs
100+
Payload = Some payload }
101+
14102
/// Step represents a single user action like login, logout, etc.
15103
type Step =
16104

src/NBomber/Api/FSharp.fs

+36
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,42 @@ open NBomber.Errors
2020
open NBomber.Domain.ScenarioContext
2121
open NBomber.DomainServices
2222

23+
type Response() =
24+
25+
static let _okEmpty = { StatusCode = ""; IsError = false; SizeBytes = 0; Message = ""; LatencyMs = 0; Payload = None }
26+
static let _failEmpty = { StatusCode = ""; IsError = true; SizeBytes = 0; Message = ""; LatencyMs = 0; Payload = None }
27+
28+
static member ok () = _okEmpty
29+
static member fail () = _failEmpty
30+
31+
static member ok<'T>(
32+
?payload: 'T,
33+
?statusCode: string,
34+
?sizeBytes: int,
35+
?message: string,
36+
?latencyMs: float) =
37+
38+
{ StatusCode = statusCode |> Option.defaultValue ""
39+
IsError = false
40+
SizeBytes = sizeBytes |> Option.defaultValue 0
41+
Message = message |> Option.defaultValue ""
42+
LatencyMs = latencyMs |> Option.defaultValue 0
43+
Payload = payload }
44+
45+
static member fail<'T>(
46+
?statusCode: string,
47+
?message: string,
48+
?payload: 'T,
49+
?sizeBytes: int,
50+
?latencyMs: float) =
51+
52+
{ StatusCode = statusCode |> Option.defaultValue ""
53+
IsError = true
54+
SizeBytes = sizeBytes |> Option.defaultValue 0
55+
Message = message |> Option.defaultValue ""
56+
LatencyMs = latencyMs |> Option.defaultValue 0
57+
Payload = payload }
58+
2359
/// Step represents a single user action like login, logout, etc.
2460
[<RequireQualifiedAccess>]
2561
type Step =

src/NBomber/Contracts.fs

+28
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,9 @@ type NBomberContext = {
5050

5151
namespace NBomber.Contracts.Internal
5252

53+
open System
5354
open CommandLine
55+
open NBomber
5456
open NBomber.Configuration
5557
open NBomber.Contracts
5658
open NBomber.Contracts.Stats
@@ -88,3 +90,29 @@ type SessionArgs = {
8890

8991
member this.GetScenariosSettings() = this.NBomberConfig.GlobalSettings.Value.ScenariosSettings.Value
9092
member this.GetUseHintsAnalyzer() = this.NBomberConfig.GlobalSettings.Value.EnableHintsAnalyzer.Value
93+
94+
module internal ResponseInternal =
95+
96+
let emptyFail<'T> : Response<'T> =
97+
{ StatusCode = ""
98+
IsError = true
99+
SizeBytes = 0
100+
Message = String.Empty
101+
LatencyMs = 0
102+
Payload = None }
103+
104+
let failUnhandled<'T> (ex: Exception) : Response<'T> =
105+
{ StatusCode = Constants.UnhandledExceptionCode
106+
IsError = true
107+
SizeBytes = 0
108+
LatencyMs = 0
109+
Message = ex.Message
110+
Payload = None }
111+
112+
let failTimeout<'T> : Response<'T> =
113+
{ StatusCode = Constants.TimeoutStatusCode
114+
IsError = true
115+
SizeBytes = 0
116+
LatencyMs = 0
117+
Message = "operation timeout"
118+
Payload = None }

src/NBomber/Domain/Scenario.fs

+4-4
Original file line numberDiff line numberDiff line change
@@ -188,8 +188,8 @@ let measure (name: string) (ctx: ScenarioContext) (run: IScenarioContext -> Task
188188
let context = ctx :> IScenarioContext
189189
context.Logger.Fatal(ex, $"Operation timeout for Scenario : {0}", context.ScenarioInfo.ScenarioName)
190190

191-
let error = Response.fail(message = "operation timeout", statusCode = Constants.TimeoutStatusCode)
192-
let result = { Name = name; ClientResponse = error; EndTimeMs = endTime; LatencyMs = latency }
191+
let response = ResponseInternal.failTimeout
192+
let result = { Name = name; ClientResponse = response; EndTimeMs = endTime; LatencyMs = latency }
193193
ctx.StatsActor.Publish(AddMeasurement result)
194194

195195
| ex ->
@@ -199,7 +199,7 @@ let measure (name: string) (ctx: ScenarioContext) (run: IScenarioContext -> Task
199199
let context = ctx :> IScenarioContext
200200
context.Logger.Fatal(ex, $"Unhandled exception for Scenario: {0}", context.ScenarioInfo.ScenarioName)
201201

202-
let error = Response.fail(ex, statusCode = Constants.UnhandledExceptionCode)
203-
let result = { Name = name; ClientResponse = error; EndTimeMs = endTime; LatencyMs = latency }
202+
let response = ResponseInternal.failUnhandled ex
203+
let result = { Name = name; ClientResponse = response; EndTimeMs = endTime; LatencyMs = latency }
204204
ctx.StatsActor.Publish(AddMeasurement result)
205205
}

src/NBomber/Domain/Step.fs

+8-7
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ module internal NBomber.Domain.Step
33

44
open System
55
open System.Threading.Tasks
6-
open NBomber
76
open NBomber.Contracts
87
open NBomber.Contracts.Internal
98
open NBomber.Domain.ScenarioContext
@@ -27,10 +26,11 @@ let measure (name: string) (ctx: ScenarioContext) (run: unit -> Task<Response<'T
2726
let context = ctx :> IScenarioContext
2827
context.Logger.Fatal(ex, $"Operation timeout for Scenario: {0}, Step: {1}", context.ScenarioInfo.ScenarioName, name)
2928

30-
let error = Response.fail<'T>(message = "operation timeout", statusCode = Constants.TimeoutStatusCode)
31-
let result = { Name = name; ClientResponse = error; EndTimeMs = endTime; LatencyMs = latency }
29+
let response = ResponseInternal.failTimeout
30+
let result = { Name = name; ClientResponse = response; EndTimeMs = endTime; LatencyMs = latency }
31+
3232
ctx.StatsActor.Publish(AddMeasurement result)
33-
return error
33+
return response
3434

3535
| ex ->
3636
let endTime = ctx.Timer.Elapsed.TotalMilliseconds
@@ -39,8 +39,9 @@ let measure (name: string) (ctx: ScenarioContext) (run: unit -> Task<Response<'T
3939
let context = ctx :> IScenarioContext
4040
context.Logger.Fatal(ex, $"Unhandled exception for Scenario: {0}, Step: {1}", context.ScenarioInfo.ScenarioName, name)
4141

42-
let error = Response.fail<'T>(ex, statusCode = Constants.UnhandledExceptionCode)
43-
let result = { Name = name; ClientResponse = error; EndTimeMs = endTime; LatencyMs = latency }
42+
let response = ResponseInternal.failUnhandled ex
43+
let result = { Name = name; ClientResponse = response; EndTimeMs = endTime; LatencyMs = latency }
44+
4445
ctx.StatsActor.Publish(AddMeasurement result)
45-
return error
46+
return response
4647
}

src/NBomber/NBomber.fsproj

+1-1
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@
6969
</ItemGroup>
7070

7171
<ItemGroup>
72-
<PackageReference Include="NBomber.Contracts" Version="[4.0.0-beta5]" />
72+
<PackageReference Include="NBomber.Contracts" Version="[4.0.0-beta6]" />
7373
<PackageReference Include="CommandLineParser" Version="2.8.0" />
7474
<PackageReference Include="CsvHelper" Version="27.2.1" />
7575
<PackageReference Include="FSharp.UMX" Version="1.1.0" />

0 commit comments

Comments
 (0)