stoobly-agent 1.9.1__py3-none-any.whl → 1.9.2__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/models/factories/resource/local_db/helpers/log.py +39 -24
- stoobly_agent/app/proxy/handle_mock_service.py +15 -9
- stoobly_agent/app/proxy/mock/eval_fixtures_service.py +30 -24
- stoobly_agent/config/constants/custom_headers.py +1 -0
- stoobly_agent/lib/api/keys/uuid_key.py +4 -0
- stoobly_agent/test/app/cli/request/request_snapshot_test.py +54 -4
- stoobly_agent/test/app/cli/snapshot/snapshot_apply_test.py +122 -2
- stoobly_agent/test/app/cli/snapshot/snapshot_prune_test.py +3 -3
- {stoobly_agent-1.9.1.dist-info → stoobly_agent-1.9.2.dist-info}/METADATA +1 -1
- {stoobly_agent-1.9.1.dist-info → stoobly_agent-1.9.2.dist-info}/RECORD +14 -14
- {stoobly_agent-1.9.1.dist-info → stoobly_agent-1.9.2.dist-info}/LICENSE +0 -0
- {stoobly_agent-1.9.1.dist-info → stoobly_agent-1.9.2.dist-info}/WHEEL +0 -0
- {stoobly_agent-1.9.1.dist-info → stoobly_agent-1.9.2.dist-info}/entry_points.txt +0 -0
stoobly_agent/__init__.py
CHANGED
@@ -1,2 +1,2 @@
|
|
1
1
|
COMMAND = 'stoobly-agent'
|
2
|
-
VERSION = '1.9.
|
2
|
+
VERSION = '1.9.2'
|
@@ -70,22 +70,7 @@ class Log():
|
|
70
70
|
|
71
71
|
@property
|
72
72
|
def scenario_inverted_index(self):
|
73
|
-
|
74
|
-
|
75
|
-
def handle_snapshot(snapshot: RequestSnapshot):
|
76
|
-
request_uuid = snapshot.uuid
|
77
|
-
if not request_uuid in index:
|
78
|
-
index[request_uuid] = []
|
79
|
-
|
80
|
-
index[request_uuid].append(event.resource_uuid)
|
81
|
-
|
82
|
-
for event in self.target_events:
|
83
|
-
if not event.is_scenario():
|
84
|
-
continue
|
85
|
-
|
86
|
-
event.snapshot().iter_request_snapshots(handle_snapshot)
|
87
|
-
|
88
|
-
return index
|
73
|
+
return self.build_scenario_inverted_index(self.target_events)
|
89
74
|
|
90
75
|
@property
|
91
76
|
def unprocessed_events(self) -> List[LogEvent]:
|
@@ -153,6 +138,22 @@ class Log():
|
|
153
138
|
|
154
139
|
def build_log_events(self, raw_events) -> List[LogEvent]:
|
155
140
|
return list(map(lambda raw_event: LogEvent(raw_event), raw_events))
|
141
|
+
|
142
|
+
def build_scenario_inverted_index(self, events: List[LogEvent], index = {}):
|
143
|
+
def handle_snapshot(snapshot: RequestSnapshot):
|
144
|
+
request_uuid = snapshot.uuid
|
145
|
+
if not request_uuid in index:
|
146
|
+
index[request_uuid] = []
|
147
|
+
|
148
|
+
index[request_uuid].append(event.resource_uuid)
|
149
|
+
|
150
|
+
for event in events:
|
151
|
+
if not event.is_scenario():
|
152
|
+
continue
|
153
|
+
|
154
|
+
event.snapshot().iter_request_snapshots(handle_snapshot)
|
155
|
+
|
156
|
+
return index
|
156
157
|
|
157
158
|
def next_version(self, last_processed_uuid: str = None):
|
158
159
|
uuids = self.uuids()
|
@@ -169,7 +170,7 @@ class Log():
|
|
169
170
|
def collapse(self, events: List[LogEvent]) -> List[LogEvent]:
|
170
171
|
events_count = {}
|
171
172
|
|
172
|
-
# More recent events take precedence over earlier ones,
|
173
|
+
# More recent events take precedence over earlier ones, only the most recent event
|
173
174
|
for event in events:
|
174
175
|
event_key = event.key
|
175
176
|
|
@@ -274,10 +275,10 @@ class Log():
|
|
274
275
|
|
275
276
|
def remove_dangling_events(self, processed_events: List[LogEvent], unprocessed_events: List[LogEvent]):
|
276
277
|
'''
|
277
|
-
Remove DELETE events
|
278
|
+
Remove DELETE events unless the last processed event was a PUT
|
278
279
|
'''
|
279
280
|
|
280
|
-
# Build an index
|
281
|
+
# Build an index to keep track of the last action that occurred for a resource
|
281
282
|
index = {}
|
282
283
|
for event in processed_events:
|
283
284
|
if event.action == PUT_ACTION:
|
@@ -286,13 +287,27 @@ class Log():
|
|
286
287
|
if event.resource_uuid in index:
|
287
288
|
del index[event.resource_uuid]
|
288
289
|
|
289
|
-
scenario_inverted_index = self.
|
290
|
-
|
290
|
+
scenario_inverted_index = self.build_scenario_inverted_index(processed_events)
|
291
|
+
|
291
292
|
def keep(e: LogEvent):
|
292
|
-
if
|
293
|
+
# Keep the event if it's a PUT, it may have been updated
|
294
|
+
if e.action == PUT_ACTION:
|
293
295
|
return True
|
294
|
-
|
295
|
-
|
296
|
+
|
297
|
+
if e.action == DELETE_ACTION:
|
298
|
+
if e.is_request():
|
299
|
+
referenced = e.resource_uuid in scenario_inverted_index
|
300
|
+
# Keep the DELETE event if the requests exists in a scenario
|
301
|
+
# or if it doesn't exist in a scenario, there was a previous delete event
|
302
|
+
return referenced or (e.resource_uuid in index and not referenced)
|
303
|
+
elif e.is_scenario():
|
304
|
+
# Update scenario_inverted_index with unprocessed event
|
305
|
+
self.build_scenario_inverted_index([e], scenario_inverted_index)
|
306
|
+
|
307
|
+
# Keep DELETE scenario event only if previous event for the resource was PUT
|
308
|
+
return e.resource_uuid in index
|
309
|
+
else:
|
310
|
+
return True
|
296
311
|
|
297
312
|
return list(
|
298
313
|
filter(
|
@@ -147,15 +147,8 @@ def handle_request_mock(context: MockContext):
|
|
147
147
|
# 2. AFTER_MOCK gets triggered (if mock found)
|
148
148
|
#
|
149
149
|
def handle_response_mock(context: MockContext):
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
if request_key:
|
154
|
-
request = context.flow.request
|
155
|
-
Logger.instance(LOG_ID).info(f"{bcolors.OKBLUE}Mocked{bcolors.ENDC} {request.url} -> {request_key}")
|
156
|
-
|
157
|
-
__rewrite_response(context)
|
158
|
-
__mock_hook(lifecycle_hooks.AFTER_MOCK, context)
|
150
|
+
__rewrite_response(context)
|
151
|
+
__mock_hook(lifecycle_hooks.AFTER_MOCK, context)
|
159
152
|
|
160
153
|
def __handle_mock_failure(context: MockContext) -> None:
|
161
154
|
flow = context.flow
|
@@ -186,6 +179,19 @@ def __handle_found_policy(context: MockContext) -> None:
|
|
186
179
|
reverse_proxy(req, upstream_url, {})
|
187
180
|
|
188
181
|
def __handle_mock_success(context: MockContext) -> None:
|
182
|
+
response = context.response
|
183
|
+
|
184
|
+
if response:
|
185
|
+
request = context.flow.request
|
186
|
+
|
187
|
+
request_key = response.headers.get(custom_headers.MOCK_REQUEST_KEY)
|
188
|
+
if request_key:
|
189
|
+
Logger.instance(LOG_ID).info(f"{bcolors.OKBLUE}Mocked{bcolors.ENDC} {request.url} -> {request_key}")
|
190
|
+
|
191
|
+
fixture_path = response.headers.get(custom_headers.MOCK_FIXTURE_PATH)
|
192
|
+
if fixture_path:
|
193
|
+
Logger.instance(LOG_ID).info(f"{bcolors.OKBLUE}Mocked{bcolors.ENDC} {request.url} -> {fixture_path}")
|
194
|
+
|
189
195
|
if os.environ.get(env_vars.AGENT_SIMULATE_LATENCY):
|
190
196
|
response = context.response
|
191
197
|
start_time = context.start_time
|
@@ -10,6 +10,7 @@ from requests.structures import CaseInsensitiveDict
|
|
10
10
|
from typing import Union
|
11
11
|
|
12
12
|
from stoobly_agent.lib.logger import bcolors, Logger
|
13
|
+
from stoobly_agent.config.constants.custom_headers import MOCK_FIXTURE_PATH
|
13
14
|
|
14
15
|
from .types import Fixtures
|
15
16
|
|
@@ -20,45 +21,50 @@ class Options():
|
|
20
21
|
response_fixtures: Fixtures
|
21
22
|
|
22
23
|
def eval_fixtures(request: MitmproxyRequest, **options: Options) -> Union[Response, None]:
|
23
|
-
fixture_path =
|
24
|
+
fixture_path = request.headers.get(MOCK_FIXTURE_PATH)
|
24
25
|
headers = CaseInsensitiveDict()
|
25
26
|
status_code = 200
|
26
27
|
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
if not fixture:
|
31
|
-
public_directory_path = options.get('public_directory_path')
|
32
|
-
|
33
|
-
if not public_directory_path:
|
28
|
+
if fixture_path:
|
29
|
+
if not os.path.exists(fixture_path):
|
34
30
|
return
|
31
|
+
else:
|
32
|
+
response_fixtures = options.get('response_fixtures')
|
33
|
+
fixture: dict = __eval_response_fixtures(request, response_fixtures)
|
35
34
|
|
36
|
-
|
37
|
-
|
38
|
-
if request.headers.get('accept'):
|
39
|
-
fixture_path = __guess_file_path(_fixture_path, request.headers['accept'])
|
35
|
+
if not fixture:
|
36
|
+
public_directory_path = options.get('public_directory_path')
|
40
37
|
|
41
|
-
|
42
|
-
|
38
|
+
if not public_directory_path:
|
39
|
+
return
|
43
40
|
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
41
|
+
request_path = 'index' if request.path == '/' else request.path
|
42
|
+
_fixture_path = os.path.join(public_directory_path, request_path.lstrip('/'))
|
43
|
+
if request.headers.get('accept'):
|
44
|
+
fixture_path = __guess_file_path(_fixture_path, request.headers['accept'])
|
45
|
+
|
46
|
+
if not fixture_path:
|
47
|
+
fixture_path = _fixture_path
|
50
48
|
|
51
|
-
|
52
|
-
|
49
|
+
if not os.path.isfile(fixture_path):
|
50
|
+
return
|
51
|
+
else:
|
52
|
+
fixture_path = fixture.get('path')
|
53
|
+
if not fixture_path or not os.path.isfile(fixture_path):
|
54
|
+
return
|
53
55
|
|
54
|
-
|
55
|
-
|
56
|
+
_headers = fixture.get('headers')
|
57
|
+
headers = CaseInsensitiveDict(_headers if isinstance(_headers, dict) else {})
|
56
58
|
|
59
|
+
if fixture.get('status_code'):
|
60
|
+
status_code = fixture.get('status_code')
|
61
|
+
|
57
62
|
with open(fixture_path, 'rb') as fp:
|
58
63
|
response = Response()
|
59
64
|
|
60
65
|
response.status_code = status_code
|
61
66
|
response.raw = BytesIO(fp.read())
|
67
|
+
headers[MOCK_FIXTURE_PATH] = fixture_path
|
62
68
|
response.headers = headers
|
63
69
|
|
64
70
|
if not response.headers.get('content-type'):
|
@@ -2,6 +2,7 @@ ALIAS_RESOLVE_STRATEGY = 'X-Stoobly-Alias-Resolve-Strategy'
|
|
2
2
|
CONTENT_TYPE = 'X-Stoobly-Content-Type'
|
3
3
|
CONTENT_TYPE_TEST_RESULTS = 'test/results'
|
4
4
|
REMOTE_PROJECT_KEY = 'X-Stoobly-Endpoints-Project-Id'
|
5
|
+
MOCK_FIXTURE_PATH = 'X-Stoobly-Fixture-Path'
|
5
6
|
MOCK_POLICY = 'X-Stoobly-Mock-Policy'
|
6
7
|
MOCK_REQUEST_ID = 'X-Stoobly-Request-Id'
|
7
8
|
MOCK_REQUEST_ENDPOINT_ID = 'X-Stoobly-Request-Endpoint-Id'
|
@@ -1,16 +1,18 @@
|
|
1
1
|
import pdb
|
2
2
|
import pytest
|
3
|
+
import time
|
3
4
|
|
4
5
|
from click.testing import CliRunner
|
5
|
-
|
6
|
-
from stoobly_agent.test.test_helper import DETERMINISTIC_GET_REQUEST_URL, reset
|
6
|
+
from typing import List
|
7
7
|
|
8
8
|
from stoobly_agent.app.models.adapters.orm import JoinedRequestStringAdapter
|
9
9
|
from stoobly_agent.app.models.factories.resource.local_db.helpers.log import Log
|
10
|
-
from stoobly_agent.app.models.factories.resource.local_db.helpers.log_event import DELETE_ACTION
|
10
|
+
from stoobly_agent.app.models.factories.resource.local_db.helpers.log_event import DELETE_ACTION, PUT_ACTION
|
11
11
|
from stoobly_agent.app.models.factories.resource.local_db.helpers.request_snapshot import RequestSnapshot
|
12
|
-
from stoobly_agent.cli import record, request
|
12
|
+
from stoobly_agent.cli import record, request, scenario, snapshot
|
13
13
|
from stoobly_agent.lib.orm.request import Request
|
14
|
+
from stoobly_agent.lib.orm.scenario import Scenario
|
15
|
+
from stoobly_agent.test.test_helper import DETERMINISTIC_GET_REQUEST_URL, NON_DETERMINISTIC_GET_REQUEST_URL, reset
|
14
16
|
|
15
17
|
@pytest.fixture(scope='module')
|
16
18
|
def runner():
|
@@ -122,3 +124,51 @@ class TestRequestSnapshot():
|
|
122
124
|
|
123
125
|
event = unprocessed_events[0]
|
124
126
|
assert event.resource_uuid == recorded_request_two.uuid
|
127
|
+
assert event.action == PUT_ACTION
|
128
|
+
|
129
|
+
class TestWhenDeleteFirst():
|
130
|
+
|
131
|
+
@pytest.fixture(scope='class')
|
132
|
+
def recorded_request(self, runner: CliRunner):
|
133
|
+
record_result = runner.invoke(record, [DETERMINISTIC_GET_REQUEST_URL])
|
134
|
+
assert record_result.exit_code == 0
|
135
|
+
return Request.last()
|
136
|
+
|
137
|
+
def test_initial_delete(self, runner: CliRunner, recorded_request: Request):
|
138
|
+
snapshot_result = runner.invoke(request, ['snapshot', '--action', DELETE_ACTION, recorded_request.key()])
|
139
|
+
assert snapshot_result.exit_code == 0
|
140
|
+
|
141
|
+
log = Log()
|
142
|
+
|
143
|
+
events = log.raw_events
|
144
|
+
assert len(events) == 1
|
145
|
+
|
146
|
+
unprocessed_events = log.unprocessed_events
|
147
|
+
assert len(unprocessed_events) == 0
|
148
|
+
|
149
|
+
def test_puts(self, runner: CliRunner, recorded_request: Request):
|
150
|
+
snapshot_result = runner.invoke(request, ['snapshot', '--action', PUT_ACTION, recorded_request.key()])
|
151
|
+
assert snapshot_result.exit_code == 0
|
152
|
+
|
153
|
+
log = Log()
|
154
|
+
|
155
|
+
events = log.raw_events
|
156
|
+
assert len(events) == 2
|
157
|
+
|
158
|
+
unprocessed_events = log.unprocessed_events
|
159
|
+
assert len(unprocessed_events) == 1
|
160
|
+
assert unprocessed_events[0].action == PUT_ACTION
|
161
|
+
|
162
|
+
def test_final_delete(self, runner: CliRunner, recorded_request: Request):
|
163
|
+
snapshot_result = runner.invoke(request, ['snapshot', '--action', DELETE_ACTION, recorded_request.key()])
|
164
|
+
assert snapshot_result.exit_code == 0
|
165
|
+
|
166
|
+
log = Log()
|
167
|
+
|
168
|
+
events = log.events
|
169
|
+
assert len(events) == 3
|
170
|
+
|
171
|
+
collapsed_events = log.collapse(events)
|
172
|
+
assert len(collapsed_events) == 1
|
173
|
+
unprocessed_events = log.unprocessed_events
|
174
|
+
assert len(unprocessed_events) == 0
|
@@ -556,7 +556,7 @@ class TestApply():
|
|
556
556
|
1. Create scenario
|
557
557
|
2. Add 2 requests to it
|
558
558
|
3. Snapshot scenario
|
559
|
-
4. Snapshot
|
559
|
+
4. Snapshot second request with action DELETE_ACTION
|
560
560
|
5. Apply
|
561
561
|
6. Expect scenario to have 1 request
|
562
562
|
'''
|
@@ -689,4 +689,124 @@ class TestApply():
|
|
689
689
|
|
690
690
|
requests = created_scenario_two.requests
|
691
691
|
|
692
|
-
assert_orm_request_equivalent(requests[0], created_scenario_request)
|
692
|
+
assert_orm_request_equivalent(requests[0], created_scenario_request)
|
693
|
+
|
694
|
+
class TestApply():
|
695
|
+
|
696
|
+
class TestWhenNoApply():
|
697
|
+
'''
|
698
|
+
1. Create scenario
|
699
|
+
2. Add 2 requests to it
|
700
|
+
3. Snapshot scenario
|
701
|
+
4. Apply scenario
|
702
|
+
5. Snapshot second request with action DELETE_ACTION
|
703
|
+
6. Prune
|
704
|
+
7. Apply
|
705
|
+
8. Expect scenario to have 1 request, because scenario depends on the request, should not be able to prune
|
706
|
+
'''
|
707
|
+
|
708
|
+
@pytest.fixture(scope='class')
|
709
|
+
def created_scenario(self, runner: CliRunner):
|
710
|
+
create_result = runner.invoke(scenario, ['create', 'test'])
|
711
|
+
assert create_result.exit_code == 0
|
712
|
+
return Scenario.last()
|
713
|
+
|
714
|
+
@pytest.fixture(scope='class', autouse=True)
|
715
|
+
def created_scenario_requests(self, runner: CliRunner, created_scenario: Scenario):
|
716
|
+
record_result = runner.invoke(record, ['--scenario-key', created_scenario.key(), DETERMINISTIC_GET_REQUEST_URL])
|
717
|
+
assert record_result.exit_code == 0
|
718
|
+
|
719
|
+
record_result = runner.invoke(record, ['--scenario-key', created_scenario.key(), NON_DETERMINISTIC_GET_REQUEST_URL])
|
720
|
+
assert record_result.exit_code == 0
|
721
|
+
|
722
|
+
return created_scenario.requests
|
723
|
+
|
724
|
+
@pytest.fixture(scope='class', autouse=True)
|
725
|
+
def snapshots(self, runner: CliRunner, created_scenario: Scenario, created_scenario_requests: List[Request]):
|
726
|
+
snapshot_result = runner.invoke(scenario, ['snapshot', created_scenario.key()])
|
727
|
+
assert snapshot_result.exit_code == 0
|
728
|
+
|
729
|
+
created_request = created_scenario_requests[1]
|
730
|
+
snapshot_result = runner.invoke(request, ['snapshot', created_request.key(), '--action', DELETE_ACTION])
|
731
|
+
assert snapshot_result.exit_code == 0
|
732
|
+
|
733
|
+
def test_events(self):
|
734
|
+
log = Log()
|
735
|
+
|
736
|
+
events = log.events
|
737
|
+
assert len(events) == 2
|
738
|
+
|
739
|
+
def test_collapsed_events(self):
|
740
|
+
log = Log()
|
741
|
+
|
742
|
+
collapsed_events = log.collapse(log.events)
|
743
|
+
assert len(collapsed_events) == 2
|
744
|
+
|
745
|
+
def test_unprocessed_events(self):
|
746
|
+
log = Log()
|
747
|
+
|
748
|
+
unprocessed_events = log.unprocessed_events
|
749
|
+
assert len(unprocessed_events) == 2
|
750
|
+
|
751
|
+
class TestWhenRemoveScenarioRequest():
|
752
|
+
'''
|
753
|
+
1. Create scenario
|
754
|
+
2. Add 2 requests to it
|
755
|
+
3. Snapshot scenario
|
756
|
+
4. Apply scenario
|
757
|
+
5. Snapshot second request with action DELETE_ACTION
|
758
|
+
6. Prune
|
759
|
+
7. Apply
|
760
|
+
8. Expect scenario to have 1 request, because scenario depends on the request, should not be able to prune
|
761
|
+
'''
|
762
|
+
|
763
|
+
@pytest.fixture(scope='class')
|
764
|
+
def created_scenario(self, runner: CliRunner):
|
765
|
+
create_result = runner.invoke(scenario, ['create', 'test'])
|
766
|
+
assert create_result.exit_code == 0
|
767
|
+
return Scenario.last()
|
768
|
+
|
769
|
+
@pytest.fixture(scope='class', autouse=True)
|
770
|
+
def created_scenario_requests(self, runner: CliRunner, created_scenario: Scenario):
|
771
|
+
record_result = runner.invoke(record, ['--scenario-key', created_scenario.key(), DETERMINISTIC_GET_REQUEST_URL])
|
772
|
+
assert record_result.exit_code == 0
|
773
|
+
|
774
|
+
record_result = runner.invoke(record, ['--scenario-key', created_scenario.key(), NON_DETERMINISTIC_GET_REQUEST_URL])
|
775
|
+
assert record_result.exit_code == 0
|
776
|
+
|
777
|
+
return created_scenario.requests
|
778
|
+
|
779
|
+
@pytest.fixture(scope='class', autouse=True)
|
780
|
+
def apply_result(self, runner: CliRunner, created_scenario: Scenario, created_scenario_requests: List[Request]):
|
781
|
+
snapshot_result = runner.invoke(scenario, ['snapshot', created_scenario.key()])
|
782
|
+
assert snapshot_result.exit_code == 0
|
783
|
+
|
784
|
+
created_scenario = Scenario.find(created_scenario.id)
|
785
|
+
assert created_scenario.requests_count == 2
|
786
|
+
apply_result = runner.invoke(snapshot, ['apply'])
|
787
|
+
assert apply_result.exit_code == 0
|
788
|
+
|
789
|
+
created_request = created_scenario_requests[1]
|
790
|
+
snapshot_result = runner.invoke(request, ['snapshot', created_request.key(), '--action', DELETE_ACTION])
|
791
|
+
assert snapshot_result.exit_code == 0
|
792
|
+
|
793
|
+
return apply_result
|
794
|
+
|
795
|
+
def test_events(self):
|
796
|
+
log = Log()
|
797
|
+
|
798
|
+
events = log.events
|
799
|
+
assert len(events) == 2
|
800
|
+
|
801
|
+
def test_collapsed_events(self):
|
802
|
+
log = Log()
|
803
|
+
|
804
|
+
collapsed_events = log.collapse(log.events)
|
805
|
+
assert len(collapsed_events) == 2
|
806
|
+
|
807
|
+
def test_unprocessed_events(self):
|
808
|
+
log = Log()
|
809
|
+
|
810
|
+
unprocessed_events = log.unprocessed_events
|
811
|
+
assert len(unprocessed_events) == 1
|
812
|
+
assert unprocessed_events[0].action == DELETE_ACTION
|
@@ -116,10 +116,10 @@ class TestPrune():
|
|
116
116
|
1. Create scenario
|
117
117
|
2. Add 2 requests to it
|
118
118
|
3. Snapshot scenario
|
119
|
-
4. Snapshot request with action DELETE_ACTION
|
120
|
-
5. Prune
|
119
|
+
4. Snapshot second request with action DELETE_ACTION
|
120
|
+
5. Prune
|
121
121
|
6. Apply
|
122
|
-
7. Expect scenario to have 1 request
|
122
|
+
7. Expect scenario to have 1 request, because scenario depends on the request, should not be able to prune
|
123
123
|
'''
|
124
124
|
|
125
125
|
@pytest.fixture(scope='class')
|
@@ -1,4 +1,4 @@
|
|
1
|
-
stoobly_agent/__init__.py,sha256=
|
1
|
+
stoobly_agent/__init__.py,sha256=epZElDe2ihHM7JdgjopRIH49aMQpYH4SYIjmxXXMnY0,44
|
2
2
|
stoobly_agent/app/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
3
3
|
stoobly_agent/app/api/__init__.py,sha256=ctkB8KR-eXO0SFhj602huHiyvQ3PslFWd8fkcufgrAI,1000
|
4
4
|
stoobly_agent/app/api/application_http_request_handler.py,sha256=Vvz53yB0bR7J-QqMAkLlhcZrA4P64ZEN7w8cMbgl6o0,5261
|
@@ -258,7 +258,7 @@ stoobly_agent/app/models/factories/resource/local_db/body_adapter.py,sha256=lrnI
|
|
258
258
|
stoobly_agent/app/models/factories/resource/local_db/header_adapter.py,sha256=NQdCErFtJL7sBaLpKLYfJSEA3AiaaVuU7LUcGJ-dHOI,3104
|
259
259
|
stoobly_agent/app/models/factories/resource/local_db/helpers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
260
260
|
stoobly_agent/app/models/factories/resource/local_db/helpers/create_request_columns_service.py,sha256=HABMelW-cvhm2WXaywbQcd4PQhzSrz4vAbN7uOdetXM,1541
|
261
|
-
stoobly_agent/app/models/factories/resource/local_db/helpers/log.py,sha256=
|
261
|
+
stoobly_agent/app/models/factories/resource/local_db/helpers/log.py,sha256=COKyrRFZgxQgLVH6cs_Mvc616BScoldamg8QqG8JV3c,11670
|
262
262
|
stoobly_agent/app/models/factories/resource/local_db/helpers/log_event.py,sha256=30wWhqibTWgnpibosclaB9OCWzArL7R4krGS8WW2bGY,3584
|
263
263
|
stoobly_agent/app/models/factories/resource/local_db/helpers/request_builder.py,sha256=PyVvsYmi5bBQ6PsUPxQ4nJM9rhhjGVOTd7ipuc2tMMM,3227
|
264
264
|
stoobly_agent/app/models/factories/resource/local_db/helpers/request_snapshot.py,sha256=Tpuu7sZ4A2Vc5e5OAyU9pSKzbOpLpZoI-4E2Ty7n4Ac,2672
|
@@ -309,7 +309,7 @@ stoobly_agent/app/proxy/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG
|
|
309
309
|
stoobly_agent/app/proxy/constants/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
310
310
|
stoobly_agent/app/proxy/constants/custom_response_codes.py,sha256=1CaApt_6W7GrxvN8_Ozbf_SEodVEQaNZRR2sMYpI0U8,40
|
311
311
|
stoobly_agent/app/proxy/context.py,sha256=m6iu6QSZsim8meZS8H8DsZeXyjfoC-MRMHhQD1MFKM0,532
|
312
|
-
stoobly_agent/app/proxy/handle_mock_service.py,sha256=
|
312
|
+
stoobly_agent/app/proxy/handle_mock_service.py,sha256=qz7rxAg6R8U9aiXbYjuncDkx5eliPYX3x-uVLelwSr0,9451
|
313
313
|
stoobly_agent/app/proxy/handle_record_service.py,sha256=Fe8RAcMVvHhl3-XgjZ41242p4JXooYHQ-MhjcQhJn2E,4223
|
314
314
|
stoobly_agent/app/proxy/handle_replay_service.py,sha256=kBUYd8kj8UPrsYHoBXmq06DPLjCnHo8K-QsKzhDIKcw,2526
|
315
315
|
stoobly_agent/app/proxy/handle_test_service.py,sha256=WkMPbM4argVtl-TQB7VdQIvB8cOwURAahxFX5Vkqwws,8405
|
@@ -327,7 +327,7 @@ stoobly_agent/app/proxy/mitmproxy/response_facade.py,sha256=0wCSzUULUhDDV93QXUgz
|
|
327
327
|
stoobly_agent/app/proxy/mock/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
328
328
|
stoobly_agent/app/proxy/mock/context.py,sha256=vDo5_3WBL73mVFnsmQWvcxvPg5nWtRJbigSrE3zGc-o,794
|
329
329
|
stoobly_agent/app/proxy/mock/custom_not_found_response_builder.py,sha256=0KWB3KFxVrnJOKDaYxm5eoJEccw7IpJZRyUvBX61-8k,697
|
330
|
-
stoobly_agent/app/proxy/mock/eval_fixtures_service.py,sha256=
|
330
|
+
stoobly_agent/app/proxy/mock/eval_fixtures_service.py,sha256=sVw8l916ouEBj2ViDtHFjgmEA4tLmZGvBfw8wD1Ab-c,4132
|
331
331
|
stoobly_agent/app/proxy/mock/eval_request_service.py,sha256=A1tcE3wmrC1HwLpz0aRuRw-Nucn0dyHD_yHw5BeQEJU,8146
|
332
332
|
stoobly_agent/app/proxy/mock/hashed_request_decorator.py,sha256=h1ma90fdaYI9LBWpMWMqWBz-RjNwI628O4VuS_uUBX4,5061
|
333
333
|
stoobly_agent/app/proxy/mock/ignored_components_response_builder.py,sha256=E32_E1eSdmPn2SeM_e1jWnqu4xh5w_SnmOs32Shx99E,501
|
@@ -419,7 +419,7 @@ stoobly_agent/cli.py,sha256=sw8Ke5mCvzQ50X-zsb2Ld_zW4T6S58P0fN5GyKNOrcQ,10255
|
|
419
419
|
stoobly_agent/config/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
420
420
|
stoobly_agent/config/constants/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
421
421
|
stoobly_agent/config/constants/alias_resolve_strategy.py,sha256=_R1tVqFnyGxCraVS5-dhSskaDj_X8-NthsY7i_bEt9M,119
|
422
|
-
stoobly_agent/config/constants/custom_headers.py,sha256=
|
422
|
+
stoobly_agent/config/constants/custom_headers.py,sha256=8YiKDjrpe0qH8tr4qM_CgonBy6bf_HHTqQ7B_hYv2L0,1398
|
423
423
|
stoobly_agent/config/constants/env_vars.py,sha256=HAR_ZIdXXbpWQgCDaRR5RtpVyGXCsMLr_Fh8n6S12K0,1344
|
424
424
|
stoobly_agent/config/constants/headers.py,sha256=Hfv7R8_NPXAGaMiZPqywGZDnr0qcVUyfenPb4g465rE,169
|
425
425
|
stoobly_agent/config/constants/intercept_policy.py,sha256=5hIgOft8PQmCRdOHb5OEvEj10tU66DIQF3GYltlWyM8,25
|
@@ -488,7 +488,7 @@ stoobly_agent/lib/api/keys/request_key.py,sha256=68hN0KLdf0FwxSCSjeJZ1uUs526PCbN
|
|
488
488
|
stoobly_agent/lib/api/keys/resource_key.py,sha256=9qrkp3t8iJsScZvKVcBDvVbcfwmP0yEBWy3b1tHi8CM,689
|
489
489
|
stoobly_agent/lib/api/keys/scenario_key.py,sha256=VAc6gayvJS7shWgDL3SAqVET3fmgBefcygXTsKot07U,629
|
490
490
|
stoobly_agent/lib/api/keys/test_key.py,sha256=-MCWp1oYLkJ3S_Pqs62j8KkkssXpT9quKb4YqMSq1Ks,438
|
491
|
-
stoobly_agent/lib/api/keys/uuid_key.py,sha256=
|
491
|
+
stoobly_agent/lib/api/keys/uuid_key.py,sha256=30ZJIEAQHsR1KCsmeALxsKwCaUQtm7pKvFUhLmk0J4I,643
|
492
492
|
stoobly_agent/lib/api/param_builder.py,sha256=50eq0zkqRz5MVezPZMIu69fYSB6z4CD5FG26_IU3eq0,996
|
493
493
|
stoobly_agent/lib/api/projects_resource.py,sha256=7leBuQnlpgUwbYUX445lUC3jy-dzLMpTumeNPrqRc5c,1166
|
494
494
|
stoobly_agent/lib/api/query_param_names_resource.py,sha256=k-3nlyfCOa_Vwj-TMI7v8_4g9qAs50baP073gkStAKE,1710
|
@@ -675,7 +675,7 @@ stoobly_agent/test/app/cli/request/request_list_test.py,sha256=tqMjkODU2i2eDvYyk
|
|
675
675
|
stoobly_agent/test/app/cli/request/request_replay_test.py,sha256=w13NzkXhmBKvoogpQ8CdmBbCzoyqxEQvBZsEkGDCPx0,6237
|
676
676
|
stoobly_agent/test/app/cli/request/request_reset_test.py,sha256=5My6Z452eideAOUun77tWUkuu3_yGhDVxCG1baUF8Zo,1290
|
677
677
|
stoobly_agent/test/app/cli/request/request_response_test.py,sha256=Fu-A8tIn016DKme4WIaPzo3YeFY-CPtTOpaSFigUVVM,1263
|
678
|
-
stoobly_agent/test/app/cli/request/request_snapshot_test.py,sha256=
|
678
|
+
stoobly_agent/test/app/cli/request/request_snapshot_test.py,sha256=3kMmv0CuvnMXLgDQA-_u9S1DIiNOdL63L-IptVuOpf8,6308
|
679
679
|
stoobly_agent/test/app/cli/request/request_test_test.py,sha256=-cJNXKjgryVVfVt-7IN5fIhBwe3NjFoPmeavDH8lAjU,5527
|
680
680
|
stoobly_agent/test/app/cli/scaffold/cli_invoker.py,sha256=_nGDLUsYxqkeqs5DdhvAeXy3IuotpgqKHXKVzu6GDF4,3700
|
681
681
|
stoobly_agent/test/app/cli/scaffold/cli_test.py,sha256=sMNvO845MIu5DVGa1HmwXQDmKDcwrfNTdEb3fK5886w,4557
|
@@ -688,10 +688,10 @@ stoobly_agent/test/app/cli/scenario/scenario_reset_test.py,sha256=QOyytOoFu1FALn
|
|
688
688
|
stoobly_agent/test/app/cli/scenario/scenario_snapshot_test.py,sha256=IAe1l69Smd8a9E6I0CVs8lgqnC4mI4M1EFfUjC4ZHs8,3396
|
689
689
|
stoobly_agent/test/app/cli/scenario/scenario_test_integration_test.py,sha256=BdXGe1xfb79tCCTKtp4sqI6CkZL_KamvQKLK8Wwb4u0,5543
|
690
690
|
stoobly_agent/test/app/cli/snapshot/lifecycle_hooks_migrate.py,sha256=x3x5vHfZ1xmoOpZ0yRSB3kbWbPjfbLk2PJFSa1xOLoU,316
|
691
|
-
stoobly_agent/test/app/cli/snapshot/snapshot_apply_test.py,sha256=
|
691
|
+
stoobly_agent/test/app/cli/snapshot/snapshot_apply_test.py,sha256=mpkTZx8eaFFZU_RKHPcphaNl6zKCIOTJ2i4kY9BZRgQ,32395
|
692
692
|
stoobly_agent/test/app/cli/snapshot/snapshot_copy_test.py,sha256=Yg78-FhSiG_r6Jpm-sN8sn0LjVXTwTOXt6hg8ni2GIY,1953
|
693
693
|
stoobly_agent/test/app/cli/snapshot/snapshot_migrate_test.py,sha256=voEvblK6CMGCrSJDTHVmkUkLXj0auNb78jxlGiiBBQQ,7370
|
694
|
-
stoobly_agent/test/app/cli/snapshot/snapshot_prune_test.py,sha256=
|
694
|
+
stoobly_agent/test/app/cli/snapshot/snapshot_prune_test.py,sha256=bn4yUU7Eb4-6GnwnRaPZPi5Cn7XEaIsrJ_mB7jydgWw,6693
|
695
695
|
stoobly_agent/test/app/cli/snapshot/snapshot_update_test.py,sha256=fILsX2M5j4wuLRP6LJTHe4CPB8gvaEbsSoYmFCHmKVk,4514
|
696
696
|
stoobly_agent/test/app/models/adapters/orm/joined_request_string_adapter_test.py,sha256=a2IHTk3l7aiLyYF7vtqissrk0MFTF2wlUBiaKWyJKfU,2667
|
697
697
|
stoobly_agent/test/app/models/adapters/orm/request/orm_mitmproxy_request_adapter_test.py,sha256=PbJsAaxPUEbF9vM7DX4z858biWf4qlGnvE8KBuy8SgY,2763
|
@@ -748,8 +748,8 @@ stoobly_agent/test/mock_data/scaffold/docker-compose-local-service.yml,sha256=1W
|
|
748
748
|
stoobly_agent/test/mock_data/scaffold/index.html,sha256=qJwuYajKZ4ihWZrJQ3BNObV5kf1VGnnm_vqlPJzdqLE,258
|
749
749
|
stoobly_agent/test/mock_data/uspto.yaml,sha256=6U5se7C3o-86J4m9xpOk9Npias399f5CbfWzR87WKwE,7835
|
750
750
|
stoobly_agent/test/test_helper.py,sha256=m_oAI7tmRYCNZdKfNqISWhMv3e44tjeYViQ3nTUfnos,1007
|
751
|
-
stoobly_agent-1.9.
|
752
|
-
stoobly_agent-1.9.
|
753
|
-
stoobly_agent-1.9.
|
754
|
-
stoobly_agent-1.9.
|
755
|
-
stoobly_agent-1.9.
|
751
|
+
stoobly_agent-1.9.2.dist-info/LICENSE,sha256=o93sj12cdoEOsTCjPaPFsw3Xq0SXs3pPcY-9reE2sEw,548
|
752
|
+
stoobly_agent-1.9.2.dist-info/METADATA,sha256=qMOKulRLao6AQJC0ctx4h0IyYP6Fd-ACe5NtoyuIY1U,3087
|
753
|
+
stoobly_agent-1.9.2.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
|
754
|
+
stoobly_agent-1.9.2.dist-info/entry_points.txt,sha256=aq5wix5oC8MDQtmyPGU0xaFrsjJg7WH28NmXh2sc3Z8,56
|
755
|
+
stoobly_agent-1.9.2.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|