stoobly-agent 1.0.6__py3-none-any.whl → 1.0.8__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/cli/scaffold/constants.py +9 -1
- stoobly_agent/app/cli/scaffold/docker/constants.py +6 -0
- stoobly_agent/app/cli/scaffold/docker/workflow/builder.py +0 -2
- stoobly_agent/app/cli/scaffold/docker/workflow/mock_decorator.py +1 -1
- stoobly_agent/app/cli/scaffold/docker/workflow/reverse_proxy_decorator.py +0 -1
- stoobly_agent/app/cli/scaffold/managed_services_docker_compose.py +9 -0
- stoobly_agent/app/cli/scaffold/service_command.py +3 -1
- stoobly_agent/app/cli/scaffold/service_config.py +2 -1
- stoobly_agent/app/cli/scaffold/service_docker_compose.py +15 -0
- stoobly_agent/app/cli/scaffold/service_workflow_validate_command.py +234 -0
- stoobly_agent/app/cli/scaffold/templates/constants.py +3 -3
- stoobly_agent/app/cli/scaffold/validate_command.py +59 -0
- stoobly_agent/app/cli/scaffold/validate_exceptions.py +5 -0
- stoobly_agent/app/cli/scaffold/workflow.py +22 -1
- stoobly_agent/app/cli/scaffold/workflow_run_command.py +2 -1
- stoobly_agent/app/cli/scaffold/workflow_validate_command.py +94 -0
- stoobly_agent/app/cli/scaffold_cli.py +40 -2
- stoobly_agent/config/data_dir.py +14 -6
- stoobly_agent/test/app/cli/scaffold/e2e_test.py +428 -0
- stoobly_agent/test/app/models/schemas/.stoobly/db/VERSION +1 -1
- stoobly_agent/test/mock_data/scaffold/docker-compose-assets-service.yml +18 -0
- stoobly_agent/test/mock_data/scaffold/docker-compose-local-service.yml +16 -0
- stoobly_agent/test/mock_data/scaffold/index.html +12 -0
- {stoobly_agent-1.0.6.dist-info → stoobly_agent-1.0.8.dist-info}/METADATA +2 -1
- {stoobly_agent-1.0.6.dist-info → stoobly_agent-1.0.8.dist-info}/RECORD +29 -19
- {stoobly_agent-1.0.6.dist-info → stoobly_agent-1.0.8.dist-info}/LICENSE +0 -0
- {stoobly_agent-1.0.6.dist-info → stoobly_agent-1.0.8.dist-info}/WHEEL +0 -0
- {stoobly_agent-1.0.6.dist-info → stoobly_agent-1.0.8.dist-info}/entry_points.txt +0 -0
stoobly_agent/config/data_dir.py
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
import pdb
|
1
2
|
import os
|
2
3
|
import shutil
|
3
4
|
|
@@ -16,6 +17,8 @@ class DataDir:
|
|
16
17
|
if DataDir._instances.get(path):
|
17
18
|
raise RuntimeError('Call instance() instead')
|
18
19
|
else:
|
20
|
+
self.__path = path
|
21
|
+
|
19
22
|
if path:
|
20
23
|
self.__data_dir_path = os.path.join(path, DATA_DIR_NAME)
|
21
24
|
else:
|
@@ -35,6 +38,9 @@ class DataDir:
|
|
35
38
|
if not os.path.exists(self.__data_dir_path):
|
36
39
|
self.create(os.path.dirname(self.__data_dir_path))
|
37
40
|
|
41
|
+
def __repr__(self) -> str:
|
42
|
+
return self.path
|
43
|
+
|
38
44
|
@classmethod
|
39
45
|
def instance(cls, path: str = None):
|
40
46
|
if not cls._instances:
|
@@ -58,7 +64,7 @@ class DataDir:
|
|
58
64
|
|
59
65
|
@property
|
60
66
|
def path(self):
|
61
|
-
if os.environ.get(ENV) == 'test':
|
67
|
+
if not self.__path and os.environ.get(ENV) == 'test':
|
62
68
|
test_path = os.path.join(self.__data_dir_path, 'tmp', DATA_DIR_NAME)
|
63
69
|
|
64
70
|
if not os.path.exists(test_path):
|
@@ -122,13 +128,13 @@ class DataDir:
|
|
122
128
|
options = json.loads(contents)
|
123
129
|
_conf_dir = options.get('confdir')
|
124
130
|
|
125
|
-
if _conf_dir
|
131
|
+
if _conf_dir and os.path.exists(_conf_dir):
|
126
132
|
conf_dir = _conf_dir
|
127
133
|
except Exception:
|
128
134
|
pass
|
129
|
-
|
130
|
-
|
131
|
-
|
135
|
+
else:
|
136
|
+
if not os.path.exists(conf_dir):
|
137
|
+
os.makedirs(conf_dir)
|
132
138
|
|
133
139
|
return conf_dir
|
134
140
|
|
@@ -212,8 +218,10 @@ class DataDir:
|
|
212
218
|
if not os.path.exists(self.__data_dir_path):
|
213
219
|
os.mkdir(self.__data_dir_path)
|
214
220
|
|
221
|
+
# Create the certs_dir_path if it doesn't exist
|
222
|
+
self.certs_dir_path
|
215
223
|
# Create tmp folder
|
216
|
-
os.
|
224
|
+
os.makedirs(os.path.join(self.__data_dir_path, 'tmp'), exist_ok=True)
|
217
225
|
|
218
226
|
with open(os.path.join(self.__data_dir_path, '.gitignore'), 'w') as fp:
|
219
227
|
fp.write(
|
@@ -0,0 +1,428 @@
|
|
1
|
+
from pathlib import Path
|
2
|
+
import pathlib
|
3
|
+
import pdb
|
4
|
+
import shutil
|
5
|
+
|
6
|
+
from click.testing import CliRunner
|
7
|
+
import docker
|
8
|
+
import pytest
|
9
|
+
|
10
|
+
from stoobly_agent.app.cli import scaffold
|
11
|
+
from stoobly_agent.app.cli.scaffold.app import App
|
12
|
+
from stoobly_agent.app.cli.scaffold.constants import (
|
13
|
+
WORKFLOW_RECORD_TYPE,
|
14
|
+
WORKFLOW_TEST_TYPE,
|
15
|
+
)
|
16
|
+
from stoobly_agent.app.cli.scaffold.constants import DOCKER_NAMESPACE
|
17
|
+
from stoobly_agent.app.cli.scaffold.managed_services_docker_compose import (
|
18
|
+
ManagedServicesDockerCompose,
|
19
|
+
)
|
20
|
+
from stoobly_agent.app.cli.scaffold.service_docker_compose import ServiceDockerCompose
|
21
|
+
from stoobly_agent.app.cli.scaffold.service_workflow_validate_command import (
|
22
|
+
ServiceWorkflowValidateCommand,
|
23
|
+
)
|
24
|
+
from stoobly_agent.app.cli.scaffold.workflow_validate_command import (
|
25
|
+
WorkflowValidateCommand,
|
26
|
+
)
|
27
|
+
from stoobly_agent.config.data_dir import DATA_DIR_NAME, DataDir
|
28
|
+
from stoobly_agent.test.test_helper import reset
|
29
|
+
|
30
|
+
|
31
|
+
@pytest.mark.e2e
|
32
|
+
class TestScaffoldE2e():
|
33
|
+
|
34
|
+
@pytest.fixture(scope='module', autouse=True)
|
35
|
+
def settings(self):
|
36
|
+
return reset()
|
37
|
+
|
38
|
+
@pytest.fixture(scope='module')
|
39
|
+
def runner(self):
|
40
|
+
yield CliRunner()
|
41
|
+
|
42
|
+
@pytest.fixture(scope='class')
|
43
|
+
def docker_client(self):
|
44
|
+
yield docker.from_env()
|
45
|
+
|
46
|
+
@pytest.fixture(scope='class')
|
47
|
+
def app_name(self):
|
48
|
+
yield "0.0.1"
|
49
|
+
|
50
|
+
@pytest.fixture(scope='class', autouse=True)
|
51
|
+
def temp_dir(self):
|
52
|
+
data_dir_path = DataDir.instance().path
|
53
|
+
tmp_path = data_dir_path[:data_dir_path.rfind('/')]
|
54
|
+
|
55
|
+
yield tmp_path
|
56
|
+
|
57
|
+
@pytest.fixture(scope='class', autouse=True)
|
58
|
+
def app_dir_path(self, temp_dir, app_name):
|
59
|
+
yield temp_dir
|
60
|
+
|
61
|
+
@pytest.fixture(scope='class')
|
62
|
+
def mock_data_directory_path(self):
|
63
|
+
yield Path(__file__).parent.parent.parent.parent / 'mock_data'
|
64
|
+
|
65
|
+
@pytest.fixture(scope='class')
|
66
|
+
def local_service_mock_docker_compose_path(self, mock_data_directory_path):
|
67
|
+
path = mock_data_directory_path / "scaffold" / "docker-compose-local-service.yml"
|
68
|
+
yield path
|
69
|
+
|
70
|
+
@pytest.fixture(scope='class')
|
71
|
+
def hostname(self):
|
72
|
+
yield "http.badssl.com"
|
73
|
+
|
74
|
+
@pytest.fixture(scope='class')
|
75
|
+
def https_service_hostname(self):
|
76
|
+
yield "example.com"
|
77
|
+
|
78
|
+
@pytest.fixture(scope='class')
|
79
|
+
def external_service_name(self):
|
80
|
+
yield "external-service"
|
81
|
+
|
82
|
+
@pytest.fixture(scope='class')
|
83
|
+
def external_https_service_name(self):
|
84
|
+
yield "external-https-service"
|
85
|
+
|
86
|
+
@pytest.fixture(scope='class')
|
87
|
+
def local_hostname(self):
|
88
|
+
yield "my-httpbin.com"
|
89
|
+
|
90
|
+
@pytest.fixture(scope='class')
|
91
|
+
def local_service_name(self):
|
92
|
+
yield "my-httpbin"
|
93
|
+
|
94
|
+
|
95
|
+
class TestRecordWorkflow():
|
96
|
+
@pytest.fixture(scope='class', autouse=True)
|
97
|
+
def target_workflow_name(self):
|
98
|
+
yield WORKFLOW_RECORD_TYPE
|
99
|
+
|
100
|
+
@pytest.fixture(scope='class')
|
101
|
+
def managed_services_docker_compose(self, target_workflow_name):
|
102
|
+
yield ManagedServicesDockerCompose(target_workflow_name=target_workflow_name)
|
103
|
+
|
104
|
+
@pytest.fixture(scope='class')
|
105
|
+
def external_service_docker_compose(self, app_dir_path, target_workflow_name, external_service_name, hostname):
|
106
|
+
yield ServiceDockerCompose(app_dir_path=app_dir_path, target_workflow_name=target_workflow_name, service_name=external_service_name, hostname=hostname)
|
107
|
+
|
108
|
+
@pytest.fixture(scope='class')
|
109
|
+
def external_https_service_docker_compose(self, app_dir_path, target_workflow_name, external_https_service_name, https_service_hostname):
|
110
|
+
yield ServiceDockerCompose(app_dir_path=app_dir_path, target_workflow_name=target_workflow_name, service_name=external_https_service_name, hostname=https_service_hostname)
|
111
|
+
|
112
|
+
@pytest.fixture(scope='class')
|
113
|
+
def local_service_docker_compose(self, app_dir_path, target_workflow_name, local_service_name, local_hostname):
|
114
|
+
yield ServiceDockerCompose(app_dir_path=app_dir_path, target_workflow_name=target_workflow_name, service_name=local_service_name, hostname=local_hostname)
|
115
|
+
|
116
|
+
@pytest.fixture(scope='class', autouse=True)
|
117
|
+
def setup_docker_composes(self, managed_services_docker_compose, external_service_docker_compose, local_service_docker_compose):
|
118
|
+
self.managed_services_docker_compose = managed_services_docker_compose
|
119
|
+
self.external_service_docker_compose = external_service_docker_compose
|
120
|
+
self.local_service_docker_compose = local_service_docker_compose
|
121
|
+
|
122
|
+
@pytest.fixture(scope="class", autouse=True)
|
123
|
+
def create_scaffold_setup(self, runner, app_dir_path, app_name, target_workflow_name, external_service_docker_compose, external_https_service_docker_compose, local_service_docker_compose, local_service_mock_docker_compose_path):
|
124
|
+
TestScaffoldE2e.cli_app_create(runner, app_dir_path, app_name)
|
125
|
+
|
126
|
+
# Create external user defined service
|
127
|
+
TestScaffoldE2e.cli_service_create(runner, app_dir_path, external_service_docker_compose.hostname, external_service_docker_compose.service_name, False)
|
128
|
+
TestScaffoldE2e.cli_service_create(runner, app_dir_path, external_https_service_docker_compose.hostname, external_https_service_docker_compose.service_name, True)
|
129
|
+
|
130
|
+
# Create local user defined service
|
131
|
+
TestScaffoldE2e.cli_service_create(runner, app_dir_path, local_service_docker_compose.hostname, local_service_docker_compose.service_name, False)
|
132
|
+
|
133
|
+
# Validate docker-compose path exists
|
134
|
+
destination_path = Path(local_service_docker_compose.docker_compose_path)
|
135
|
+
assert destination_path.is_file()
|
136
|
+
# Add user defined Docker Compose file for the local service
|
137
|
+
shutil.copyfile(local_service_mock_docker_compose_path, destination_path)
|
138
|
+
|
139
|
+
# Record workflow doesn't have a fixtures folder
|
140
|
+
|
141
|
+
# Generate certs
|
142
|
+
TestScaffoldE2e.cli_app_mkcert(runner, app_dir_path)
|
143
|
+
|
144
|
+
TestScaffoldE2e.cli_workflow_run(runner, app_dir_path, target_workflow_name)
|
145
|
+
|
146
|
+
@pytest.fixture(scope="class", autouse=True)
|
147
|
+
def cleanup_after_all(self, runner, app_dir_path, target_workflow_name):
|
148
|
+
yield
|
149
|
+
TestScaffoldE2e.cli_workflow_stop(runner, app_dir_path, target_workflow_name)
|
150
|
+
|
151
|
+
def test_core_components(self, app_dir_path, target_workflow_name):
|
152
|
+
app = App(app_dir_path, DOCKER_NAMESPACE)
|
153
|
+
config = {
|
154
|
+
'workflow_name': target_workflow_name,
|
155
|
+
'service_name': 'build'
|
156
|
+
}
|
157
|
+
|
158
|
+
command = WorkflowValidateCommand(app, **config)
|
159
|
+
command.validate()
|
160
|
+
|
161
|
+
def test_external_service(self, external_service_docker_compose: ServiceDockerCompose, app_dir_path, target_workflow_name):
|
162
|
+
app = App(app_dir_path, DOCKER_NAMESPACE)
|
163
|
+
config = {
|
164
|
+
'workflow_name': target_workflow_name,
|
165
|
+
'service_name': external_service_docker_compose.service_name
|
166
|
+
}
|
167
|
+
|
168
|
+
command = ServiceWorkflowValidateCommand(app, **config)
|
169
|
+
command.validate()
|
170
|
+
|
171
|
+
def test_local_service(self, app_dir_path, target_workflow_name, local_service_docker_compose: ServiceDockerCompose):
|
172
|
+
app = App(app_dir_path, DOCKER_NAMESPACE)
|
173
|
+
config = {
|
174
|
+
'workflow_name': target_workflow_name,
|
175
|
+
'service_name': local_service_docker_compose.service_name
|
176
|
+
}
|
177
|
+
|
178
|
+
command = ServiceWorkflowValidateCommand(app, **config)
|
179
|
+
command.validate()
|
180
|
+
|
181
|
+
|
182
|
+
class TestTestWorkflow():
|
183
|
+
@pytest.fixture(scope='class')
|
184
|
+
def assets_service_mock_docker_compose_path(self, mock_data_directory_path):
|
185
|
+
path = mock_data_directory_path / "scaffold" / "docker-compose-assets-service.yml"
|
186
|
+
yield path
|
187
|
+
|
188
|
+
@pytest.fixture(scope='class')
|
189
|
+
def assets_service_assets_path(self, mock_data_directory_path):
|
190
|
+
path = mock_data_directory_path / "scaffold" / "index.html"
|
191
|
+
yield path
|
192
|
+
|
193
|
+
@pytest.fixture(scope='class', autouse=True)
|
194
|
+
def target_workflow_name(self):
|
195
|
+
yield WORKFLOW_TEST_TYPE
|
196
|
+
|
197
|
+
@pytest.fixture(scope='class')
|
198
|
+
def assets_service_name(self):
|
199
|
+
yield "assets"
|
200
|
+
|
201
|
+
@pytest.fixture(scope='class')
|
202
|
+
def assets_hostname(self):
|
203
|
+
yield "assets"
|
204
|
+
|
205
|
+
@pytest.fixture(scope='class')
|
206
|
+
def managed_services_docker_compose(self, target_workflow_name):
|
207
|
+
yield ManagedServicesDockerCompose(target_workflow_name=target_workflow_name)
|
208
|
+
|
209
|
+
@pytest.fixture(scope='class')
|
210
|
+
def external_service_docker_compose(self, app_dir_path, target_workflow_name, external_service_name, hostname):
|
211
|
+
yield ServiceDockerCompose(app_dir_path=app_dir_path, target_workflow_name=target_workflow_name, service_name=external_service_name, hostname=hostname)
|
212
|
+
|
213
|
+
@pytest.fixture(scope='class')
|
214
|
+
def local_service_docker_compose(self, app_dir_path, target_workflow_name, local_service_name, local_hostname):
|
215
|
+
yield ServiceDockerCompose(app_dir_path=app_dir_path, target_workflow_name=target_workflow_name, service_name=local_service_name, hostname=local_hostname)
|
216
|
+
|
217
|
+
@pytest.fixture(scope='class')
|
218
|
+
def assets_service_docker_compose(self, app_dir_path, target_workflow_name, assets_service_name, assets_hostname):
|
219
|
+
yield ServiceDockerCompose(app_dir_path=app_dir_path, target_workflow_name=target_workflow_name, service_name=assets_service_name, hostname=assets_hostname)
|
220
|
+
|
221
|
+
@pytest.fixture(scope='class', autouse=True)
|
222
|
+
def setup_docker_composes(self, managed_services_docker_compose, external_service_docker_compose, local_service_docker_compose, assets_service_docker_compose):
|
223
|
+
self.managed_services_docker_compose = managed_services_docker_compose
|
224
|
+
self.external_service_docker_compose = external_service_docker_compose
|
225
|
+
self.local_service_docker_compose = local_service_docker_compose
|
226
|
+
self.assets_service_docker_compose = assets_service_docker_compose
|
227
|
+
|
228
|
+
@pytest.fixture(scope="class", autouse=True)
|
229
|
+
def create_scaffold_setup(self, runner, app_name, app_dir_path, target_workflow_name, external_service_docker_compose, local_service_docker_compose, assets_service_docker_compose, mock_data_directory_path, assets_service_mock_docker_compose_path):
|
230
|
+
|
231
|
+
TestScaffoldE2e.cli_app_create(runner, app_dir_path, app_name)
|
232
|
+
|
233
|
+
# Create external user defined service
|
234
|
+
TestScaffoldE2e.cli_service_create(runner, app_dir_path, external_service_docker_compose.hostname, external_service_docker_compose.service_name, False)
|
235
|
+
# Create local user defined services
|
236
|
+
TestScaffoldE2e.cli_service_create(runner, app_dir_path, local_service_docker_compose.hostname, local_service_docker_compose.service_name, False)
|
237
|
+
TestScaffoldE2e.cli_service_create_assets(runner, app_dir_path, assets_service_docker_compose.hostname, assets_service_docker_compose.service_name, False)
|
238
|
+
|
239
|
+
# Don't run the local user defined service in the 'test' workflow
|
240
|
+
# So don't copy the Docker Compose file over
|
241
|
+
|
242
|
+
# Add user defined Docker Compose file for the assets service
|
243
|
+
destination_path = Path(assets_service_docker_compose.docker_compose_path)
|
244
|
+
assert destination_path.is_file()
|
245
|
+
shutil.copyfile(assets_service_mock_docker_compose_path, destination_path)
|
246
|
+
|
247
|
+
TestScaffoldE2e.cli_service_create_assets(runner, app_dir_path, assets_service_docker_compose.hostname, assets_service_docker_compose.service_name, False)
|
248
|
+
|
249
|
+
# Add assets for assets service
|
250
|
+
data_dir_path = DataDir.instance().path
|
251
|
+
destination_assets_path = f"{data_dir_path}/docker/{assets_service_docker_compose.service_name}/{target_workflow_name}/index.html"
|
252
|
+
destination_path = Path(destination_assets_path)
|
253
|
+
assets_mock_path = mock_data_directory_path / "scaffold" / "index.html"
|
254
|
+
shutil.copyfile(assets_mock_path, destination_path)
|
255
|
+
|
256
|
+
# Created shared file in fixtures folder
|
257
|
+
app = App(app_dir_path, DOCKER_NAMESPACE)
|
258
|
+
config = {
|
259
|
+
'workflow_name': target_workflow_name,
|
260
|
+
'service_name': external_service_docker_compose.service_name
|
261
|
+
}
|
262
|
+
command = ServiceWorkflowValidateCommand(app, **config)
|
263
|
+
with open(f"{command.fixtures_dir_path}/shared_file.txt", 'w') as file:
|
264
|
+
file.write('this is a shared file')
|
265
|
+
|
266
|
+
TestScaffoldE2e.cli_workflow_run(runner, app_dir_path, target_workflow_name=target_workflow_name)
|
267
|
+
|
268
|
+
@pytest.fixture(scope="class", autouse=True)
|
269
|
+
def cleanup_after_all(self, runner, app_dir_path, target_workflow_name):
|
270
|
+
yield
|
271
|
+
TestScaffoldE2e.cli_workflow_stop(runner, app_dir_path, target_workflow_name)
|
272
|
+
|
273
|
+
def test_no_core_components(self, app_dir_path, target_workflow_name):
|
274
|
+
app = App(app_dir_path, DOCKER_NAMESPACE)
|
275
|
+
config = {
|
276
|
+
'workflow_name': target_workflow_name,
|
277
|
+
'service_name': 'build'
|
278
|
+
}
|
279
|
+
|
280
|
+
command = WorkflowValidateCommand(app, **config)
|
281
|
+
command.validate()
|
282
|
+
|
283
|
+
def test_user_services(self, app_dir_path, target_workflow_name, external_service_docker_compose, local_service_docker_compose):
|
284
|
+
app = App(app_dir_path, DOCKER_NAMESPACE)
|
285
|
+
|
286
|
+
config = {
|
287
|
+
'workflow_name': target_workflow_name,
|
288
|
+
'service_name': external_service_docker_compose.service_name
|
289
|
+
}
|
290
|
+
command = ServiceWorkflowValidateCommand(app, **config)
|
291
|
+
command.validate()
|
292
|
+
|
293
|
+
config = {
|
294
|
+
'workflow_name': target_workflow_name,
|
295
|
+
'service_name': local_service_docker_compose.service_name
|
296
|
+
}
|
297
|
+
command = ServiceWorkflowValidateCommand(app, **config)
|
298
|
+
command.validate()
|
299
|
+
|
300
|
+
def test_tests(self):
|
301
|
+
# This is covered by test_assets
|
302
|
+
pass
|
303
|
+
|
304
|
+
def test_assets(self, app_dir_path, target_workflow_name):
|
305
|
+
|
306
|
+
app = App(app_dir_path, DOCKER_NAMESPACE)
|
307
|
+
config = {
|
308
|
+
'workflow_name': target_workflow_name,
|
309
|
+
'service_name': 'assets'
|
310
|
+
}
|
311
|
+
|
312
|
+
command = ServiceWorkflowValidateCommand(app, **config)
|
313
|
+
command.validate()
|
314
|
+
|
315
|
+
@staticmethod
|
316
|
+
def cli_app_create(runner: CliRunner, app_dir_path: str, app_name: str):
|
317
|
+
pathlib.Path(f"{app_dir_path}/{DATA_DIR_NAME}").mkdir(parents=True, exist_ok=True)
|
318
|
+
|
319
|
+
result = runner.invoke(scaffold, ['app', 'create',
|
320
|
+
'--app-dir-path', app_dir_path,
|
321
|
+
'--force',
|
322
|
+
app_name
|
323
|
+
])
|
324
|
+
|
325
|
+
assert result.exit_code == 0
|
326
|
+
output = result.stdout
|
327
|
+
assert not output
|
328
|
+
|
329
|
+
@staticmethod
|
330
|
+
def cli_app_mkcert(runner: CliRunner, app_dir_path: str):
|
331
|
+
result = runner.invoke(scaffold, ['app', 'mkcert',
|
332
|
+
'--app-dir-path', app_dir_path,
|
333
|
+
'--context-dir-path', app_dir_path,
|
334
|
+
])
|
335
|
+
|
336
|
+
assert result.exit_code == 0
|
337
|
+
output = result.stdout
|
338
|
+
assert not output
|
339
|
+
|
340
|
+
|
341
|
+
@staticmethod
|
342
|
+
def cli_service_create(runner: CliRunner, app_dir_path: str, hostname: str, service_name: str, https: bool):
|
343
|
+
scheme = 'http'
|
344
|
+
port = '80'
|
345
|
+
if https == True:
|
346
|
+
scheme = 'https'
|
347
|
+
port = '443'
|
348
|
+
|
349
|
+
result = runner.invoke(scaffold, ['service', 'create',
|
350
|
+
'--app-dir-path', app_dir_path,
|
351
|
+
'--env', 'TEST',
|
352
|
+
'--force',
|
353
|
+
'--hostname', hostname,
|
354
|
+
'--scheme', scheme,
|
355
|
+
'--port', port,
|
356
|
+
'--workflow', 'mock',
|
357
|
+
'--workflow', 'record',
|
358
|
+
'--workflow', 'test',
|
359
|
+
service_name
|
360
|
+
])
|
361
|
+
assert result.exit_code == 0
|
362
|
+
output = result.stdout
|
363
|
+
assert not output
|
364
|
+
|
365
|
+
# Specific flags for assets
|
366
|
+
@staticmethod
|
367
|
+
def cli_service_create_assets(runner: CliRunner, app_dir_path: str, hostname: str, service_name: str, https: bool):
|
368
|
+
scheme = 'http'
|
369
|
+
port = '80'
|
370
|
+
if https == True:
|
371
|
+
scheme = 'https'
|
372
|
+
port = '443'
|
373
|
+
proxy_mode_reverse_spec = f"reverse:{scheme}://{hostname}:8080"
|
374
|
+
|
375
|
+
result = runner.invoke(scaffold, ['service', 'create',
|
376
|
+
'--app-dir-path', app_dir_path,
|
377
|
+
'--force',
|
378
|
+
'--hostname', hostname,
|
379
|
+
'--scheme', scheme,
|
380
|
+
'--port', port,
|
381
|
+
'--proxy-mode', proxy_mode_reverse_spec,
|
382
|
+
'--detached',
|
383
|
+
'--workflow', 'test',
|
384
|
+
service_name
|
385
|
+
])
|
386
|
+
assert result.exit_code == 0
|
387
|
+
output = result.stdout
|
388
|
+
assert not output
|
389
|
+
|
390
|
+
@staticmethod
|
391
|
+
def cli_workflow_create(runner: CliRunner, app_dir_path: str, service_name: str):
|
392
|
+
result = runner.invoke(scaffold, ['workflow', 'create',
|
393
|
+
'--app-dir-path', app_dir_path,
|
394
|
+
'--service', service_name,
|
395
|
+
'--template', 'mock',
|
396
|
+
'ci',
|
397
|
+
])
|
398
|
+
|
399
|
+
assert result.exit_code == 0
|
400
|
+
output = result.stdout
|
401
|
+
assert not output
|
402
|
+
|
403
|
+
@staticmethod
|
404
|
+
def cli_workflow_run(runner: CliRunner, app_dir_path: str, target_workflow_name: str):
|
405
|
+
command = ['workflow', 'run',
|
406
|
+
'--app-dir-path', app_dir_path,
|
407
|
+
'--context-dir-path', app_dir_path,
|
408
|
+
target_workflow_name,
|
409
|
+
]
|
410
|
+
result = runner.invoke(scaffold, command)
|
411
|
+
|
412
|
+
assert result.exit_code == 0
|
413
|
+
output = result.stdout
|
414
|
+
assert output
|
415
|
+
|
416
|
+
@staticmethod
|
417
|
+
def cli_workflow_stop(runner: CliRunner, app_dir_path: str, target_workflow_name: str):
|
418
|
+
command = ['workflow', 'stop',
|
419
|
+
'--app-dir-path', app_dir_path,
|
420
|
+
'--context-dir-path', app_dir_path,
|
421
|
+
target_workflow_name,
|
422
|
+
]
|
423
|
+
result = runner.invoke(scaffold, command)
|
424
|
+
|
425
|
+
assert result.exit_code == 0
|
426
|
+
output = result.stdout
|
427
|
+
assert output
|
428
|
+
|
@@ -1 +1 @@
|
|
1
|
-
1.0.
|
1
|
+
1.0.7
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# Define services here
|
2
|
+
|
3
|
+
networks:
|
4
|
+
app:
|
5
|
+
external: true
|
6
|
+
name: ${APP_NETWORK}
|
7
|
+
|
8
|
+
services:
|
9
|
+
assets:
|
10
|
+
image: nginx:1.27
|
11
|
+
hostname: assets
|
12
|
+
networks:
|
13
|
+
- app
|
14
|
+
volumes:
|
15
|
+
- ./index.html:/usr/share/nginx/html/index.html
|
16
|
+
profiles: &id001
|
17
|
+
- test
|
18
|
+
|
@@ -0,0 +1,12 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html lang="en">
|
3
|
+
<head>
|
4
|
+
<meta charset="UTF-8">
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
6
|
+
<title>Welcome to NGINX</title>
|
7
|
+
</head>
|
8
|
+
<body>
|
9
|
+
<h1>Hello, NGINX is serving this page!</h1>
|
10
|
+
</body>
|
11
|
+
</html>
|
12
|
+
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.3
|
2
2
|
Name: stoobly-agent
|
3
|
-
Version: 1.0.
|
3
|
+
Version: 1.0.8
|
4
4
|
Summary: Record, mock, and test HTTP(s) requests. CLI agent for Stoobly
|
5
5
|
License: Apache-2.0
|
6
6
|
Author: Matt Le
|
@@ -16,6 +16,7 @@ Requires-Dist: click (>=8.1.0,<9.0.0)
|
|
16
16
|
Requires-Dist: diff-match-patch (>=20230430,<20230431)
|
17
17
|
Requires-Dist: distro (>=1.6.0,<1.7.0)
|
18
18
|
Requires-Dist: dnspython (>=2.6.1,<2.7.0)
|
19
|
+
Requires-Dist: docker (>=7.1.0,<8.0)
|
19
20
|
Requires-Dist: httptools (>=0.4.0)
|
20
21
|
Requires-Dist: jmespath (>=1.0.0)
|
21
22
|
Requires-Dist: mergedeep (>=1.3.0,<1.3.4)
|