Skip to content

Commit

Permalink
Updated webhost startup condition (#32)
Browse files Browse the repository at this point in the history
- removed requirement of passing `prometheus` flag to start the web host
- removed unit tests that referenced external sources
- fixed max duration bug

Co-authored-by: bartr <[email protected]>
Co-authored-by: aflinchb <[email protected]>
  • Loading branch information
3 people authored Jun 16, 2022
1 parent a5f970d commit b78082f
Show file tree
Hide file tree
Showing 15 changed files with 91 additions and 66 deletions.
14 changes: 14 additions & 0 deletions .github/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,19 @@
# Change Log

## v2.5.0 - June 2022

- updated condition to run webhost without `--prometheus`
- removed unit tests that referenced external sources
- fixed max duration bug

## v2.4.0 - March 2022

- fixed thread sync bug
- added /readyz endpoint
- updated packages
- bumped version
- Retail Edge customer feedback

## v2.3.1 - Dec 2021

- minor bug fixes
Expand Down
31 changes: 21 additions & 10 deletions .github/workflows/codeql.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,18 @@
name: "CodeQL"
name: CodeQL

on:
workflow_dispatch:

push:
branches:
- main

paths-ignore:
- '.devcontainer/**'
- 'docs/**'
- '**.md'
- '**.json'

pull_request:
branches: [main]

Expand Down Expand Up @@ -43,16 +55,15 @@ jobs:
with:
languages: ${{ matrix.language }}

- name: Setup .NET
uses: actions/setup-dotnet@v1
with:
dotnet-version: '6.0'
include-prerelease: True

# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
# Autobuild doesn't build correctly, so we run a manual build
- name: Autobuild
# uses: github/codeql-action/autobuild@v1
run: |
# install dotnet 6
sudo apt-get -y install --no-install-recommends dotnet-sdk-6.0
cd src
dotnet build
uses: github/codeql-action/autobuild@v2

- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v1
uses: github/codeql-action/analyze@v2
8 changes: 3 additions & 5 deletions .github/workflows/dockerCI.yaml
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
name: Docker Image Build
name: DockerBuild

on:
schedule:
# Run on Sunday at 6:00 AM UTC
- cron: "0 6 * * 0"

workflow_dispatch:

push:
branches:
- main
Expand Down
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
# Web Validate - A web request validation tool

![License](https://img.shields.io/badge/license-MIT-green.svg)
![Docker Image Build](https://github.com/microsoft/webvalidate/workflows/Docker%20Image%20Build/badge.svg)
![CodeQL Build](https://github.com/microsoft/webvalidate/workflows/CodeQL/badge.svg)
![Docker Build](https://github.com/microsoft/webvalidate/workflows/DockerBuild/badge.svg)

Web Validate (WebV) is a web request validation tool that we use to run end-to-end tests and long-running performance and availability tests.

Expand Down
33 changes: 15 additions & 18 deletions src/app/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -127,28 +127,25 @@ public static async Task<int> Run(Config config, ParseResult parseResult)
{
IHost host = null;

if (config.Prometheus)
{
// build and run the web host
host = BuildWebHost(config.Port);
Task t = host.StartAsync(TokenSource.Token);

if (t.IsFaulted)
{
// stop and dispose the web host
await host.StopAsync(TimeSpan.FromMilliseconds(100)).ConfigureAwait(false);
host.Dispose();
host = null;
// build and run the web host
host = BuildWebHost(config.Port);
Task t = host.StartAsync(TokenSource.Token);

Console.WriteLine("\n\nUnabled to start web server\n");
if (t.IsFaulted)
{
// stop and dispose the web host
await host.StopAsync(TimeSpan.FromMilliseconds(100)).ConfigureAwait(false);
host.Dispose();
host = null;

if (t.Exception != null)
{
Console.WriteLine(t.Exception.Message);
}
Console.WriteLine("\n\nUnabled to start web server\n");

return -1;
if (t.Exception != null)
{
Console.WriteLine(t.Exception.Message);
}

return -1;
}

// run in a loop
Expand Down
2 changes: 1 addition & 1 deletion src/app/WebValidation/Main.cs
Original file line number Diff line number Diff line change
Expand Up @@ -452,7 +452,7 @@ public async Task<PerfLog> ExecuteRequest(HttpClient client, string server, Requ
double duration = Math.Round(DateTime.UtcNow.Subtract(dt).TotalMilliseconds, 0);

// validate the response
valid = ResponseValidator.Validate(request, resp, body);
valid = ResponseValidator.Validate(request, resp, body, duration);

// check the performance
perfLog = CreatePerfLog(server, request, valid, duration, (long)resp.Content.Headers.ContentLength, (int)resp.StatusCode, cv.Value);
Expand Down
2 changes: 1 addition & 1 deletion src/app/WebValidation/Model/Validation.cs
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ public class Validation
/// gets or sets the maximum ms for the request
/// default: null (ignore)
/// </summary>
public int? MaxMilliseconds { get; set; }
public int? MaxMilliSeconds { get; set; }

/// <summary>
/// gets or sets the list of strings that must be in the response
Expand Down
2 changes: 1 addition & 1 deletion src/app/WebValidation/Validators/ParameterValidator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ public static ValidationResult Validate(Validation v)
res.Add(ValidateLength(v));

// validate MaxMilliSeconds
if (v.MaxMilliseconds != null && v.MaxMilliseconds <= 0)
if (v.MaxMilliSeconds != null && v.MaxMilliSeconds <= 0)
{
res.Failed = true;
res.ValidationErrors.Add("maxMilliseconds: maxMilliseconds cannot be less than zero");
Expand Down
12 changes: 11 additions & 1 deletion src/app/WebValidation/Validators/ResponseValidator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,9 @@ public static class ResponseValidator
/// <param name="r">Request</param>
/// <param name="response">HttpResponseMessage</param>
/// <param name="body">response body</param>
/// <param name="duration">request duration</param>
/// <returns>ValidationResult</returns>
public static ValidationResult Validate(Request r, HttpResponseMessage response, string body)
public static ValidationResult Validate(Request r, HttpResponseMessage response, string body, double duration)
{
ValidationResult result = new ();

Expand All @@ -48,6 +49,15 @@ public static ValidationResult Validate(Request r, HttpResponseMessage response,
return result;
}

// validate max duration
if (r.Validation.MaxMilliSeconds > 0)
{
if (duration > r.Validation.MaxMilliSeconds)
{
result.ValidationErrors.Add($"duration: {duration}ms exceeded max value {r.Validation.MaxMilliSeconds}ms");
}
}

// redirects don't have body or headers
if ((int)response.StatusCode >= 300 && (int)response.StatusCode <= 399)
{
Expand Down
10 changes: 10 additions & 0 deletions src/app/duration.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
// test command:
// dotnet run -- --verbose-errors -s https://bing.com -f duration.json
// validation errors are expected

{
"requests":
[
{"path":"/","perfTarget":{"category":"Static"},"validation":{"maxMilliSeconds":1, "statusCode":301}}
]
}
3 changes: 3 additions & 0 deletions src/app/github.json
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
// test command
// dotnet run -- --verbose-errors -s https://api.github.com -f github.json

{
"requests":
[
Expand Down
5 changes: 4 additions & 1 deletion src/app/msft.json
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
// test command
// dotnet run -- --verbose-errors -s https://www.microsoft.com -f msft.json

{
"requests":
[
{"path":"/","testName": "mytest1", "perfTarget":{"category":"Static"},"validation":{"statusCode":302}},
{"path":"/en-us","perfTarget":{"category":"Static"},"validation":{"contentType":"text/html","contains":["<title>Microsoft - Official Home Page</title>","<head data-info=\"{"]}},
{"path":"/en-us","perfTarget":{"category":"Static"},"validation":{"contentType":"text/html","contains":["<title>Microsoft – Cloud, Computers, Apps","<head data-info=\"{"]}},
{"path":"/robots.txt","perfTarget":{"category":"Static"},"validation":{"contentType":"text/plain","minLength":200,"contains":["User-agent: *","Disallow: /en-us/windows/si/matrix.html"]}},
{"path":"/favicon.ico","perfTarget":{"category":"Static"},"validation":{"contentType":"image/x-icon"}}
]
Expand Down
2 changes: 1 addition & 1 deletion src/app/webvalidate.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<RootNamespace>CSE.WebValidate</RootNamespace>
<VersionPrefix>2.4.0</VersionPrefix>
<VersionPrefix>2.5.0</VersionPrefix>
<VersionSuffix>$([System.DateTime]::UtcNow.ToString(`MMdd-HHmm`))</VersionSuffix>
<Company>Microsoft Corporation</Company>
<Copyright>Copyright (c) Microsoft Corporation. All rights reserved.</Copyright>
Expand Down
22 changes: 0 additions & 22 deletions src/tests/TestApp.cs
Original file line number Diff line number Diff line change
Expand Up @@ -166,27 +166,5 @@ private static Config BuildConfig(string server)
MaxErrors = 10,
};
}

[Fact]
public async Task MsftTest()
{
Config cfg = BuildConfig("https://www.microsoft.com");
cfg.Files.Add("msft.json");

// load and validate all of our test files
WebV wv = new (cfg);
Assert.Equal(0, await wv.RunOnce(cfg, new System.Threading.CancellationToken()).ConfigureAwait(false));
}

[Fact]
public async Task GithubTest()
{
Config cfg = BuildConfig("https://api.github.com");
cfg.Files.Add("github.json");

// load and validate all of our test files
WebV wv = new (cfg);
Assert.Equal(0, await wv.RunOnce(cfg, new System.Threading.CancellationToken()).ConfigureAwait(false));
}
}
}
8 changes: 4 additions & 4 deletions src/tests/TestCommonValidator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ public void CommonBoundariesTest()
v.StatusCode = 10;

// > 0
v.MaxMilliseconds = 0;
v.MaxMilliSeconds = 0;

// ! isnullorempty
v.ExactMatch = string.Empty;
Expand Down Expand Up @@ -108,14 +108,14 @@ public void ResponseNullTest()
{
Request r = new ();

Assert.False(ResponseValidator.Validate(r, null, string.Empty).Failed);
Assert.False(ResponseValidator.Validate(r, null, string.Empty, 0).Failed);

r.Validation = new Validation();

Assert.True(ResponseValidator.Validate(r, null, "this is a test").Failed);
Assert.True(ResponseValidator.Validate(r, null, "this is a test", 0).Failed);

using System.Net.Http.HttpResponseMessage resp = new (System.Net.HttpStatusCode.NotFound);
Assert.True(ResponseValidator.Validate(r, resp, "this is a test").Failed);
Assert.True(ResponseValidator.Validate(r, resp, "this is a test", 0).Failed);

Assert.True(ResponseValidator.ValidateStatusCode(400, 200).Failed);
}
Expand Down

0 comments on commit b78082f

Please sign in to comment.