Skip to content

Commit 3b59e4e

Browse files
committed
bombardier binaries update, more tests, bombardier inline JSON body instead of files, switch generation improvement
1 parent ee3b7cf commit 3b59e4e

File tree

10 files changed

+382
-78
lines changed

10 files changed

+382
-78
lines changed

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ Major features:
1010
- Library takes `IList<HttpTestRequest>` object, which can be produced in your code or can be imported from other sources. One example can be QAToolKit Swagger library that can produce that object with many options. Check it out [here](https://github.com/qatoolkit/qatoolkit-source-swagger-net).
1111
- Generate a Bombardier report that can be exported to the format you want.
1212

13+
Bombardier version [1.2.5](https://github.com/codesenberg/bombardier/releases/tag/v1.2.5) is used for `windows-amd64` and `linux-amd64`.
14+
1315
## Sample
1416

1517
```csharp

bombardier/linux/bombardier

-848 KB
Binary file not shown.

bombardier/win/bombardier.exe

-50.5 KB
Binary file not shown.

src/QAToolKit.Engine.Bombardier.Test/BombardierTestsGeneratorTests.cs

Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
using System.IO;
88
using System.Linq;
99
using System.Net.Http;
10+
using System.Text;
1011
using System.Threading.Tasks;
1112
using Xunit;
1213
using Xunit.Abstractions;
@@ -121,5 +122,132 @@ public async Task GenerateBombardierTestWithOptionsVariation4Test_Successfull()
121122
Assert.Equal(HttpMethod.Get, bombardierTests.FirstOrDefault().Method);
122123
Assert.Equal("/pet/10", bombardierTests.FirstOrDefault().Url.ToString());
123124
}
125+
126+
[Fact]
127+
public async Task GenerateBombardierTestWithOptionsVariation5Test_Successfull()
128+
{
129+
130+
var bombardierTestsGenerator = new BombardierTestsGenerator(options =>
131+
{
132+
options.BombardierConcurrentUsers = 1;
133+
options.BombardierDuration = 1;
134+
options.BombardierTimeout = 30;
135+
options.BombardierUseHttp2 = true;
136+
options.BombardierRateLimit = 20;
137+
options.BombardierNumberOfTotalRequests = 22;
138+
});
139+
140+
var content = File.ReadAllText("Assets/getPetById.json");
141+
var httpRequest = JsonConvert.DeserializeObject<IList<HttpRequest>>(content);
142+
143+
var bombardierTests = await bombardierTestsGenerator.Generate(httpRequest);
144+
145+
Assert.NotNull(bombardierTests);
146+
Assert.Single(bombardierTests);
147+
Assert.Contains(" -m GET https://petstore3.swagger.io/api/v3/pet/10 -c 1 --http2 --timeout=30s --duration=1s --rate=20 --requests=22", bombardierTests.FirstOrDefault().Command);
148+
Assert.Equal(HttpMethod.Get, bombardierTests.FirstOrDefault().Method);
149+
Assert.Equal("/pet/10", bombardierTests.FirstOrDefault().Url.ToString());
150+
}
151+
152+
[Fact]
153+
public async Task GenerateBombardierTestWithOptionsApiKeyTest_Successfull()
154+
{
155+
156+
var bombardierTestsGenerator = new BombardierTestsGenerator(options =>
157+
{
158+
options.AddApiKey("1234");
159+
options.BombardierConcurrentUsers = 1;
160+
options.BombardierDuration = 1;
161+
options.BombardierTimeout = 30;
162+
options.BombardierUseHttp2 = true;
163+
options.BombardierRateLimit = 20;
164+
options.BombardierNumberOfTotalRequests = 22;
165+
});
166+
167+
var content = File.ReadAllText("Assets/getPetById.json");
168+
var httpRequest = JsonConvert.DeserializeObject<IList<HttpRequest>>(content);
169+
170+
var bombardierTests = await bombardierTestsGenerator.Generate(httpRequest);
171+
172+
Assert.NotNull(bombardierTests);
173+
Assert.Single(bombardierTests);
174+
Assert.Contains(" -m GET https://petstore3.swagger.io/api/v3/pet/10 -c 1 -H \"ApiKey: 1234\" --http2 --timeout=30s --duration=1s --rate=20 --requests=22", bombardierTests.FirstOrDefault().Command);
175+
Assert.Equal(HttpMethod.Get, bombardierTests.FirstOrDefault().Method);
176+
Assert.Equal("/pet/10", bombardierTests.FirstOrDefault().Url.ToString());
177+
}
178+
179+
[Fact]
180+
public async Task GenerateBombardierTestWithOptionsBasicAuthTest_Successfull()
181+
{
182+
183+
var bombardierTestsGenerator = new BombardierTestsGenerator(options =>
184+
{
185+
options.AddBasicAuthentication("user", "pass");
186+
options.BombardierConcurrentUsers = 1;
187+
options.BombardierDuration = 1;
188+
options.BombardierTimeout = 30;
189+
options.BombardierUseHttp2 = true;
190+
options.BombardierRateLimit = 20;
191+
options.BombardierNumberOfTotalRequests = 22;
192+
});
193+
194+
var content = File.ReadAllText("Assets/getPetById.json");
195+
var httpRequest = JsonConvert.DeserializeObject<IList<HttpRequest>>(content);
196+
197+
var bombardierTests = await bombardierTestsGenerator.Generate(httpRequest);
198+
199+
var authHeader = Convert.ToBase64String(ASCIIEncoding.ASCII.GetBytes("user:pass"));
200+
201+
Assert.NotNull(bombardierTests);
202+
Assert.Single(bombardierTests);
203+
Assert.Contains($" -m GET https://petstore3.swagger.io/api/v3/pet/10 -c 1 -H \"Authorization: Basic {authHeader}\" --http2 --timeout=30s --duration=1s --rate=20 --requests=22", bombardierTests.FirstOrDefault().Command);
204+
Assert.Equal(HttpMethod.Get, bombardierTests.FirstOrDefault().Method);
205+
Assert.Equal("/pet/10", bombardierTests.FirstOrDefault().Url.ToString());
206+
}
207+
208+
[Fact]
209+
public async Task GenerateBombardierTestWithOptionsOAuth2Test_Successfull()
210+
{
211+
212+
var bombardierTestsGenerator = new BombardierTestsGenerator(options =>
213+
{
214+
options.AddOAuth2Token("1234567890", AuthenticationType.Customer);
215+
options.BombardierConcurrentUsers = 1;
216+
options.BombardierDuration = 1;
217+
options.BombardierTimeout = 30;
218+
options.BombardierUseHttp2 = true;
219+
options.BombardierRateLimit = 20;
220+
options.BombardierNumberOfTotalRequests = 22;
221+
});
222+
223+
var content = File.ReadAllText("Assets/getPetById.json");
224+
var httpRequest = JsonConvert.DeserializeObject<IList<HttpRequest>>(content);
225+
226+
var bombardierTests = await bombardierTestsGenerator.Generate(httpRequest);
227+
228+
Assert.NotNull(bombardierTests);
229+
Assert.Single(bombardierTests);
230+
Assert.Contains($" -m GET https://petstore3.swagger.io/api/v3/pet/10 -c 1 -H \"Authorization: Bearer 1234567890\" --http2 --timeout=30s --duration=1s --rate=20 --requests=22", bombardierTests.FirstOrDefault().Command);
231+
Assert.Equal(HttpMethod.Get, bombardierTests.FirstOrDefault().Method);
232+
Assert.Equal("/pet/10", bombardierTests.FirstOrDefault().Url.ToString());
233+
}
234+
235+
[Fact]
236+
public async Task GenerateBombardierTestDefaultBombardierOptionsTest_Successfull()
237+
{
238+
239+
var bombardierTestsGenerator = new BombardierTestsGenerator();
240+
241+
var content = File.ReadAllText("Assets/getPetById.json");
242+
var httpRequest = JsonConvert.DeserializeObject<IList<HttpRequest>>(content);
243+
244+
var bombardierTests = await bombardierTestsGenerator.Generate(httpRequest);
245+
246+
Assert.NotNull(bombardierTests);
247+
Assert.Single(bombardierTests);
248+
Assert.Contains($" -m GET https://petstore3.swagger.io/api/v3/pet/10 -c 3 --http2 --timeout=30s --duration=5s", bombardierTests.FirstOrDefault().Command);
249+
Assert.Equal(HttpMethod.Get, bombardierTests.FirstOrDefault().Method);
250+
Assert.Equal("/pet/10", bombardierTests.FirstOrDefault().Url.ToString());
251+
}
124252
}
125253
}

src/QAToolKit.Engine.Bombardier.Test/BombardierTestsRunnerTests.cs

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
using System.Collections.Generic;
77
using System.IO;
88
using System.Linq;
9-
using System.Net.Http;
109
using System.Threading.Tasks;
1110
using Xunit;
1211
using Xunit.Abstractions;
@@ -66,7 +65,7 @@ public async Task BombardierGetTestWithOptionsTest_Successfull()
6665
Assert.True(bombardierResults.FirstOrDefault().TestStop.Subtract(bombardierResults.FirstOrDefault().TestStart).TotalSeconds == bombardierResults.FirstOrDefault().Duration);
6766
}
6867

69-
/* [Fact]
68+
[Fact]
7069
public async Task BombardierPostTestWithOptionsTest_Successfull()
7170
{
7271

@@ -76,6 +75,7 @@ public async Task BombardierPostTestWithOptionsTest_Successfull()
7675
options.BombardierDuration = 1;
7776
options.BombardierTimeout = 30;
7877
options.BombardierUseHttp2 = true;
78+
options.BombardierNumberOfTotalRequests = 1;
7979
});
8080

8181
var content = File.ReadAllText("Assets/addPet.json");
@@ -97,15 +97,15 @@ public async Task BombardierPostTestWithOptionsTest_Successfull()
9797
Assert.True(bombardierResults.FirstOrDefault().Counter3xx == 0);
9898
Assert.True(bombardierResults.FirstOrDefault().Counter4xx == 0);
9999
Assert.True(bombardierResults.FirstOrDefault().Counter5xx == 0);
100-
Assert.True(bombardierResults.FirstOrDefault().AverageLatency > 0);
101-
Assert.True(bombardierResults.FirstOrDefault().MaxLatency > 0);
102-
Assert.True(bombardierResults.FirstOrDefault().StdevLatency > 0);
103-
Assert.True(bombardierResults.FirstOrDefault().AverageRequestsPerSecond > 0);
104-
Assert.True(bombardierResults.FirstOrDefault().MaxRequestsPerSecond > 0);
105-
Assert.True(bombardierResults.FirstOrDefault().StdevRequestsPerSecond > 0);
100+
Assert.True(bombardierResults.FirstOrDefault().AverageLatency >= 0);
101+
Assert.True(bombardierResults.FirstOrDefault().MaxLatency >= 0);
102+
Assert.True(bombardierResults.FirstOrDefault().StdevLatency >= 0);
103+
Assert.True(bombardierResults.FirstOrDefault().AverageRequestsPerSecond >= 0);
104+
Assert.True(bombardierResults.FirstOrDefault().MaxRequestsPerSecond >= 0);
105+
Assert.True(bombardierResults.FirstOrDefault().StdevRequestsPerSecond >= 0);
106106
Assert.True(bombardierResults.FirstOrDefault().TestStart.AddMinutes(60) > DateTime.Now);
107107
Assert.True(bombardierResults.FirstOrDefault().TestStop.AddMinutes(60) > DateTime.Now);
108108
Assert.True(bombardierResults.FirstOrDefault().TestStop.Subtract(bombardierResults.FirstOrDefault().TestStart).TotalSeconds == bombardierResults.FirstOrDefault().Duration);
109-
}*/
109+
}
110110
}
111111
}

src/QAToolKit.Engine.Bombardier/BombardierGeneratorOptions.cs

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,28 +29,32 @@ public class BombardierGeneratorOptions
2929
/// <summary>
3030
/// Bombardier concurrent users options
3131
/// </summary>
32-
public int BombardierConcurrentUsers { get; set; }
32+
public int BombardierConcurrentUsers { get; set; } = 3;
3333
/// <summary>
3434
/// Bombardier request timeout
3535
/// </summary>
36-
public int BombardierTimeout { get; set; }
36+
public int BombardierTimeout { get; set; } = 30;
3737
/// <summary>
3838
/// Bombardier test runner duration
3939
/// </summary>
40-
public int BombardierDuration { get; set; }
40+
public int BombardierDuration { get; set; } = 5;
4141
/// <summary>
4242
/// Bombardier rate limiting per second
4343
/// </summary>
4444
public int BombardierRateLimit { get; set; }
4545
/// <summary>
4646
/// Bombardier use HTTP2 protocol
4747
/// </summary>
48-
public bool BombardierUseHttp2 { get; set; }
48+
public bool BombardierUseHttp2 { get; set; } = true;
4949
/// <summary>
5050
/// Use http or https protocols, default is false.
5151
/// </summary>
5252
public bool BombardierInsecure { get; set; } = false;
5353
/// <summary>
54+
/// Cap the test with number of requests
55+
/// </summary>
56+
public int? BombardierNumberOfTotalRequests { get; set; } = null;
57+
/// <summary>
5458
/// Set request body content type for Bombardier tests, default is 'application/json'
5559
/// </summary>
5660
public ContentType.Enumeration BombardierBodyContentType { get; set; } = ContentType.Enumeration.Json;

src/QAToolKit.Engine.Bombardier/BombardierTestsGenerator.cs

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ public class BombardierTestsGenerator : IGenerator<IList<HttpRequest>, IEnumerab
2121
/// Bombardier test generator constructor
2222
/// </summary>
2323
/// <param name="options"></param>
24-
public BombardierTestsGenerator(Action<BombardierGeneratorOptions> options)
24+
public BombardierTestsGenerator(Action<BombardierGeneratorOptions> options = null)
2525
{
2626
_bombardierGeneratorOptions = new BombardierGeneratorOptions();
2727
options?.Invoke(_bombardierGeneratorOptions);
@@ -49,19 +49,18 @@ public async Task<IEnumerable<BombardierTest>> Generate(IList<HttpRequest> restR
4949

5050
foreach (var request in restRequests)
5151
{
52-
string authHeader = GeneratorHelper.GenerateAuthHeader(request, _bombardierGeneratorOptions);
53-
5452
scriptBuilder.AppendLine($"{bombardierFullPath} " +
55-
$"-m {request.Method.ToString().ToUpper()} {GeneratorHelper.GenerateUrlParameters(request)} " +
56-
$"-c {_bombardierGeneratorOptions.BombardierConcurrentUsers} " +
57-
$"{authHeader}" +
53+
$"-m {request.Method.ToString().ToUpper()} {GeneratorHelper.GenerateUrlParameters(request)}" +
54+
$"{GeneratorHelper.GenerateConcurrentSwitch(request, _bombardierGeneratorOptions)}" +
55+
$"{GeneratorHelper.GenerateAuthHeader(request, _bombardierGeneratorOptions)}" +
5856
$"{GeneratorHelper.GenerateContentTypeHeader(request, _bombardierGeneratorOptions.BombardierBodyContentType)}" +
5957
$"{GeneratorHelper.GenerateJsonBody(request, _bombardierGeneratorOptions.BombardierBodyContentType)}" +
60-
$"--{(Convert.ToBoolean(_bombardierGeneratorOptions.BombardierUseHttp2) ? "http2" : "http1")} " +
61-
$"--timeout={_bombardierGeneratorOptions.BombardierTimeout}s " +
62-
$"--duration={_bombardierGeneratorOptions.BombardierDuration}s " +
58+
$"{GeneratorHelper.GenerateHttpProtocolSwitch(_bombardierGeneratorOptions)}" +
59+
$"{GeneratorHelper.GenerateTimeoutSwitch(_bombardierGeneratorOptions)}" +
60+
$"{GeneratorHelper.GenerateDurationSwitch(_bombardierGeneratorOptions)}" +
6361
$"{GeneratorHelper.GenerateInsecureSwitch(_bombardierGeneratorOptions)}" +
64-
$"{GeneratorHelper.GenerateRateLimit(_bombardierGeneratorOptions.BombardierRateLimit)}");
62+
$"{GeneratorHelper.GenerateRateLimitSwitch(_bombardierGeneratorOptions)}" +
63+
$"{GeneratorHelper.GenerateTotalRequestsSwitch(_bombardierGeneratorOptions)}");
6564

6665
bombardierTests.Add(new BombardierTest()
6766
{

src/QAToolKit.Engine.Bombardier/BombardierTestsRunner.cs

Lines changed: 0 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -87,29 +87,12 @@ private async Task<BombardierResult> Run(string testCommand)
8787
process.WaitForExit();
8888
}
8989

90-
//Delete temp files
91-
DeleteBodyFile(bombardierArguments);
92-
9390
var testStop = DateTime.Now;
9491
var parsedBombardierOutput = ParseOutput(bombardrierOutput, bombardierArguments, testStart, testStop);
9592

9693
return parsedBombardierOutput;
9794
}
9895

99-
private void DeleteBodyFile(string arguments)
100-
{
101-
try
102-
{
103-
var file = StringHelper.Between(arguments, "-f \"", "\"");
104-
105-
if (string.IsNullOrEmpty(file) && File.Exists(file))
106-
{
107-
File.Delete(file);
108-
}
109-
}
110-
catch { }
111-
}
112-
11396
private BombardierResult ParseOutput(StringBuilder sb, string command, DateTime testStart, DateTime testStop)
11497
{
11598
try

0 commit comments

Comments
 (0)