Skip to content

Commit 38ad2ca

Browse files
committed
Various changes: documentation, test --viewResponse
1 parent ed1b942 commit 38ad2ca

File tree

9 files changed

+195
-25
lines changed

9 files changed

+195
-25
lines changed

README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Netmockery is a simple system for simulating network services.
2+
3+
The [documentation](netmockery/documentation.md) is a work in progress.

UnitTests/TestTestCommand.cs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,17 @@ async public void CanCheckExpectedRequestMatcherSuccess()
185185
Assert.True(result.OK);
186186
}
187187

188+
[Fact]
189+
async public void CanGetResultBody()
190+
{
191+
var testcase =
192+
(new JSONTest { name = "checksomething", requestpath = "/foo/", requestbody = "this is a test", expectedrequestmatcher = "Regex 'test'" })
193+
.Validated().CreateTestCase(".");
194+
var result = await testcase.GetResponseAsync(EndpointCollectionReader.ReadFromDirectory(dc.DirectoryName));
195+
Assert.Equal("FOOBARBOOBAR", result.Item1);
196+
Assert.Null(result.Item2);
197+
}
198+
188199
[Fact]
189200
async public void CanCheckExpectedResponseCreatorError()
190201
{

netmockery.sln

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,17 @@
11

22
Microsoft Visual Studio Solution File, Format Version 12.00
33
# Visual Studio 14
4-
VisualStudioVersion = 14.0.25123.0
4+
VisualStudioVersion = 14.0.25420.1
55
MinimumVisualStudioVersion = 10.0.40219.1
66
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "netmockery", "netmockery\netmockery.xproj", "{3416FD6A-7658-4BEC-8467-13196D5FD2CA}"
77
EndProject
88
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "UnitTests", "UnitTests\UnitTests.xproj", "{10629440-1E0F-4677-8461-831C5251E96D}"
99
EndProject
10+
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{E789D0E5-31C6-4B48-A2F2-144D8336EAB3}"
11+
ProjectSection(SolutionItems) = preProject
12+
README.md = README.md
13+
EndProjectSection
14+
EndProject
1015
Global
1116
GlobalSection(SolutionConfigurationPlatforms) = preSolution
1217
Debug|Any CPU = Debug|Any CPU

netmockery/Controllers/DocumentationController.cs

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,22 @@
44
using System.Linq;
55
using System.Threading.Tasks;
66
using HeyRed.MarkdownSharp;
7+
using Microsoft.AspNetCore.Hosting;
78

89
namespace netmockery.Controllers
910
{
1011
public class DocumentationController : Controller
1112
{
13+
private IHostingEnvironment _env;
14+
15+
public DocumentationController(IHostingEnvironment env)
16+
{
17+
_env = env;
18+
}
19+
1220
public ActionResult Index()
1321
{
14-
var markdown = new Markdown();
15-
var text = markdown.Transform(System.IO.File.ReadAllText("documentation.md"));
22+
var text = new Markdown().Transform(System.IO.File.ReadAllText(System.IO.Path.Combine(_env.ContentRootPath, "documentation.md")));
1623
return View("DisplayMarkdown", text);
1724
}
1825
}

netmockery/JSONReader.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,10 @@ public class JSONTest
2222
public string requestpath;
2323
public string querystring;
2424
public string requestbody;
25-
public string expectedresponsebody;
25+
2626
public string expectedrequestmatcher;
2727
public string expectedresponsecreator;
28-
public string expectedrequestcreator;
28+
public string expectedresponsebody;
2929

3030
public JSONTest Validated()
3131
{

netmockery/NetmockeryTestCase.cs

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,10 @@ public bool Evaluate(string requestMatcher, string responseCreator, string respo
126126
return true;
127127
}
128128

129+
private const string ERROR_NOMATCHING_ENDPOINT = "No endpoint matches request path";
130+
private const string ERROR_ENDPOINT_HAS_NO_MATCH = "Endpoint has no match for request";
131+
132+
129133
async public Task<NetmockeryTestCaseResult> ExecuteAsync(EndpointCollection endpointCollection, bool handleErrors=true)
130134
{
131135
Debug.Assert(endpointCollection != null);
@@ -136,7 +140,7 @@ async public Task<NetmockeryTestCaseResult> ExecuteAsync(EndpointCollection endp
136140
var endpoint = endpointCollection.Resolve(RequestPath);
137141
if (endpoint == null)
138142
{
139-
retval.SetFailure("No endpoint matches request path");
143+
retval.SetFailure(ERROR_NOMATCHING_ENDPOINT);
140144
}
141145
else
142146
{
@@ -169,7 +173,7 @@ async public Task<NetmockeryTestCaseResult> ExecuteAsync(EndpointCollection endp
169173
}
170174
else
171175
{
172-
retval.SetFailure("Endpoint has not match for request");
176+
retval.SetFailure(ERROR_ENDPOINT_HAS_NO_MATCH);
173177
}
174178
}
175179
}
@@ -180,6 +184,28 @@ async public Task<NetmockeryTestCaseResult> ExecuteAsync(EndpointCollection endp
180184
}
181185
return retval;
182186
}
187+
188+
async public Task<Tuple<string, string>> GetResponseAsync(EndpointCollection endpointCollection)
189+
{
190+
var endpoint = endpointCollection.Resolve(RequestPath);
191+
if (endpoint == null)
192+
{
193+
return Tuple.Create((string)null, ERROR_NOMATCHING_ENDPOINT);
194+
}
195+
bool singleMatch;
196+
var matcher_and_creator = endpoint.Resolve(new PathString(RequestPath), new QueryString(QueryString), RequestBody, null, out singleMatch);
197+
if (matcher_and_creator != null)
198+
{
199+
var responseCreator = matcher_and_creator.Item2;
200+
var responseBodyBytes = await responseCreator.CreateResponseAsync(new TestCaseHttpRequest(RequestPath), Encoding.UTF8.GetBytes(RequestBody), new TestCaseHttpResponse(), endpoint.Directory);
201+
return Tuple.Create(Encoding.UTF8.GetString(responseBodyBytes), (string)null);
202+
}
203+
else
204+
{
205+
return Tuple.Create((string)null, ERROR_ENDPOINT_HAS_NO_MATCH);
206+
}
207+
208+
}
183209
}
184210

185211
public class NetmockeryTestCaseResult

netmockery/Program.cs

Lines changed: 33 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
using Microsoft.AspNetCore.Hosting;
2+
using Microsoft.AspNetCore.Hosting.WindowsServices;
23
using System;
34
using System.Collections.Generic;
45
using System.Diagnostics;
56
using System.IO;
67
using System.Linq;
8+
using System.Reflection;
79
using System.Threading.Tasks;
810
using static System.Console;
911

@@ -18,6 +20,17 @@ public static void ReloadConfig()
1820
{
1921
EndpointCollection = EndpointCollectionReader.ReadFromDirectory(_configdirectory);
2022
}
23+
24+
private static IWebHost CreateWebHost(string contentRoot)
25+
{
26+
return new WebHostBuilder()
27+
.UseKestrel()
28+
.UseContentRoot(contentRoot)
29+
.UseIISIntegration()
30+
.UseStartup<Startup>()
31+
.Build();
32+
}
33+
2134
public static void Main(string[] args)
2235
{
2336
System.Net.ServicePointManager.ServerCertificateValidationCallback =
@@ -30,15 +43,8 @@ public static void Main(string[] args)
3043

3144
if (args.Length == 1)
3245
{
33-
var host = new WebHostBuilder()
34-
.UseKestrel()
35-
.UseContentRoot(Directory.GetCurrentDirectory())
36-
.UseIISIntegration()
37-
.UseStartup<Startup>()
38-
.Build();
39-
4046
WriteLine("Admin interface available on /__netmockery");
41-
host.Run();
47+
CreateWebHost(Directory.GetCurrentDirectory()).Run();
4248
}
4349
else
4450
{
@@ -67,6 +73,11 @@ public static void Main(string[] args)
6773
Test(commandArgs);
6874
break;
6975

76+
case "service":
77+
WriteLine("Running as service");
78+
RunAsService();
79+
break;
80+
7081
default:
7182
Error.WriteLine($"Unknown command {commandName}");
7283
break;
@@ -79,6 +90,11 @@ public static void Main(string[] args)
7990
}
8091
}
8192

93+
static public void RunAsService()
94+
{
95+
CreateWebHost(AppDomain.CurrentDomain.BaseDirectory).RunAsService();
96+
}
97+
8298
static private string getSwitchValue(string[] commandArgs, string switchName)
8399
{
84100
var index = Array.FindIndex(commandArgs, v => v == switchName);
@@ -114,7 +130,15 @@ public static void Test(string[] commandArgs)
114130

115131
if (containsSwitch(commandArgs, "--showResponse"))
116132
{
117-
throw new NotImplementedException("TODO");
133+
var response = testCase.GetResponseAsync(EndpointCollection).Result;
134+
if (response.Item2 != null)
135+
{
136+
Error.WriteLine($"ERROR: {response.Item2}");
137+
}
138+
else
139+
{
140+
WriteLine(response.Item1);
141+
}
118142
}
119143
else
120144
{

netmockery/documentation.md

Lines changed: 99 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,108 @@
1-
Directory structure
2-
===================
1+
# Netmockery Documentation
2+
3+
* [Running netmockery](#running)
4+
* [Configuring netmockery](#configuring)
5+
* [Writing tests](#tests)
6+
* [Misc](#misc)
7+
8+
<a name="running"></a>
9+
# Running netmockery
10+
11+
Command line:
12+
13+
netmockery.exe p:\ath\to\endpoint\directory
14+
15+
Netmockery starts and listens on port ``5000``.
16+
17+
## Installing as windows service
18+
19+
To install:
20+
21+
sc create netmockery binPath= "p:\ath\to\netmockery.exe p:\ath\to\endpoint\directory service"
22+
23+
If ``p:\ath\to\netmockery.exe`` or ``p:\ath\to\endpoint\directory`` contains spaces, they must be escaped using ``\"`` . Example:
24+
25+
sc create netmockery binPath= "p:\ath\to\netmockery.exe \"p:\ath\to\endpoint\directory\with space\" service"
26+
27+
Start/stop service:
28+
29+
net start netmockery
30+
net stop netmockery
31+
32+
To uninstall:
33+
34+
sc delete netmockery
35+
36+
<a name="configuring"></a>
37+
# Configuring netmockery
38+
39+
## Directory structure
340

441
TODO
542

43+
## Request matching
644

7-
Request matching
8-
================
45+
TODO
46+
47+
## Response creation
948

1049
TODO
1150

51+
<a name="tests"></a>
52+
# Writing tests
53+
54+
Within a endpoint directory, a ``tests`` directory with a ``tests.json`` file defines test cases for the endpoint directory.
55+
56+
Example ``tests.json`` file:
57+
58+
[
59+
{
60+
'name': 'My first test',
61+
'requestpath': '/somepath/',
62+
63+
// optional request parameters:
64+
// querystring
65+
// requestbody
66+
67+
// one or more test expectations:
68+
// expectedrequestmatcher
69+
// expectedresponsecreator
70+
// expectedresponsebody
71+
},
72+
// More test cases
73+
]
74+
75+
Specifying the request:
76+
77+
* ``name``: display name for test (required)
78+
* ``requestpath``: request path (required)
79+
* ``querystring``: request query string
80+
* ``requestbody``: request body
81+
82+
Specifying the expectations:
83+
84+
* ``expectedrequestmatcher``: Display name of request matcher
85+
* ``expectedresponsecreator``: Display name of response creator
86+
* ``expectedresponsebody``: Expected response body contents. If specified as ``file:filename``, the expected response body is read from the specified file.
87+
88+
## Running tests
89+
90+
Command line:
91+
92+
# run all tests
93+
netmockery.exe p:\ath\to\endpoint\directory test
94+
95+
# run single test, numeric parameter N specifies which test (first test is test 0 (zero))
96+
netmockery.exe p:\ath\to\endpoint\directory test --only N
97+
98+
# execute request specified by test N, but display respons (do not check test expectations)
99+
netmockery.exe p:\ath\to\endpoint\directory test --only N --showResponse
100+
101+
<a name="misc"></a>
102+
# Misc
103+
104+
TODO: delay parameter
12105

13-
Response creation
14-
=================
106+
TODO: index.md documentation
15107

16-
TODO
108+
TODO: other commands, dump

netmockery/project.json

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,8 @@
1010
"Newtonsoft.Json": "9.0.1",
1111
"Markdown": "2.1.0",
1212
"Microsoft.AspNetCore.StaticFiles": "1.0.0",
13-
"System.Net.Http": "4.1.0"
13+
"System.Net.Http": "4.1.0",
14+
"Microsoft.AspNetCore.Hosting.WindowsServices": "1.1.0-preview1-final"
1415
},
1516

1617
"tools": {
@@ -33,7 +34,8 @@
3334
"include": [
3435
"wwwroot",
3536
"web.config",
36-
"Views"
37+
"Views",
38+
"documentation.md"
3739
]
3840
},
3941

0 commit comments

Comments
 (0)