stoobly-agent 1.2.3__py3-none-any.whl → 1.4.0__py3-none-any.whl
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.
- stoobly_agent/__init__.py +1 -1
- stoobly_agent/app/api/application_http_request_handler.py +3 -3
- stoobly_agent/app/api/proxy_controller.py +8 -7
- stoobly_agent/app/cli/config_cli.py +1 -1
- stoobly_agent/app/cli/helpers/certificate_authority.py +7 -6
- stoobly_agent/app/cli/helpers/print_service.py +17 -0
- stoobly_agent/app/cli/scaffold/app.py +16 -34
- stoobly_agent/app/cli/scaffold/app_command.py +4 -7
- stoobly_agent/app/cli/scaffold/app_config.py +15 -2
- stoobly_agent/app/cli/scaffold/app_create_command.py +18 -2
- stoobly_agent/app/cli/scaffold/command.py +1 -1
- stoobly_agent/app/cli/scaffold/constants.py +9 -5
- stoobly_agent/app/cli/scaffold/docker/app_builder.py +3 -7
- stoobly_agent/app/cli/scaffold/docker/constants.py +0 -1
- stoobly_agent/app/cli/scaffold/docker/service/builder.py +12 -11
- stoobly_agent/app/cli/scaffold/docker/workflow/builder.py +14 -31
- stoobly_agent/app/cli/scaffold/docker/workflow/mock_decorator.py +6 -2
- stoobly_agent/app/cli/scaffold/docker/workflow/reverse_proxy_decorator.py +6 -2
- stoobly_agent/app/cli/scaffold/hosts_file_manager.py +112 -0
- stoobly_agent/app/cli/scaffold/service.py +1 -2
- stoobly_agent/app/cli/scaffold/service_command.py +1 -1
- stoobly_agent/app/cli/scaffold/service_config.py +10 -14
- stoobly_agent/app/cli/scaffold/service_workflow_validate_command.py +9 -11
- stoobly_agent/app/cli/scaffold/templates/app/.Dockerfile.context +2 -4
- stoobly_agent/app/cli/scaffold/templates/app/.Makefile +108 -68
- stoobly_agent/app/cli/scaffold/templates/app/.docker-compose.base.yml +8 -13
- stoobly_agent/app/cli/scaffold/templates/app/Makefile +1 -1
- stoobly_agent/app/cli/scaffold/templates/app/build/.docker-compose.base.yml +8 -4
- stoobly_agent/app/cli/scaffold/templates/app/build/mock/.docker-compose.mock.yml +2 -6
- stoobly_agent/app/cli/scaffold/templates/app/build/mock/bin/.configure +3 -0
- stoobly_agent/app/cli/scaffold/templates/app/build/mock/bin/.init +3 -0
- stoobly_agent/app/cli/scaffold/templates/app/build/record/.docker-compose.record.yml +2 -6
- stoobly_agent/app/cli/scaffold/templates/app/build/record/bin/.configure +3 -0
- stoobly_agent/app/cli/scaffold/templates/app/build/record/bin/.init +3 -0
- stoobly_agent/app/cli/scaffold/templates/app/build/test/.docker-compose.test.yml +2 -6
- stoobly_agent/app/cli/scaffold/templates/app/build/test/bin/.configure +3 -0
- stoobly_agent/app/cli/scaffold/templates/app/build/test/bin/.init +3 -0
- stoobly_agent/app/cli/scaffold/templates/app/entrypoint/.docker-compose.base.yml +2 -0
- stoobly_agent/app/cli/scaffold/templates/app/entrypoint/mock/.docker-compose.mock.yml +2 -8
- stoobly_agent/app/cli/scaffold/templates/app/entrypoint/record/.docker-compose.record.yml +2 -8
- stoobly_agent/app/cli/scaffold/templates/app/entrypoint/test/.docker-compose.test.yml +2 -8
- stoobly_agent/app/cli/scaffold/templates/app/stoobly-ui/exec/.docker-compose.exec.yml +2 -3
- stoobly_agent/app/cli/scaffold/templates/app/stoobly-ui/exec/bin/.logs +1 -0
- stoobly_agent/app/cli/scaffold/templates/app/stoobly-ui/exec/bin/.services +9 -0
- stoobly_agent/app/cli/scaffold/templates/app/stoobly-ui/mock/.docker-compose.mock.yml +1 -2
- stoobly_agent/app/cli/scaffold/templates/app/stoobly-ui/record/.docker-compose.record.yml +1 -2
- stoobly_agent/app/cli/scaffold/templates/workflow/mock/bin/.configure +3 -0
- stoobly_agent/app/cli/scaffold/templates/workflow/mock/bin/.init +7 -1
- stoobly_agent/app/cli/scaffold/templates/workflow/record/bin/.configure +3 -0
- stoobly_agent/app/cli/scaffold/templates/workflow/record/bin/.init +7 -1
- stoobly_agent/app/cli/scaffold/templates/workflow/test/bin/.configure +3 -0
- stoobly_agent/app/cli/scaffold/templates/workflow/test/bin/.init +7 -1
- stoobly_agent/app/cli/scaffold/validate_command.py +2 -2
- stoobly_agent/app/cli/scaffold/workflow.py +5 -4
- stoobly_agent/app/cli/scaffold/workflow_command.py +3 -3
- stoobly_agent/app/cli/scaffold/workflow_create_command.py +0 -1
- stoobly_agent/app/cli/scaffold/workflow_run_command.py +78 -45
- stoobly_agent/app/cli/scaffold_cli.py +246 -109
- stoobly_agent/app/cli/snapshot_cli.py +7 -3
- stoobly_agent/app/models/adapters/joined_request_adapter.py +6 -0
- stoobly_agent/app/models/factories/resource/local_db/helpers/scenario_snapshot.py +3 -1
- stoobly_agent/app/models/helpers/apply.py +34 -17
- stoobly_agent/app/models/helpers/create_request_params_service.py +4 -0
- stoobly_agent/app/proxy/handle_mock_service.py +2 -0
- stoobly_agent/app/proxy/handle_replay_service.py +2 -0
- stoobly_agent/app/proxy/mitmproxy/request_facade.py +1 -1
- stoobly_agent/app/proxy/mitmproxy/response_body_facade.py +19 -0
- stoobly_agent/app/proxy/mitmproxy/response_facade.py +90 -18
- stoobly_agent/app/proxy/record/join_request_service.py +1 -1
- stoobly_agent/app/proxy/replay/body_parser_service.py +11 -3
- stoobly_agent/app/settings/constants/request_component.py +2 -1
- stoobly_agent/config/constants/custom_headers.py +13 -13
- stoobly_agent/config/constants/headers.py +0 -2
- stoobly_agent/config/data_dir.py +2 -1
- stoobly_agent/config/schema.yml +2 -2
- stoobly_agent/public/18-es2015.583f191cc7ad512ee262.js +1 -0
- stoobly_agent/public/18-es5.583f191cc7ad512ee262.js +1 -0
- stoobly_agent/public/35-es2015.8f79ff8748d4ff06ab03.js +1 -0
- stoobly_agent/public/35-es5.8f79ff8748d4ff06ab03.js +1 -0
- stoobly_agent/public/index.html +1 -1
- stoobly_agent/public/main-es2015.2cc16523aa3fcaba51e5.js +1 -0
- stoobly_agent/public/main-es5.2cc16523aa3fcaba51e5.js +1 -0
- stoobly_agent/public/{runtime-es2015.9addf49b79aca951b7e2.js → runtime-es2015.b914470164e4d6e75d96.js} +1 -1
- stoobly_agent/public/{runtime-es5.9addf49b79aca951b7e2.js → runtime-es5.b914470164e4d6e75d96.js} +1 -1
- stoobly_agent/test/app/cli/scaffold/cli_invoker.py +1 -2
- stoobly_agent/test/app/cli/scaffold/{hosts_file_reader_test.py → hosts_file_manager_test.py} +20 -20
- stoobly_agent/test/app/cli/snapshot/snapshot_apply_test.py +162 -1
- stoobly_agent/test/app/models/schemas/.stoobly/db/VERSION +1 -1
- stoobly_agent/test/mock_data/scaffold/docker-compose-assets-service.yml +1 -3
- {stoobly_agent-1.2.3.dist-info → stoobly_agent-1.4.0.dist-info}/METADATA +1 -1
- {stoobly_agent-1.2.3.dist-info → stoobly_agent-1.4.0.dist-info}/RECORD +94 -93
- stoobly_agent/app/cli/scaffold/hosts_file_reader.py +0 -65
- stoobly_agent/app/cli/scaffold/templates/app/.Dockerfile.proxy +0 -34
- stoobly_agent/public/18-es2015.d3b430636a4d6f544d92.js +0 -1
- stoobly_agent/public/18-es5.d3b430636a4d6f544d92.js +0 -1
- stoobly_agent/public/35-es2015.f741ebce0bfc25f0ec99.js +0 -1
- stoobly_agent/public/35-es5.f741ebce0bfc25f0ec99.js +0 -1
- stoobly_agent/public/main-es2015.ccd46ac1b6638ddf2066.js +0 -1
- stoobly_agent/public/main-es5.ccd46ac1b6638ddf2066.js +0 -1
- {stoobly_agent-1.2.3.dist-info → stoobly_agent-1.4.0.dist-info}/LICENSE +0 -0
- {stoobly_agent-1.2.3.dist-info → stoobly_agent-1.4.0.dist-info}/WHEEL +0 -0
- {stoobly_agent-1.2.3.dist-info → stoobly_agent-1.4.0.dist-info}/entry_points.txt +0 -0
@@ -1 +1 @@
|
|
1
|
-
!function(e){function r(r){for(var
|
1
|
+
!function(e){function r(r){for(var a,f,o=r[0],b=r[1],d=r[2],i=0,l=[];i<o.length;i++)f=o[i],Object.prototype.hasOwnProperty.call(c,f)&&c[f]&&l.push(c[f][0]),c[f]=0;for(a in b)Object.prototype.hasOwnProperty.call(b,a)&&(e[a]=b[a]);for(u&&u(r);l.length;)l.shift()();return n.push.apply(n,d||[]),t()}function t(){for(var e,r=0;r<n.length;r++){for(var t=n[r],a=!0,o=1;o<t.length;o++)0!==c[t[o]]&&(a=!1);a&&(n.splice(r--,1),e=f(f.s=t[0]))}return e}var a={},c={11:0},n=[];function f(r){if(a[r])return a[r].exports;var t=a[r]={i:r,l:!1,exports:{}};return e[r].call(t.exports,t,t.exports,f),t.l=!0,t.exports}f.e=function(e){var r=[],t=c[e];if(0!==t)if(t)r.push(t[2]);else{var a=new Promise(function(r,a){t=c[e]=[r,a]});r.push(t[2]=a);var n,o=document.createElement("script");o.charset="utf-8",o.timeout=120,f.nc&&o.setAttribute("nonce",f.nc),o.src=function(e){return f.p+""+({3:"common"}[e]||e)+"-es2015."+{0:"c7c5a6d51b98cb85b9fc",1:"bb4492eeabe1fe937ada",2:"51eb8544ea9a21f2874c",3:"388805227aa99c527fba",4:"f8ac5475bf103969b2d2",5:"90ea7bd4439d9749e052",6:"5fb726c0555664300974",7:"19ccb84e62e2ea874f53",8:"b901639e2aeff1358c3d",9:"b7bcad8238f58e214f03",10:"56da22458086513ba0c7",12:"be58ed0ef449008b932e",13:"343b0261a8b3b3f4a1fc",14:"b6619d7742671d2a37fb",15:"d8855701408b0e1d7a3e",16:"98fa59c2c96d2caac3c3",17:"7f60b56d1fd66d4d5544",18:"583f191cc7ad512ee262",19:"78ec0e9fd228b5104712",20:"90544c488f1f0900bab4",21:"63ed4e6b242fbc047bd6",22:"1e96ef651f96d51191e2",23:"6d3052555b4fac38f16d",28:"a2bf42f38e4dd771ccea",29:"18b515f07c88753c7eb6",30:"d4d3dc4101400cadf3f3",31:"e3ea815f75c19c217b7d",32:"57553995bff0ae518501",33:"da5ba1e5baa164921198",34:"87acbb95cfb824650157",35:"8f79ff8748d4ff06ab03",36:"e3a104020eeec02cb8c4",37:"3b472e6cf303201bbf2c",38:"39dbf43d46cdc94f78c6",39:"e5475ea4fb6ec5c60741",40:"47b2873a8439717af6a7",41:"69f2771002745c066976",42:"b590b92ede890155dcd6",43:"ad1d956bffba561ba64c",44:"3ef2c17996ed5be95ced",45:"3d65d27e0a7085e96356",46:"e4f0a5b127eae13c27c0",47:"c7d45334a70131f133b5"}[e]+".js"}(e);var b=new Error;n=function(r){o.onerror=o.onload=null,clearTimeout(d);var t=c[e];if(0!==t){if(t){var a=r&&("load"===r.type?"missing":r.type),n=r&&r.target&&r.target.src;b.message="Loading chunk "+e+" failed.\n("+a+": "+n+")",b.name="ChunkLoadError",b.type=a,b.request=n,t[1](b)}c[e]=void 0}};var d=setTimeout(function(){n({type:"timeout",target:o})},12e4);o.onerror=o.onload=n,document.head.appendChild(o)}return Promise.all(r)},f.m=e,f.c=a,f.d=function(e,r,t){f.o(e,r)||Object.defineProperty(e,r,{enumerable:!0,get:t})},f.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},f.t=function(e,r){if(1&r&&(e=f(e)),8&r)return e;if(4&r&&"object"==typeof e&&e&&e.__esModule)return e;var t=Object.create(null);if(f.r(t),Object.defineProperty(t,"default",{enumerable:!0,value:e}),2&r&&"string"!=typeof e)for(var a in e)f.d(t,a,(function(r){return e[r]}).bind(null,a));return t},f.n=function(e){var r=e&&e.__esModule?function(){return e.default}:function(){return e};return f.d(r,"a",r),r},f.o=function(e,r){return Object.prototype.hasOwnProperty.call(e,r)},f.p="",f.oe=function(e){throw console.error(e),e};var o=window.webpackJsonp=window.webpackJsonp||[],b=o.push.bind(o);o.push=r,o=o.slice();for(var d=0;d<o.length;d++)r(o[d]);var u=b;t()}([]);
|
stoobly_agent/public/{runtime-es5.9addf49b79aca951b7e2.js → runtime-es5.b914470164e4d6e75d96.js}
RENAMED
@@ -1 +1 @@
|
|
1
|
-
!function(e){function r(r){for(var
|
1
|
+
!function(e){function r(r){for(var a,f,o=r[0],b=r[1],d=r[2],i=0,l=[];i<o.length;i++)f=o[i],Object.prototype.hasOwnProperty.call(c,f)&&c[f]&&l.push(c[f][0]),c[f]=0;for(a in b)Object.prototype.hasOwnProperty.call(b,a)&&(e[a]=b[a]);for(u&&u(r);l.length;)l.shift()();return n.push.apply(n,d||[]),t()}function t(){for(var e,r=0;r<n.length;r++){for(var t=n[r],a=!0,o=1;o<t.length;o++)0!==c[t[o]]&&(a=!1);a&&(n.splice(r--,1),e=f(f.s=t[0]))}return e}var a={},c={11:0},n=[];function f(r){if(a[r])return a[r].exports;var t=a[r]={i:r,l:!1,exports:{}};return e[r].call(t.exports,t,t.exports,f),t.l=!0,t.exports}f.e=function(e){var r=[],t=c[e];if(0!==t)if(t)r.push(t[2]);else{var a=new Promise(function(r,a){t=c[e]=[r,a]});r.push(t[2]=a);var n,o=document.createElement("script");o.charset="utf-8",o.timeout=120,f.nc&&o.setAttribute("nonce",f.nc),o.src=function(e){return f.p+""+({3:"common"}[e]||e)+"-es5."+{0:"c7c5a6d51b98cb85b9fc",1:"bb4492eeabe1fe937ada",2:"51eb8544ea9a21f2874c",3:"388805227aa99c527fba",4:"f8ac5475bf103969b2d2",5:"90ea7bd4439d9749e052",6:"5fb726c0555664300974",7:"19ccb84e62e2ea874f53",8:"b901639e2aeff1358c3d",9:"b7bcad8238f58e214f03",10:"56da22458086513ba0c7",12:"be58ed0ef449008b932e",13:"343b0261a8b3b3f4a1fc",14:"b6619d7742671d2a37fb",15:"d8855701408b0e1d7a3e",16:"98fa59c2c96d2caac3c3",17:"7f60b56d1fd66d4d5544",18:"583f191cc7ad512ee262",19:"78ec0e9fd228b5104712",20:"90544c488f1f0900bab4",21:"63ed4e6b242fbc047bd6",22:"1e96ef651f96d51191e2",23:"6d3052555b4fac38f16d",28:"a2bf42f38e4dd771ccea",29:"18b515f07c88753c7eb6",30:"d4d3dc4101400cadf3f3",31:"e3ea815f75c19c217b7d",32:"57553995bff0ae518501",33:"da5ba1e5baa164921198",34:"87acbb95cfb824650157",35:"8f79ff8748d4ff06ab03",36:"e3a104020eeec02cb8c4",37:"3b472e6cf303201bbf2c",38:"39dbf43d46cdc94f78c6",39:"e5475ea4fb6ec5c60741",40:"47b2873a8439717af6a7",41:"69f2771002745c066976",42:"b590b92ede890155dcd6",43:"ad1d956bffba561ba64c",44:"3ef2c17996ed5be95ced",45:"3d65d27e0a7085e96356",46:"e4f0a5b127eae13c27c0",47:"c7d45334a70131f133b5"}[e]+".js"}(e);var b=new Error;n=function(r){o.onerror=o.onload=null,clearTimeout(d);var t=c[e];if(0!==t){if(t){var a=r&&("load"===r.type?"missing":r.type),n=r&&r.target&&r.target.src;b.message="Loading chunk "+e+" failed.\n("+a+": "+n+")",b.name="ChunkLoadError",b.type=a,b.request=n,t[1](b)}c[e]=void 0}};var d=setTimeout(function(){n({type:"timeout",target:o})},12e4);o.onerror=o.onload=n,document.head.appendChild(o)}return Promise.all(r)},f.m=e,f.c=a,f.d=function(e,r,t){f.o(e,r)||Object.defineProperty(e,r,{enumerable:!0,get:t})},f.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},f.t=function(e,r){if(1&r&&(e=f(e)),8&r)return e;if(4&r&&"object"==typeof e&&e&&e.__esModule)return e;var t=Object.create(null);if(f.r(t),Object.defineProperty(t,"default",{enumerable:!0,value:e}),2&r&&"string"!=typeof e)for(var a in e)f.d(t,a,(function(r){return e[r]}).bind(null,a));return t},f.n=function(e){var r=e&&e.__esModule?function(){return e.default}:function(){return e};return f.d(r,"a",r),r},f.o=function(e,r){return Object.prototype.hasOwnProperty.call(e,r)},f.p="",f.oe=function(e){throw console.error(e),e};var o=window.webpackJsonp=window.webpackJsonp||[],b=o.push.bind(o);o.push=r,o=o.slice();for(var d=0;d<o.length;d++)r(o[d]);var u=b;t()}([]);
|
stoobly_agent/test/app/cli/scaffold/{hosts_file_reader_test.py → hosts_file_manager_test.py}
RENAMED
@@ -1,23 +1,23 @@
|
|
1
1
|
import pdb
|
2
2
|
import pytest
|
3
3
|
|
4
|
-
from stoobly_agent.app.cli.scaffold.
|
4
|
+
from stoobly_agent.app.cli.scaffold.hosts_file_manager import HostsFileManager
|
5
5
|
|
6
6
|
|
7
|
-
class
|
7
|
+
class TestHostsFileManager():
|
8
8
|
|
9
9
|
@pytest.fixture
|
10
|
-
def
|
11
|
-
yield
|
10
|
+
def hosts_file_manager(self):
|
11
|
+
yield HostsFileManager()
|
12
12
|
|
13
|
-
def test_get_hosts_file_path(self,
|
14
|
-
hosts_file_path =
|
13
|
+
def test_get_hosts_file_path(self, hosts_file_manager):
|
14
|
+
hosts_file_path = hosts_file_manager._HostsFileManager__get_hosts_file_path()
|
15
15
|
|
16
16
|
# Test runners are all Linux distros for now
|
17
17
|
assert hosts_file_path == '/etc/hosts'
|
18
18
|
|
19
|
-
def test_get_hosts(self,
|
20
|
-
hosts =
|
19
|
+
def test_get_hosts(self, hosts_file_manager):
|
20
|
+
hosts = hosts_file_manager.get_hosts()
|
21
21
|
|
22
22
|
assert hosts
|
23
23
|
assert len(hosts) > 1
|
@@ -29,10 +29,10 @@ class TestHostsFileReader():
|
|
29
29
|
break
|
30
30
|
assert localhost_found
|
31
31
|
|
32
|
-
def test_find_host(self,
|
32
|
+
def test_find_host(self, hosts_file_manager):
|
33
33
|
url = 'localhost'
|
34
34
|
|
35
|
-
host =
|
35
|
+
host = hosts_file_manager.find_host(url)
|
36
36
|
|
37
37
|
assert host
|
38
38
|
assert host.ip_address == '127.0.0.1'
|
@@ -40,36 +40,36 @@ class TestHostsFileReader():
|
|
40
40
|
|
41
41
|
|
42
42
|
class TestsSplitHostsLine():
|
43
|
-
def test_basic(self,
|
43
|
+
def test_basic(self, hosts_file_manager):
|
44
44
|
line = '0.0.0.0 example.com'
|
45
|
-
split =
|
45
|
+
split = hosts_file_manager._HostsFileManager__split_hosts_line(line)
|
46
46
|
|
47
47
|
assert split[0] == '0.0.0.0'
|
48
48
|
assert split[1] == 'example.com'
|
49
49
|
|
50
|
-
def test_tabs(self,
|
50
|
+
def test_tabs(self, hosts_file_manager):
|
51
51
|
line = '0.0.0.0\texample.com'
|
52
|
-
split =
|
52
|
+
split = hosts_file_manager._HostsFileManager__split_hosts_line(line)
|
53
53
|
|
54
54
|
assert split[0] == '0.0.0.0'
|
55
55
|
assert split[1] == 'example.com'
|
56
56
|
|
57
|
-
def test_comment(self,
|
57
|
+
def test_comment(self, hosts_file_manager):
|
58
58
|
line = '# 0.0.0.0 example.com'
|
59
|
-
split =
|
59
|
+
split = hosts_file_manager._HostsFileManager__split_hosts_line(line)
|
60
60
|
|
61
61
|
assert len(split) == 0
|
62
62
|
|
63
|
-
def test_inline_comment(self,
|
63
|
+
def test_inline_comment(self, hosts_file_manager):
|
64
64
|
line = '0.0.0.0\texample.com # Comment'
|
65
|
-
split =
|
65
|
+
split = hosts_file_manager._HostsFileManager__split_hosts_line(line)
|
66
66
|
|
67
67
|
assert split[0] == '0.0.0.0'
|
68
68
|
assert split[1] == 'example.com'
|
69
69
|
|
70
|
-
def test_multiple_hostnames(self,
|
70
|
+
def test_multiple_hostnames(self, hosts_file_manager):
|
71
71
|
line = '0.0.0.0\texample.com example2.com example3.com # Comment'
|
72
|
-
split =
|
72
|
+
split = hosts_file_manager._HostsFileManager__split_hosts_line(line)
|
73
73
|
|
74
74
|
assert split[0] == '0.0.0.0'
|
75
75
|
assert split[1] == 'example.com'
|
@@ -1,3 +1,4 @@
|
|
1
|
+
import os
|
1
2
|
import pdb
|
2
3
|
import pytest
|
3
4
|
import time
|
@@ -13,6 +14,10 @@ from stoobly_agent.lib.orm.request import Request
|
|
13
14
|
from stoobly_agent.lib.orm.scenario import Scenario
|
14
15
|
from stoobly_agent.test.test_helper import assert_orm_request_equivalent, DETERMINISTIC_GET_REQUEST_URL, NON_DETERMINISTIC_GET_REQUEST_URL, reset
|
15
16
|
|
17
|
+
def write_junk(path: str):
|
18
|
+
with open(path, 'w') as fp:
|
19
|
+
fp.write('junk')
|
20
|
+
|
16
21
|
@pytest.fixture(scope='module')
|
17
22
|
def runner():
|
18
23
|
return CliRunner()
|
@@ -386,4 +391,160 @@ class TestApply():
|
|
386
391
|
apply_result = runner.invoke(snapshot, ['apply'])
|
387
392
|
assert apply_result.exit_code == 0
|
388
393
|
|
389
|
-
assert log.version == expected_version
|
394
|
+
assert log.version == expected_version
|
395
|
+
|
396
|
+
class TestWhenMalformedScenarioMetadata():
|
397
|
+
|
398
|
+
@pytest.fixture(scope='class')
|
399
|
+
def created_scenario(self, runner: CliRunner):
|
400
|
+
create_result = runner.invoke(scenario, ['create', 'test'])
|
401
|
+
assert create_result.exit_code == 0
|
402
|
+
return Scenario.last()
|
403
|
+
|
404
|
+
@pytest.fixture(scope='class', autouse=True)
|
405
|
+
def put_event(self, runner: CliRunner, created_scenario: Scenario):
|
406
|
+
snapshot_result = runner.invoke(scenario, ['snapshot', created_scenario.key()])
|
407
|
+
assert snapshot_result.exit_code == 0
|
408
|
+
|
409
|
+
log = Log()
|
410
|
+
events = log.events
|
411
|
+
event = events[len(events) - 1]
|
412
|
+
metadata_path = event.snapshot().metadata_path
|
413
|
+
with open(metadata_path, 'w') as fp:
|
414
|
+
fp.write('junk')
|
415
|
+
|
416
|
+
return event
|
417
|
+
|
418
|
+
@pytest.fixture(scope='class', autouse=True)
|
419
|
+
def removed_scenario(self, created_scenario: Scenario):
|
420
|
+
created_scenario.delete()
|
421
|
+
assert Scenario.find(created_scenario.id) == None
|
422
|
+
|
423
|
+
def test_creates_scenario_with_uuid_name(self, runner: CliRunner, created_scenario: Scenario):
|
424
|
+
apply_result = runner.invoke(snapshot, ['apply'])
|
425
|
+
assert apply_result.exit_code == 0
|
426
|
+
|
427
|
+
recreated_scenario = Scenario.find_by(uuid=created_scenario.uuid)
|
428
|
+
assert recreated_scenario.name == created_scenario.uuid
|
429
|
+
|
430
|
+
class TestWhenMissingScenarioMetadata():
|
431
|
+
|
432
|
+
@pytest.fixture(scope='class')
|
433
|
+
def created_scenario(self, runner: CliRunner):
|
434
|
+
create_result = runner.invoke(scenario, ['create', 'test'])
|
435
|
+
assert create_result.exit_code == 0
|
436
|
+
return Scenario.last()
|
437
|
+
|
438
|
+
@pytest.fixture(scope='class', autouse=True)
|
439
|
+
def put_event(self, runner: CliRunner, created_scenario: Scenario):
|
440
|
+
snapshot_result = runner.invoke(scenario, ['snapshot', created_scenario.key()])
|
441
|
+
assert snapshot_result.exit_code == 0
|
442
|
+
|
443
|
+
log = Log()
|
444
|
+
events = log.events
|
445
|
+
event = events[len(events) - 1]
|
446
|
+
metadata_path = event.snapshot().metadata_path
|
447
|
+
os.remove(metadata_path)
|
448
|
+
|
449
|
+
return event
|
450
|
+
|
451
|
+
@pytest.fixture(scope='class', autouse=True)
|
452
|
+
def removed_scenario(self, created_scenario: Scenario):
|
453
|
+
created_scenario.delete()
|
454
|
+
assert Scenario.find(created_scenario.id) == None
|
455
|
+
|
456
|
+
def test_skips_scenario(self, runner: CliRunner, created_scenario: Scenario):
|
457
|
+
apply_result = runner.invoke(snapshot, ['apply'])
|
458
|
+
assert apply_result.exit_code == 0
|
459
|
+
|
460
|
+
recreated_scenario = Scenario.find_by(uuid=created_scenario.uuid)
|
461
|
+
assert recreated_scenario == None
|
462
|
+
|
463
|
+
class TestWhenMalformedRequest():
|
464
|
+
|
465
|
+
@pytest.fixture(scope='class')
|
466
|
+
def recorded_request(self, runner: CliRunner):
|
467
|
+
record_result = runner.invoke(record, [DETERMINISTIC_GET_REQUEST_URL])
|
468
|
+
assert record_result.exit_code == 0
|
469
|
+
return Request.last()
|
470
|
+
|
471
|
+
@pytest.fixture(autouse=True, scope='class')
|
472
|
+
def put_event(self, runner: CliRunner, recorded_request: Request):
|
473
|
+
snapshot_result = runner.invoke(request, ['snapshot', recorded_request.key()])
|
474
|
+
assert snapshot_result.exit_code == 0
|
475
|
+
|
476
|
+
log = Log()
|
477
|
+
events = log.events
|
478
|
+
event = events[len(events) - 1]
|
479
|
+
|
480
|
+
with open(event.snapshot().path, 'w') as fp:
|
481
|
+
fp.write('junk')
|
482
|
+
|
483
|
+
return event
|
484
|
+
|
485
|
+
@pytest.fixture(scope='class', autouse=True)
|
486
|
+
def removed_request(self, recorded_request: Request):
|
487
|
+
recorded_request.delete()
|
488
|
+
assert Request.find(recorded_request.id) == None
|
489
|
+
|
490
|
+
def test_it_creates_request(self, runner: CliRunner, recorded_request: Request):
|
491
|
+
apply_result = runner.invoke(snapshot, ['apply'])
|
492
|
+
assert apply_result.exit_code == 1
|
493
|
+
|
494
|
+
assert Request.find_by(uuid=recorded_request.uuid) == None
|
495
|
+
|
496
|
+
def test_idempotent(self, runner: CliRunner, recorded_request: Request, put_event: LogEvent):
|
497
|
+
apply_result = runner.invoke(snapshot, ['apply', put_event.uuid])
|
498
|
+
assert apply_result.exit_code == 1
|
499
|
+
|
500
|
+
assert Request.find_by(uuid=recorded_request.uuid) == None
|
501
|
+
|
502
|
+
class TestWhenMalformedScenarioRequest():
|
503
|
+
|
504
|
+
@pytest.fixture(scope='class')
|
505
|
+
def created_scenario(self, runner: CliRunner):
|
506
|
+
create_result = runner.invoke(scenario, ['create', 'test'])
|
507
|
+
assert create_result.exit_code == 0
|
508
|
+
return Scenario.last()
|
509
|
+
|
510
|
+
@pytest.fixture(scope='class', autouse=True)
|
511
|
+
def created_scenario_requests(self, runner: CliRunner, created_scenario: Scenario):
|
512
|
+
record_result = runner.invoke(record, ['--scenario-key', created_scenario.key(), DETERMINISTIC_GET_REQUEST_URL])
|
513
|
+
assert record_result.exit_code == 0
|
514
|
+
|
515
|
+
return created_scenario.requests
|
516
|
+
|
517
|
+
@pytest.fixture(scope='class', autouse=True)
|
518
|
+
def put_event(self, runner: CliRunner, created_scenario: Scenario):
|
519
|
+
snapshot_result = runner.invoke(scenario, ['snapshot', created_scenario.key()])
|
520
|
+
assert snapshot_result.exit_code == 0
|
521
|
+
|
522
|
+
log = Log()
|
523
|
+
events = log.events
|
524
|
+
event = events[len(events) - 1]
|
525
|
+
event.snapshot().iter_request_snapshots(lambda snapshot: write_junk(snapshot.path))
|
526
|
+
|
527
|
+
return event
|
528
|
+
|
529
|
+
@pytest.fixture(scope='class', autouse=True)
|
530
|
+
def removed_scenario(self, created_scenario: Scenario):
|
531
|
+
created_scenario.delete()
|
532
|
+
assert Scenario.find(created_scenario.id) == None
|
533
|
+
|
534
|
+
def test_skips_scenario(self, runner: CliRunner, created_scenario: Scenario):
|
535
|
+
apply_result = runner.invoke(snapshot, ['apply'])
|
536
|
+
assert apply_result.exit_code == 1
|
537
|
+
|
538
|
+
recreated_scenario = Scenario.find_by(uuid=created_scenario.uuid)
|
539
|
+
assert recreated_scenario
|
540
|
+
|
541
|
+
assert len(recreated_scenario.requests) == 0
|
542
|
+
|
543
|
+
def test_idempotent(self, runner: CliRunner, created_scenario: Scenario, put_event: LogEvent):
|
544
|
+
apply_result = runner.invoke(snapshot, ['apply', put_event.uuid])
|
545
|
+
assert apply_result.exit_code == 1
|
546
|
+
|
547
|
+
recreated_scenario = Scenario.find_by(uuid=created_scenario.uuid)
|
548
|
+
assert recreated_scenario
|
549
|
+
|
550
|
+
assert len(recreated_scenario.requests) == 0
|
@@ -1 +1 @@
|
|
1
|
-
1.
|
1
|
+
1.2.3
|
@@ -1,5 +1,4 @@
|
|
1
1
|
# Define services here
|
2
|
-
|
3
2
|
networks:
|
4
3
|
app:
|
5
4
|
external: true
|
@@ -7,12 +6,11 @@ networks:
|
|
7
6
|
|
8
7
|
services:
|
9
8
|
assets:
|
10
|
-
image: nginx:1.27
|
11
9
|
hostname: assets
|
10
|
+
image: nginx:1.27
|
12
11
|
networks:
|
13
12
|
- app
|
14
13
|
volumes:
|
15
14
|
- ./index.html:/usr/share/nginx/html/index.html
|
16
15
|
profiles: &id001
|
17
16
|
- test
|
18
|
-
|