@mbtest/mountebank 2.9.2-beta.9050
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +94 -0
- package/bin/mb +136 -0
- package/package.json +71 -0
- package/releases.json +52 -0
- package/src/cli/api.js +112 -0
- package/src/cli/cli.js +420 -0
- package/src/controllers/configController.js +64 -0
- package/src/controllers/feedController.js +115 -0
- package/src/controllers/homeController.js +58 -0
- package/src/controllers/imposterController.js +328 -0
- package/src/controllers/impostersController.js +215 -0
- package/src/controllers/logsController.js +52 -0
- package/src/models/behaviors.js +553 -0
- package/src/models/behaviorsValidator.js +186 -0
- package/src/models/compatibility.js +133 -0
- package/src/models/dryRunValidator.js +261 -0
- package/src/models/filesystemBackedImpostersRepository.js +908 -0
- package/src/models/http/baseHttpServer.js +207 -0
- package/src/models/http/headersMap.js +87 -0
- package/src/models/http/httpProxy.js +230 -0
- package/src/models/http/httpRequest.js +82 -0
- package/src/models/http/httpServer.js +18 -0
- package/src/models/http/index.js +18 -0
- package/src/models/https/cert/mb-cert.pem +20 -0
- package/src/models/https/cert/mb-csr.pem +16 -0
- package/src/models/https/cert/mb-key.pem +27 -0
- package/src/models/https/httpsServer.js +42 -0
- package/src/models/https/index.js +18 -0
- package/src/models/imposter.js +243 -0
- package/src/models/imposterPrinter.js +120 -0
- package/src/models/impostersRepository.js +49 -0
- package/src/models/inMemoryImpostersRepository.js +418 -0
- package/src/models/jsonpath.js +44 -0
- package/src/models/mbConnection.js +107 -0
- package/src/models/predicates.js +438 -0
- package/src/models/protocols.js +242 -0
- package/src/models/responseResolver.js +398 -0
- package/src/models/smtp/index.js +16 -0
- package/src/models/smtp/smtpRequest.js +60 -0
- package/src/models/smtp/smtpServer.js +109 -0
- package/src/models/tcp/index.js +18 -0
- package/src/models/tcp/tcpProxy.js +110 -0
- package/src/models/tcp/tcpRequest.js +23 -0
- package/src/models/tcp/tcpServer.js +156 -0
- package/src/models/tcp/tcpValidator.js +19 -0
- package/src/models/xpath.js +95 -0
- package/src/mountebank.js +245 -0
- package/src/public/images/arrow_down.png +0 -0
- package/src/public/images/arrow_up.png +0 -0
- package/src/public/images/book.jpg +0 -0
- package/src/public/images/dataflow.png +0 -0
- package/src/public/images/favicon.ico +0 -0
- package/src/public/images/forkme_right_orange_ff7600.png +0 -0
- package/src/public/images/mountebank.png +0 -0
- package/src/public/images/overview.gif +0 -0
- package/src/public/images/quote.png +0 -0
- package/src/public/images/tw-logo.png +0 -0
- package/src/public/scripts/jquery/jquery-3.6.1.min.js +2 -0
- package/src/public/scripts/urlHashHandler.js +31 -0
- package/src/public/stylesheets/application.css +424 -0
- package/src/public/stylesheets/ie.css +14 -0
- package/src/public/stylesheets/imposters.css +121 -0
- package/src/public/stylesheets/jqueryui/1.10.4/themes/smoothness/jquery-ui.css +1178 -0
- package/src/util/combinators.js +68 -0
- package/src/util/date.js +51 -0
- package/src/util/errors.js +55 -0
- package/src/util/helpers.js +131 -0
- package/src/util/inherit.js +28 -0
- package/src/util/ip.js +54 -0
- package/src/util/logger.js +83 -0
- package/src/util/middleware.js +256 -0
- package/src/util/scopedLogger.js +47 -0
- package/src/views/_footer.ejs +20 -0
- package/src/views/_header.ejs +113 -0
- package/src/views/_imposter.ejs +8 -0
- package/src/views/config.ejs +71 -0
- package/src/views/docs/api/behaviors/copy.ejs +427 -0
- package/src/views/docs/api/behaviors/decorate.ejs +182 -0
- package/src/views/docs/api/behaviors/lookup.ejs +220 -0
- package/src/views/docs/api/behaviors/shellTransform.ejs +153 -0
- package/src/views/docs/api/behaviors/wait.ejs +121 -0
- package/src/views/docs/api/behaviors.ejs +141 -0
- package/src/views/docs/api/contracts/addStub-description.ejs +10 -0
- package/src/views/docs/api/contracts/addStub.ejs +10 -0
- package/src/views/docs/api/contracts/config-description.ejs +32 -0
- package/src/views/docs/api/contracts/config.ejs +23 -0
- package/src/views/docs/api/contracts/home-description.ejs +18 -0
- package/src/views/docs/api/contracts/home.ejs +13 -0
- package/src/views/docs/api/contracts/imposter-description.ejs +439 -0
- package/src/views/docs/api/contracts/imposter.ejs +182 -0
- package/src/views/docs/api/contracts/imposters-description.ejs +13 -0
- package/src/views/docs/api/contracts/imposters.ejs +13 -0
- package/src/views/docs/api/contracts/logs-description.ejs +3 -0
- package/src/views/docs/api/contracts/logs.ejs +14 -0
- package/src/views/docs/api/contracts/stub-description.ejs +4 -0
- package/src/views/docs/api/contracts/stub.ejs +7 -0
- package/src/views/docs/api/contracts/stubs-description.ejs +4 -0
- package/src/views/docs/api/contracts/stubs.ejs +11 -0
- package/src/views/docs/api/contracts.ejs +133 -0
- package/src/views/docs/api/errors.ejs +64 -0
- package/src/views/docs/api/fault/connectionReset.ejs +31 -0
- package/src/views/docs/api/fault/randomDataThenClose.ejs +31 -0
- package/src/views/docs/api/faults.ejs +57 -0
- package/src/views/docs/api/injection.ejs +426 -0
- package/src/views/docs/api/json.ejs +205 -0
- package/src/views/docs/api/jsonpath.ejs +210 -0
- package/src/views/docs/api/mocks.ejs +130 -0
- package/src/views/docs/api/overview.ejs +968 -0
- package/src/views/docs/api/predicates/and.ejs +62 -0
- package/src/views/docs/api/predicates/contains.ejs +64 -0
- package/src/views/docs/api/predicates/deepEquals.ejs +114 -0
- package/src/views/docs/api/predicates/endsWith.ejs +66 -0
- package/src/views/docs/api/predicates/equals.ejs +125 -0
- package/src/views/docs/api/predicates/exists.ejs +118 -0
- package/src/views/docs/api/predicates/inject.ejs +67 -0
- package/src/views/docs/api/predicates/matches.ejs +66 -0
- package/src/views/docs/api/predicates/not.ejs +52 -0
- package/src/views/docs/api/predicates/or.ejs +79 -0
- package/src/views/docs/api/predicates/startsWith.ejs +62 -0
- package/src/views/docs/api/predicates.ejs +382 -0
- package/src/views/docs/api/proxies.ejs +191 -0
- package/src/views/docs/api/proxy/addDecorateBehavior.ejs +115 -0
- package/src/views/docs/api/proxy/addWaitBehavior.ejs +96 -0
- package/src/views/docs/api/proxy/injectHeaders.ejs +91 -0
- package/src/views/docs/api/proxy/predicateGenerators.ejs +600 -0
- package/src/views/docs/api/proxy/proxyModes.ejs +495 -0
- package/src/views/docs/api/stubs.ejs +391 -0
- package/src/views/docs/api/xpath.ejs +281 -0
- package/src/views/docs/cli/configFiles.ejs +133 -0
- package/src/views/docs/cli/customFormatters.ejs +53 -0
- package/src/views/docs/cli/help.ejs +6 -0
- package/src/views/docs/cli/replay.ejs +42 -0
- package/src/views/docs/cli/restart.ejs +10 -0
- package/src/views/docs/cli/save.ejs +68 -0
- package/src/views/docs/cli/start.ejs +234 -0
- package/src/views/docs/cli/stop.ejs +32 -0
- package/src/views/docs/commandLine.ejs +93 -0
- package/src/views/docs/communityExtensions.ejs +233 -0
- package/src/views/docs/gettingStarted.ejs +146 -0
- package/src/views/docs/mentalModel.ejs +51 -0
- package/src/views/docs/protocols/custom.ejs +231 -0
- package/src/views/docs/protocols/http.ejs +238 -0
- package/src/views/docs/protocols/https.ejs +246 -0
- package/src/views/docs/protocols/smtp.ejs +142 -0
- package/src/views/docs/protocols/tcp.ejs +431 -0
- package/src/views/docs/security.ejs +38 -0
- package/src/views/faqs.ejs +65 -0
- package/src/views/feed.ejs +33 -0
- package/src/views/imposter.ejs +22 -0
- package/src/views/imposters.ejs +33 -0
- package/src/views/index.ejs +89 -0
- package/src/views/license.ejs +30 -0
- package/src/views/logs.ejs +77 -0
- package/src/views/releases/v1.1.0.ejs +55 -0
- package/src/views/releases/v1.1.36.ejs +84 -0
- package/src/views/releases/v1.1.72.ejs +92 -0
- package/src/views/releases/v1.10.0.ejs +108 -0
- package/src/views/releases/v1.11.0.ejs +109 -0
- package/src/views/releases/v1.12.0.ejs +96 -0
- package/src/views/releases/v1.13.0.ejs +118 -0
- package/src/views/releases/v1.14.0.ejs +107 -0
- package/src/views/releases/v1.14.1.ejs +94 -0
- package/src/views/releases/v1.15.0.ejs +113 -0
- package/src/views/releases/v1.16.0.ejs +104 -0
- package/src/views/releases/v1.2.0.ejs +78 -0
- package/src/views/releases/v1.2.103.ejs +86 -0
- package/src/views/releases/v1.2.122.ejs +86 -0
- package/src/views/releases/v1.2.30.ejs +84 -0
- package/src/views/releases/v1.2.45.ejs +84 -0
- package/src/views/releases/v1.2.56.ejs +79 -0
- package/src/views/releases/v1.3.0.ejs +86 -0
- package/src/views/releases/v1.3.1.ejs +100 -0
- package/src/views/releases/v1.4.0.ejs +96 -0
- package/src/views/releases/v1.4.1.ejs +103 -0
- package/src/views/releases/v1.4.2.ejs +100 -0
- package/src/views/releases/v1.4.3.ejs +113 -0
- package/src/views/releases/v1.5.0.ejs +104 -0
- package/src/views/releases/v1.5.1.ejs +91 -0
- package/src/views/releases/v1.6.0.ejs +109 -0
- package/src/views/releases/v1.7.0.ejs +113 -0
- package/src/views/releases/v1.7.1.ejs +90 -0
- package/src/views/releases/v1.7.2.ejs +96 -0
- package/src/views/releases/v1.8.0.ejs +121 -0
- package/src/views/releases/v1.9.0.ejs +111 -0
- package/src/views/releases/v2.0.0.ejs +159 -0
- package/src/views/releases/v2.1.0.ejs +121 -0
- package/src/views/releases/v2.1.1.ejs +106 -0
- package/src/views/releases/v2.1.2.ejs +84 -0
- package/src/views/releases/v2.2.0.ejs +115 -0
- package/src/views/releases/v2.2.1.ejs +102 -0
- package/src/views/releases/v2.3.0.ejs +121 -0
- package/src/views/releases/v2.3.1.ejs +100 -0
- package/src/views/releases/v2.3.2.ejs +102 -0
- package/src/views/releases/v2.3.3.ejs +97 -0
- package/src/views/releases/v2.4.0.ejs +114 -0
- package/src/views/releases/v2.5.0.ejs +51 -0
- package/src/views/releases/v2.6.0.ejs +35 -0
- package/src/views/releases/v2.7.0.ejs +32 -0
- package/src/views/releases/v2.8.0.ejs +36 -0
- package/src/views/releases/v2.8.1.ejs +7 -0
- package/src/views/releases/v2.8.2.ejs +26 -0
- package/src/views/releases/v2.9.0.ejs +32 -0
- package/src/views/releases/v2.9.1.ejs +10 -0
- package/src/views/releases.ejs +26 -0
- package/src/views/sitemap.ejs +36 -0
- package/src/views/support.ejs +14 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
The MIT License (MIT)
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2013 mountebank
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
# Project in transition
|
|
2
|
+
|
|
3
|
+
Currently the project is in transition to a collaborative group effort under a github organisation.
|
|
4
|
+
|
|
5
|
+
Work is being done to migrate and upgrade all CI/CD integrations from personal accounts to organisation accounts.
|
|
6
|
+
|
|
7
|
+
Pull requests are welcome, but don't expect anything to be merged until CI/CD infrastucture is up and running.
|
|
8
|
+
|
|
9
|
+
Many thanks goes to [Brandon Byars](https://github.com/bbyars) for all the effort building mountebank in the first place and maintaining the project for more than a decade and finally being helpfull and collaborative during this transition phase.
|
|
10
|
+
|
|
11
|
+
# Welcome, friend
|
|
12
|
+
|
|
13
|
+
mountebank is the only open source service virtualization tool that competes with the commercial offerings
|
|
14
|
+
in terms of protocol diversity, capability, and performance. Here's what
|
|
15
|
+
[Capital One wrote](https://medium.com/capital-one-tech/moving-one-of-capital-ones-largest-customer-facing-apps-to-aws-668d797af6fc)
|
|
16
|
+
about their mobile cloud migration (emphasis theirs):
|
|
17
|
+
|
|
18
|
+
>In fact, halfway through we discovered our corporate mocking software couldn’t handle the
|
|
19
|
+
>sheer amount of performance testing we were running as part of this effort (_we completely crushed
|
|
20
|
+
>some pretty industrial enterprise software in the process_). As a result, we made the call to move
|
|
21
|
+
>the entire program over to a Mountebank OSS-based solution with a custom provision to give us the ability
|
|
22
|
+
>to expand/shrink our mocking needs on demand.
|
|
23
|
+
|
|
24
|
+
At the moment, the following protocols are implemented, either directly in the tool or as a community extension:
|
|
25
|
+
* http
|
|
26
|
+
* https
|
|
27
|
+
* tcp (text and binary)
|
|
28
|
+
* smtp
|
|
29
|
+
* ldap
|
|
30
|
+
* grpc
|
|
31
|
+
* websockets
|
|
32
|
+
* graphql
|
|
33
|
+
* snmp
|
|
34
|
+
* telnet
|
|
35
|
+
* ssh
|
|
36
|
+
* netconf
|
|
37
|
+
|
|
38
|
+
mountebank supports mock verification, stubbing with advanced predicates, JavaScript injection,
|
|
39
|
+
and record-playback through proxying.
|
|
40
|
+
|
|
41
|
+

|
|
42
|
+
|
|
43
|
+
See [getting started](http://localhost:2525/docs/gettingStarted) guide for more information once you have it running locally.
|
|
44
|
+
|
|
45
|
+
## Install and Run
|
|
46
|
+
|
|
47
|
+
Install:
|
|
48
|
+
|
|
49
|
+
npm install -g mountebank
|
|
50
|
+
|
|
51
|
+
Run:
|
|
52
|
+
|
|
53
|
+
mb
|
|
54
|
+
|
|
55
|
+
There are a number of [command line options](http://localhost:2525/docs/commandLine) if you need
|
|
56
|
+
to customize mountebank.
|
|
57
|
+
|
|
58
|
+
All pre-release versions of mountebank are available with the `beta` [npm tag](https://www.npmjs.com/package/mountebank).
|
|
59
|
+
No `beta` version is published unless it has passed all tests.
|
|
60
|
+
|
|
61
|
+
## Learn More
|
|
62
|
+
|
|
63
|
+
After installing and running, view the docs in your browser at <http://localhost:2525>.
|
|
64
|
+
|
|
65
|
+
You can always learn more and support mountebank development by buying the book:
|
|
66
|
+
|
|
67
|
+
[](https://www.manning.com/books/testing-microservices-with-mountebank?a_aid=mb&a_bid=ee3288f4)
|
|
68
|
+
|
|
69
|
+
## Building
|
|
70
|
+
|
|
71
|
+
There are two packages: mountebank itself, and a test package called mbTest (which houses all
|
|
72
|
+
out-of-process tests against mountebank). First ensure all dependencies are installed for both packages:
|
|
73
|
+
|
|
74
|
+
npm install
|
|
75
|
+
|
|
76
|
+
Then, run all tests:
|
|
77
|
+
|
|
78
|
+
npm test
|
|
79
|
+
|
|
80
|
+
Several other test configurations exist. You can see the CI pipeline in .circleci/config.yml.
|
|
81
|
+
|
|
82
|
+
There are some tests that require network access.
|
|
83
|
+
A few of these tests verify the correct behavior under DNS failures. If your ISP
|
|
84
|
+
is kind enough to hijack the NXDOMAIN DNS response in an attempt to allow you to conveniently peruse their
|
|
85
|
+
advertising page, those tests will fail. I suggest that, under such circumstances, you talk to your ISP
|
|
86
|
+
and let them know that their policies are causing mountebank tests to fail. You can also set
|
|
87
|
+
the environment variable `MB_AIRPLANE_MODE=true`, which will avoid tests requiring your DNS resolver.
|
|
88
|
+
|
|
89
|
+
[npm-badge]: https://nodei.co/npm/mountebank.png?downloads=true&downloadRank=true&stars=true
|
|
90
|
+
[npm]: https://www.npmjs.com/package/mountebank
|
|
91
|
+
[codeclimate-badge]: https://codeclimate.com/github/mountebank-testing/mountebank/badges/gpa.svg
|
|
92
|
+
[codeclimate]: https://codeclimate.com/github/mountebank-testing/mountebank
|
|
93
|
+
[codeclimate-coverage-badge]: https://codeclimate.com/github/mountebank-testing/mountebank/badges/coverage.svg
|
|
94
|
+
[codeclimate-coverage]: https://codeclimate.com/github/mountebank-testing/mountebank/coverage
|
package/bin/mb
ADDED
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
'use strict';
|
|
4
|
+
|
|
5
|
+
const mountebank = require('../src/mountebank'),
|
|
6
|
+
api = require('../src/cli/api'),
|
|
7
|
+
cli = require('../src/cli/cli'),
|
|
8
|
+
fs = require('fs-extra');
|
|
9
|
+
|
|
10
|
+
function processExists (pid) {
|
|
11
|
+
try {
|
|
12
|
+
// "As a special case, signal 0 can be used to test existence of process"
|
|
13
|
+
// https://nodejs.org/api/process.html#process_process_kill_pid_signal
|
|
14
|
+
process.kill(pid, 0);
|
|
15
|
+
return true;
|
|
16
|
+
}
|
|
17
|
+
catch (e) {
|
|
18
|
+
return false;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
function serverAt (options) {
|
|
23
|
+
async function start () {
|
|
24
|
+
// Set in case npm dependencies do anything with this
|
|
25
|
+
if (!process.env.NODE_ENV) {
|
|
26
|
+
process.env.NODE_ENV = 'production';
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
const server = await mountebank.create(options);
|
|
30
|
+
|
|
31
|
+
function shutdown () {
|
|
32
|
+
server.close(() => {
|
|
33
|
+
try {
|
|
34
|
+
if (fs.existsSync(options.pidfile)) {
|
|
35
|
+
fs.unlinkSync(options.pidfile);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
finally {
|
|
39
|
+
process.exit(); // eslint-disable-line no-process-exit
|
|
40
|
+
}
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
process.on('SIGINT', shutdown);
|
|
45
|
+
process.on('SIGTERM', shutdown);
|
|
46
|
+
|
|
47
|
+
if (options.configfile) {
|
|
48
|
+
await api.loadConfig(options, server);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
// Useful for build plugins that need to wait for mb to be fully initialized
|
|
52
|
+
// They can wait for the pidfile to be written
|
|
53
|
+
fs.writeFileSync(options.pidfile, process.pid.toString());
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
function stop () {
|
|
57
|
+
if (!fs.existsSync(options.pidfile)) {
|
|
58
|
+
return Promise.resolve(true);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
const pid = fs.readFileSync(options.pidfile);
|
|
62
|
+
if (!processExists(pid)) {
|
|
63
|
+
fs.unlinkSync(options.pidfile);
|
|
64
|
+
return Promise.resolve(true);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
return new Promise(resolve => {
|
|
68
|
+
const startTime = new Date(),
|
|
69
|
+
timeout = 1000,
|
|
70
|
+
waitForClose = () => {
|
|
71
|
+
const elapsedTime = new Date() - startTime;
|
|
72
|
+
if (!fs.existsSync(options.pidfile)) {
|
|
73
|
+
resolve();
|
|
74
|
+
}
|
|
75
|
+
else if (elapsedTime > timeout) {
|
|
76
|
+
try {
|
|
77
|
+
// For Windows, which doesn't register signal handlers
|
|
78
|
+
fs.unlinkSync(options.pidfile);
|
|
79
|
+
}
|
|
80
|
+
catch (err) { /* ignore */ }
|
|
81
|
+
finally {
|
|
82
|
+
resolve();
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
else {
|
|
86
|
+
setTimeout(waitForClose, 100);
|
|
87
|
+
}
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
process.kill(pid);
|
|
91
|
+
waitForClose();
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
async function restart () {
|
|
96
|
+
await stop();
|
|
97
|
+
await start();
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
return {
|
|
101
|
+
start: start,
|
|
102
|
+
stop: stop,
|
|
103
|
+
restart: restart
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
try {
|
|
108
|
+
const server = serverAt(cli.args);
|
|
109
|
+
|
|
110
|
+
switch (cli.command) {
|
|
111
|
+
case 'start':
|
|
112
|
+
server.start();
|
|
113
|
+
break;
|
|
114
|
+
case 'stop':
|
|
115
|
+
server.stop();
|
|
116
|
+
break;
|
|
117
|
+
case 'restart':
|
|
118
|
+
server.restart();
|
|
119
|
+
break;
|
|
120
|
+
case 'save':
|
|
121
|
+
api.save(cli.args);
|
|
122
|
+
break;
|
|
123
|
+
case 'replay':
|
|
124
|
+
api.replay(cli.args);
|
|
125
|
+
break;
|
|
126
|
+
case 'help':
|
|
127
|
+
cli.help();
|
|
128
|
+
break;
|
|
129
|
+
default:
|
|
130
|
+
cli.error(`Invalid command '${cli.command}'.`);
|
|
131
|
+
break;
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
catch (err) {
|
|
135
|
+
cli.error(err.message);
|
|
136
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@mbtest/mountebank",
|
|
3
|
+
"version": "2.9.2-beta.9050",
|
|
4
|
+
"author": "Brandon Byars <brandon.byars@gmail.com>",
|
|
5
|
+
"description": "Over the wire test doubles",
|
|
6
|
+
"homepage": "http://www.mbtest.dev",
|
|
7
|
+
"license": "MIT",
|
|
8
|
+
"repository": {
|
|
9
|
+
"type": "git",
|
|
10
|
+
"url": "https://github.com/mountebank-testing/mountebank.git"
|
|
11
|
+
},
|
|
12
|
+
"bugs": {
|
|
13
|
+
"url": "https://github.com/mountebank-testing/mountebank/issues",
|
|
14
|
+
"email": "brandon.byars@gmail.com"
|
|
15
|
+
},
|
|
16
|
+
"bin": {
|
|
17
|
+
"mb": "./bin/mb"
|
|
18
|
+
},
|
|
19
|
+
"main": "./src/mountebank.js",
|
|
20
|
+
"scripts": {},
|
|
21
|
+
"files": [
|
|
22
|
+
"bin",
|
|
23
|
+
"src",
|
|
24
|
+
"package.json",
|
|
25
|
+
"package-lock.json",
|
|
26
|
+
"README.md",
|
|
27
|
+
"LICENSE",
|
|
28
|
+
"releases.json"
|
|
29
|
+
],
|
|
30
|
+
"keywords": [
|
|
31
|
+
"test",
|
|
32
|
+
"stub",
|
|
33
|
+
"mock",
|
|
34
|
+
"double",
|
|
35
|
+
"smtp",
|
|
36
|
+
"email",
|
|
37
|
+
"http",
|
|
38
|
+
"https",
|
|
39
|
+
"tcp",
|
|
40
|
+
"net",
|
|
41
|
+
"service virtualization"
|
|
42
|
+
],
|
|
43
|
+
"dependencies": {
|
|
44
|
+
"@xmldom/xmldom": "0.8.10",
|
|
45
|
+
"cors": "2.8.5",
|
|
46
|
+
"csv-parse": "5.5.3",
|
|
47
|
+
"ejs": "3.1.9",
|
|
48
|
+
"errorhandler": "1.5.1",
|
|
49
|
+
"escape-html": "1.0.3",
|
|
50
|
+
"express": "4.18.2",
|
|
51
|
+
"fs-extra": "11.2.0",
|
|
52
|
+
"http-proxy-agent": "7.0.0",
|
|
53
|
+
"https-proxy-agent": "7.0.2",
|
|
54
|
+
"jsonpath-plus": "8.0.0",
|
|
55
|
+
"mailparser": "3.6.7",
|
|
56
|
+
"mountebank-formatters": "0.0.2",
|
|
57
|
+
"nodemailer": "6.9.9",
|
|
58
|
+
"prom-client": "15.1.0",
|
|
59
|
+
"proper-lockfile": "4.1.2",
|
|
60
|
+
"safe-regex": "^2.1.1",
|
|
61
|
+
"safe-stable-stringify": "2.4.3",
|
|
62
|
+
"smtp-server": "3.13.2",
|
|
63
|
+
"winston": "3.11.0",
|
|
64
|
+
"xpath": "0.0.34",
|
|
65
|
+
"yargs": "17.7.2"
|
|
66
|
+
},
|
|
67
|
+
"engines": {
|
|
68
|
+
"node": ">=18"
|
|
69
|
+
},
|
|
70
|
+
"snyk": true
|
|
71
|
+
}
|
package/releases.json
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
[
|
|
2
|
+
{ "version": "v1.1.0", "date": "2014-05-09" },
|
|
3
|
+
{ "version": "v1.1.36", "date": "2014-05-20" },
|
|
4
|
+
{ "version": "v1.1.72", "date": "2014-12-31" },
|
|
5
|
+
{ "version": "v1.2.0", "date": "2015-01-03" },
|
|
6
|
+
{ "version": "v1.2.30", "date": "2015-01-24" },
|
|
7
|
+
{ "version": "v1.2.45", "date": "2015-02-16" },
|
|
8
|
+
{ "version": "v1.2.56", "date": "2015-03-14" },
|
|
9
|
+
{ "version": "v1.2.103", "date": "2015-04-12" },
|
|
10
|
+
{ "version": "v1.2.122", "date": "2015-05-04" },
|
|
11
|
+
{ "version": "v1.3.0", "date": "2015-09-20" },
|
|
12
|
+
{ "version": "v1.3.1", "date": "2015-10-11" },
|
|
13
|
+
{ "version": "v1.4.0", "date": "2015-10-14" },
|
|
14
|
+
{ "version": "v1.4.1", "date": "2015-10-23" },
|
|
15
|
+
{ "version": "v1.4.2", "date": "2015-11-07" },
|
|
16
|
+
{ "version": "v1.4.3", "date": "2016-01-16" },
|
|
17
|
+
{ "version": "v1.5.0", "date": "2016-04-11" },
|
|
18
|
+
{ "version": "v1.5.1", "date": "2016-04-18" },
|
|
19
|
+
{ "version": "v1.6.0", "date": "2016-08-15" },
|
|
20
|
+
{ "version": "v1.7.0", "date": "2016-11-29" },
|
|
21
|
+
{ "version": "v1.7.1", "date": "2016-11-30" },
|
|
22
|
+
{ "version": "v1.7.2", "date": "2016-12-2" },
|
|
23
|
+
{ "version": "v1.8.0", "date": "2017-01-03" },
|
|
24
|
+
{ "version": "v1.9.0", "date": "2017-02-26" },
|
|
25
|
+
{ "version": "v1.10.0", "date": "2017-04-02" },
|
|
26
|
+
{ "version": "v1.11.0", "date": "2017-05-20" },
|
|
27
|
+
{ "version": "v1.12.0", "date": "2017-07-22" },
|
|
28
|
+
{ "version": "v1.13.0", "date": "2017-10-27" },
|
|
29
|
+
{ "version": "v1.14.0", "date": "2018-02-18" },
|
|
30
|
+
{ "version": "v1.14.1", "date": "2018-05-16" },
|
|
31
|
+
{ "version": "v1.15.0", "date": "2018-08-26" },
|
|
32
|
+
{ "version": "v1.16.0", "date": "2018-12-21" },
|
|
33
|
+
{ "version": "v2.0.0", "date": "2019-03-15" },
|
|
34
|
+
{ "version": "v2.1.0", "date": "2019-06-19" },
|
|
35
|
+
{ "version": "v2.1.1", "date": "2019-10-13" },
|
|
36
|
+
{ "version": "v2.1.2", "date": "2019-10-19" },
|
|
37
|
+
{ "version": "v2.2.0", "date": "2020-02-09" },
|
|
38
|
+
{ "version": "v2.2.1", "date": "2020-04-26" },
|
|
39
|
+
{ "version": "v2.3.0", "date": "2020-09-07" },
|
|
40
|
+
{ "version": "v2.3.1", "date": "2020-09-26" },
|
|
41
|
+
{ "version": "v2.3.2", "date": "2020-09-27" },
|
|
42
|
+
{ "version": "v2.3.3", "date": "2020-10-18" },
|
|
43
|
+
{ "version": "v2.4.0", "date": "2020-12-29" },
|
|
44
|
+
{ "version": "v2.5.0", "date": "2021-09-15" },
|
|
45
|
+
{ "version": "v2.6.0", "date": "2022-02-20" },
|
|
46
|
+
{ "version": "v2.7.0", "date": "2022-07-17" },
|
|
47
|
+
{ "version": "v2.8.0", "date": "2022-10-16" },
|
|
48
|
+
{ "version": "v2.8.1", "date": "2022-10-16" },
|
|
49
|
+
{ "version": "v2.8.2", "date": "2023-01-22" },
|
|
50
|
+
{ "version": "v2.9.0", "date": "2023-08-23" },
|
|
51
|
+
{ "version": "v2.9.1", "date": "2023-08-23" }
|
|
52
|
+
]
|
package/src/cli/api.js
ADDED
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const http = require('http');
|
|
4
|
+
|
|
5
|
+
function curl (options, method, path, body) {
|
|
6
|
+
return new Promise((resolve, reject) => {
|
|
7
|
+
const requestOptions = {
|
|
8
|
+
method: method,
|
|
9
|
+
path: path,
|
|
10
|
+
port: options.port,
|
|
11
|
+
hostname: options.host || 'localhost',
|
|
12
|
+
headers: {
|
|
13
|
+
'Content-Type': 'application/json',
|
|
14
|
+
Connection: 'close'
|
|
15
|
+
}
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
if (options.apikey) {
|
|
19
|
+
requestOptions.headers['x-api-key'] = options.apikey;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
const request = http.request(requestOptions, response => {
|
|
23
|
+
response.body = '';
|
|
24
|
+
response.setEncoding('utf8');
|
|
25
|
+
response.on('data', chunk => { response.body += chunk; });
|
|
26
|
+
response.on('end', () => {
|
|
27
|
+
if (response.statusCode === 200) {
|
|
28
|
+
response.body = JSON.parse(response.body);
|
|
29
|
+
resolve(response);
|
|
30
|
+
}
|
|
31
|
+
else {
|
|
32
|
+
reject(new Error(`${response.statusCode}\n${response.body}`));
|
|
33
|
+
}
|
|
34
|
+
});
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
request.on('error', reject);
|
|
38
|
+
|
|
39
|
+
if (body) {
|
|
40
|
+
request.write(JSON.stringify(body, null, 2));
|
|
41
|
+
}
|
|
42
|
+
request.end();
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
function putImposters (options, body) {
|
|
47
|
+
return curl(options, 'PUT', '/imposters', body);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
function getImposters (options) {
|
|
51
|
+
let path = '/imposters?replayable=true';
|
|
52
|
+
if (options.removeProxies) {
|
|
53
|
+
path += '&removeProxies=true';
|
|
54
|
+
}
|
|
55
|
+
return curl(options, 'GET', path);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
function logConnectionErrorAndExit (options, err) {
|
|
59
|
+
const host = options.host || 'localhost';
|
|
60
|
+
if (err.code === 'ENOENT') {
|
|
61
|
+
console.error(`No such file: ${options.configfile}`);
|
|
62
|
+
}
|
|
63
|
+
if (err.code === 'ECONNREFUSED') {
|
|
64
|
+
console.error(`No mb process running on http://${host}:${options.port}`);
|
|
65
|
+
}
|
|
66
|
+
else {
|
|
67
|
+
console.error(err);
|
|
68
|
+
}
|
|
69
|
+
process.exit(1); // eslint-disable-line no-process-exit
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
async function loadConfig (options) {
|
|
73
|
+
const formatter = require(options.formatter);
|
|
74
|
+
|
|
75
|
+
try {
|
|
76
|
+
const imposters = await formatter.load(options);
|
|
77
|
+
await putImposters(options, imposters);
|
|
78
|
+
}
|
|
79
|
+
catch (e) {
|
|
80
|
+
logConnectionErrorAndExit(options, e);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
async function save (options) {
|
|
85
|
+
const formatter = require(options.formatter);
|
|
86
|
+
|
|
87
|
+
try {
|
|
88
|
+
const response = await getImposters(options);
|
|
89
|
+
await formatter.save(options, response.body);
|
|
90
|
+
}
|
|
91
|
+
catch (e) {
|
|
92
|
+
logConnectionErrorAndExit(options, e);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
async function replay (options) {
|
|
97
|
+
options.removeProxies = true;
|
|
98
|
+
|
|
99
|
+
try {
|
|
100
|
+
const response = await getImposters(options);
|
|
101
|
+
await putImposters(options, response.body);
|
|
102
|
+
}
|
|
103
|
+
catch (e) {
|
|
104
|
+
logConnectionErrorAndExit(e, options);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
module.exports = {
|
|
109
|
+
loadConfig,
|
|
110
|
+
save,
|
|
111
|
+
replay
|
|
112
|
+
};
|