devservices 1.0.15__tar.gz → 1.0.17__tar.gz
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.
- {devservices-1.0.15 → devservices-1.0.17}/PKG-INFO +1 -1
- {devservices-1.0.15 → devservices-1.0.17}/README.md +1 -1
- {devservices-1.0.15 → devservices-1.0.17}/devservices/commands/down.py +3 -3
- {devservices-1.0.15 → devservices-1.0.17}/devservices/commands/list_dependencies.py +1 -1
- {devservices-1.0.15 → devservices-1.0.17}/devservices/commands/logs.py +2 -2
- {devservices-1.0.15 → devservices-1.0.17}/devservices/commands/up.py +2 -2
- {devservices-1.0.15 → devservices-1.0.17}/devservices/constants.py +2 -1
- {devservices-1.0.15 → devservices-1.0.17}/devservices/main.py +33 -4
- {devservices-1.0.15 → devservices-1.0.17}/devservices/utils/docker_compose.py +27 -18
- {devservices-1.0.15 → devservices-1.0.17}/devservices.egg-info/PKG-INFO +1 -1
- {devservices-1.0.15 → devservices-1.0.17}/pyproject.toml +1 -1
- {devservices-1.0.15 → devservices-1.0.17}/tests/utils/test_docker_compose.py +88 -34
- {devservices-1.0.15 → devservices-1.0.17}/LICENSE.md +0 -0
- {devservices-1.0.15 → devservices-1.0.17}/devservices/__init__.py +0 -0
- {devservices-1.0.15 → devservices-1.0.17}/devservices/commands/__init__.py +0 -0
- {devservices-1.0.15 → devservices-1.0.17}/devservices/commands/list_services.py +0 -0
- {devservices-1.0.15 → devservices-1.0.17}/devservices/commands/purge.py +0 -0
- {devservices-1.0.15 → devservices-1.0.17}/devservices/commands/status.py +0 -0
- {devservices-1.0.15 → devservices-1.0.17}/devservices/commands/update.py +0 -0
- {devservices-1.0.15 → devservices-1.0.17}/devservices/configs/service_config.py +0 -0
- {devservices-1.0.15 → devservices-1.0.17}/devservices/exceptions.py +0 -0
- {devservices-1.0.15 → devservices-1.0.17}/devservices/utils/__init__.py +0 -0
- {devservices-1.0.15 → devservices-1.0.17}/devservices/utils/check_for_update.py +0 -0
- {devservices-1.0.15 → devservices-1.0.17}/devservices/utils/console.py +0 -0
- {devservices-1.0.15 → devservices-1.0.17}/devservices/utils/dependencies.py +0 -0
- {devservices-1.0.15 → devservices-1.0.17}/devservices/utils/devenv.py +0 -0
- {devservices-1.0.15 → devservices-1.0.17}/devservices/utils/docker.py +0 -0
- {devservices-1.0.15 → devservices-1.0.17}/devservices/utils/file_lock.py +0 -0
- {devservices-1.0.15 → devservices-1.0.17}/devservices/utils/git.py +0 -0
- {devservices-1.0.15 → devservices-1.0.17}/devservices/utils/install_binary.py +0 -0
- {devservices-1.0.15 → devservices-1.0.17}/devservices/utils/services.py +0 -0
- {devservices-1.0.15 → devservices-1.0.17}/devservices/utils/state.py +0 -0
- {devservices-1.0.15 → devservices-1.0.17}/devservices.egg-info/SOURCES.txt +0 -0
- {devservices-1.0.15 → devservices-1.0.17}/devservices.egg-info/dependency_links.txt +0 -0
- {devservices-1.0.15 → devservices-1.0.17}/devservices.egg-info/entry_points.txt +0 -0
- {devservices-1.0.15 → devservices-1.0.17}/devservices.egg-info/requires.txt +0 -0
- {devservices-1.0.15 → devservices-1.0.17}/devservices.egg-info/top_level.txt +0 -0
- {devservices-1.0.15 → devservices-1.0.17}/setup.cfg +0 -0
- {devservices-1.0.15 → devservices-1.0.17}/testing/__init__.py +0 -0
- {devservices-1.0.15 → devservices-1.0.17}/testing/utils.py +0 -0
- {devservices-1.0.15 → devservices-1.0.17}/tests/__init__.py +0 -0
- {devservices-1.0.15 → devservices-1.0.17}/tests/commands/test_down.py +0 -0
- {devservices-1.0.15 → devservices-1.0.17}/tests/commands/test_list_dependencies.py +0 -0
- {devservices-1.0.15 → devservices-1.0.17}/tests/commands/test_list_services.py +0 -0
- {devservices-1.0.15 → devservices-1.0.17}/tests/commands/test_logs.py +0 -0
- {devservices-1.0.15 → devservices-1.0.17}/tests/commands/test_purge.py +0 -0
- {devservices-1.0.15 → devservices-1.0.17}/tests/commands/test_status.py +0 -0
- {devservices-1.0.15 → devservices-1.0.17}/tests/commands/test_up.py +0 -0
- {devservices-1.0.15 → devservices-1.0.17}/tests/commands/test_update.py +0 -0
- {devservices-1.0.15 → devservices-1.0.17}/tests/configs/test_service_config.py +0 -0
- {devservices-1.0.15 → devservices-1.0.17}/tests/conftest.py +0 -0
- {devservices-1.0.15 → devservices-1.0.17}/tests/utils/test_check_for_update.py +0 -0
- {devservices-1.0.15 → devservices-1.0.17}/tests/utils/test_dependencies.py +0 -0
- {devservices-1.0.15 → devservices-1.0.17}/tests/utils/test_docker.py +0 -0
- {devservices-1.0.15 → devservices-1.0.17}/tests/utils/test_git.py +0 -0
- {devservices-1.0.15 → devservices-1.0.17}/tests/utils/test_install_binary.py +0 -0
- {devservices-1.0.15 → devservices-1.0.17}/tests/utils/test_services.py +0 -0
- {devservices-1.0.15 → devservices-1.0.17}/tests/utils/test_state.py +0 -0
|
@@ -60,7 +60,7 @@ def down(args: Namespace) -> None:
|
|
|
60
60
|
try:
|
|
61
61
|
service = find_matching_service(service_name)
|
|
62
62
|
except ConfigNotFoundError as e:
|
|
63
|
-
capture_exception(e)
|
|
63
|
+
capture_exception(e, level="info")
|
|
64
64
|
console.failure(
|
|
65
65
|
f"{str(e)}. Please specify a service (i.e. `devservices down sentry`) or run the command from a directory with a devservices configuration."
|
|
66
66
|
)
|
|
@@ -81,7 +81,7 @@ def down(args: Namespace) -> None:
|
|
|
81
81
|
active_services = starting_services.union(started_services)
|
|
82
82
|
if service.name not in active_services:
|
|
83
83
|
console.warning(f"{service.name} is not running")
|
|
84
|
-
exit(0)
|
|
84
|
+
return # Since exit(0) is captured as an internal_error by sentry
|
|
85
85
|
|
|
86
86
|
active_starting_modes = state.get_active_modes_for_service(
|
|
87
87
|
service.name, StateTables.STARTING_SERVICES
|
|
@@ -148,7 +148,7 @@ def down(args: Namespace) -> None:
|
|
|
148
148
|
try:
|
|
149
149
|
_down(service, remote_dependencies, list(mode_dependencies), status)
|
|
150
150
|
except DockerComposeError as dce:
|
|
151
|
-
capture_exception(dce)
|
|
151
|
+
capture_exception(dce, level="info")
|
|
152
152
|
status.failure(f"Failed to stop {service.name}: {dce.stderr}")
|
|
153
153
|
exit(1)
|
|
154
154
|
else:
|
|
@@ -34,7 +34,7 @@ def list_dependencies(args: Namespace) -> None:
|
|
|
34
34
|
try:
|
|
35
35
|
service = find_matching_service(service_name)
|
|
36
36
|
except ConfigNotFoundError as e:
|
|
37
|
-
capture_exception(e)
|
|
37
|
+
capture_exception(e, level="info")
|
|
38
38
|
console.failure(
|
|
39
39
|
f"{str(e)}. Please specify a service (i.e. `devservices list-dependencies sentry`) or run the command from a directory with a devservices configuration."
|
|
40
40
|
)
|
|
@@ -49,7 +49,7 @@ def logs(args: Namespace) -> None:
|
|
|
49
49
|
try:
|
|
50
50
|
service = find_matching_service(service_name)
|
|
51
51
|
except ConfigNotFoundError as e:
|
|
52
|
-
capture_exception(e)
|
|
52
|
+
capture_exception(e, level="info")
|
|
53
53
|
console.failure(
|
|
54
54
|
f"{str(e)}. Please specify a service (i.e. `devservices logs sentry`) or run the command from a directory with a devservices configuration."
|
|
55
55
|
)
|
|
@@ -86,7 +86,7 @@ def logs(args: Namespace) -> None:
|
|
|
86
86
|
try:
|
|
87
87
|
logs_output = _logs(service, remote_dependencies, mode_dependencies)
|
|
88
88
|
except DockerComposeError as dce:
|
|
89
|
-
capture_exception(dce)
|
|
89
|
+
capture_exception(dce, level="info")
|
|
90
90
|
console.failure(f"Failed to get logs for {service.name}: {dce.stderr}")
|
|
91
91
|
exit(1)
|
|
92
92
|
for log in logs_output:
|
|
@@ -63,7 +63,7 @@ def up(args: Namespace) -> None:
|
|
|
63
63
|
try:
|
|
64
64
|
service = find_matching_service(service_name)
|
|
65
65
|
except ConfigNotFoundError as e:
|
|
66
|
-
capture_exception(e)
|
|
66
|
+
capture_exception(e, level="info")
|
|
67
67
|
console.failure(
|
|
68
68
|
f"{str(e)}. Please specify a service (i.e. `devservices up sentry`) or run the command from a directory with a devservices configuration."
|
|
69
69
|
)
|
|
@@ -110,7 +110,7 @@ def up(args: Namespace) -> None:
|
|
|
110
110
|
mode_dependencies = modes[mode]
|
|
111
111
|
_up(service, [mode], remote_dependencies, mode_dependencies, status)
|
|
112
112
|
except DockerComposeError as dce:
|
|
113
|
-
capture_exception(dce)
|
|
113
|
+
capture_exception(dce, level="info")
|
|
114
114
|
status.failure(f"Failed to start {service.name}: {dce.stderr}")
|
|
115
115
|
exit(1)
|
|
116
116
|
# TODO: We should factor in healthchecks here before marking service as running
|
|
@@ -6,7 +6,8 @@ from datetime import timedelta
|
|
|
6
6
|
MINIMUM_DOCKER_COMPOSE_VERSION = "2.29.7"
|
|
7
7
|
DEVSERVICES_DIR_NAME = "devservices"
|
|
8
8
|
CONFIG_FILE_NAME = "config.yml"
|
|
9
|
-
|
|
9
|
+
DOCKER_CONFIG_DIR = os.environ.get("DOCKER_CONFIG", os.path.expanduser("~/.docker"))
|
|
10
|
+
DOCKER_USER_PLUGIN_DIR = os.path.join(DOCKER_CONFIG_DIR, "cli-plugins/")
|
|
10
11
|
|
|
11
12
|
DEVSERVICES_CACHE_DIR = os.path.expanduser("~/.cache/sentry-devservices")
|
|
12
13
|
DEVSERVICES_LOCAL_DIR = os.path.expanduser("~/.local/share/sentry-devservices")
|
|
@@ -15,6 +15,8 @@ from sentry_sdk import set_tag
|
|
|
15
15
|
from sentry_sdk import set_user
|
|
16
16
|
from sentry_sdk import start_transaction
|
|
17
17
|
from sentry_sdk.integrations.argv import ArgvIntegration
|
|
18
|
+
from sentry_sdk.types import Event
|
|
19
|
+
from sentry_sdk.types import Hint
|
|
18
20
|
|
|
19
21
|
from devservices.commands import down
|
|
20
22
|
from devservices.commands import list_dependencies
|
|
@@ -42,6 +44,31 @@ disable_sentry = os.environ.get("DEVSERVICES_DISABLE_SENTRY", default="0") == "1
|
|
|
42
44
|
logging.basicConfig(level=logging.INFO)
|
|
43
45
|
current_version = metadata.version("devservices")
|
|
44
46
|
|
|
47
|
+
error_trace_ids = set()
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
def before_send_error(event: Event, hint: Hint) -> Event:
|
|
51
|
+
"""Gets the trace_id from the errors we care about.
|
|
52
|
+
|
|
53
|
+
This function is used as a before_send callback for Sentry to track error trace IDs.
|
|
54
|
+
It adds the trace_id to error_trace_ids set for non-info level events.
|
|
55
|
+
"""
|
|
56
|
+
if event["level"] != "info":
|
|
57
|
+
error_trace_ids.add(event["contexts"]["trace"]["trace_id"])
|
|
58
|
+
return event
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
def before_send_transaction(event: Event, hint: Hint) -> Event:
|
|
62
|
+
"""Manually sets the status of a transaction.
|
|
63
|
+
|
|
64
|
+
This function is used as a before_send_transaction callback for Sentry to mark transaction status
|
|
65
|
+
as unknown if they don't correspond to errors we care about.
|
|
66
|
+
"""
|
|
67
|
+
if event["contexts"]["trace"]["trace_id"] not in error_trace_ids:
|
|
68
|
+
event["contexts"]["trace"]["status"] = "unknown"
|
|
69
|
+
return event
|
|
70
|
+
|
|
71
|
+
|
|
45
72
|
if not disable_sentry:
|
|
46
73
|
init(
|
|
47
74
|
dsn="https://56470da7302c16e83141f62f88e46449@o1.ingest.us.sentry.io/4507946704961536",
|
|
@@ -50,16 +77,18 @@ if not disable_sentry:
|
|
|
50
77
|
enable_tracing=True,
|
|
51
78
|
integrations=[ArgvIntegration()],
|
|
52
79
|
environment=sentry_environment,
|
|
80
|
+
before_send=before_send_error,
|
|
81
|
+
before_send_transaction=before_send_transaction,
|
|
53
82
|
release=current_version,
|
|
54
83
|
)
|
|
55
84
|
username = getpass.getuser()
|
|
56
85
|
set_user({"username": username})
|
|
57
|
-
set_tag("
|
|
86
|
+
set_tag("user_platform", platform.platform())
|
|
58
87
|
try:
|
|
59
88
|
git_version = get_git_version()
|
|
60
89
|
set_tag("git_version", git_version)
|
|
61
90
|
except GitError as e:
|
|
62
|
-
capture_exception(e)
|
|
91
|
+
capture_exception(e, level="info")
|
|
63
92
|
logging.debug("Failed to get git version: %s", e)
|
|
64
93
|
set_tag("git_version", "unknown")
|
|
65
94
|
|
|
@@ -75,11 +104,11 @@ def main() -> None:
|
|
|
75
104
|
try:
|
|
76
105
|
check_docker_compose_version()
|
|
77
106
|
except DockerDaemonNotRunningError as e:
|
|
78
|
-
capture_exception(e)
|
|
107
|
+
capture_exception(e, level="info")
|
|
79
108
|
console.failure(str(e))
|
|
80
109
|
exit(1)
|
|
81
110
|
except DockerComposeInstallationError as e:
|
|
82
|
-
capture_exception(e)
|
|
111
|
+
capture_exception(e, level="info")
|
|
83
112
|
console.failure("Failed to ensure docker compose is installed and up-to-date")
|
|
84
113
|
exit(1)
|
|
85
114
|
parser = argparse.ArgumentParser(
|
|
@@ -83,15 +83,10 @@ def install_docker_compose() -> None:
|
|
|
83
83
|
|
|
84
84
|
# Verify the installation
|
|
85
85
|
try:
|
|
86
|
-
version =
|
|
87
|
-
|
|
88
|
-
capture_output=True,
|
|
89
|
-
check=True,
|
|
90
|
-
text=True,
|
|
91
|
-
).stdout
|
|
92
|
-
except Exception as e:
|
|
86
|
+
version = get_docker_compose_version()
|
|
87
|
+
except DockerComposeError as e:
|
|
93
88
|
raise DockerComposeInstallationError(
|
|
94
|
-
f"Failed to verify Docker Compose installation: {e}"
|
|
89
|
+
f"Failed to verify Docker Compose installation: {e.stderr}"
|
|
95
90
|
)
|
|
96
91
|
|
|
97
92
|
console.success(f"Verified Docker Compose installation: v{version}")
|
|
@@ -129,20 +124,17 @@ def check_docker_compose_version() -> None:
|
|
|
129
124
|
check_docker_daemon_running()
|
|
130
125
|
try:
|
|
131
126
|
# Run the docker compose version command
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
text=True,
|
|
136
|
-
check=True,
|
|
137
|
-
)
|
|
138
|
-
except subprocess.CalledProcessError:
|
|
139
|
-
result = None
|
|
127
|
+
docker_compose_version = get_docker_compose_version()
|
|
128
|
+
except DockerComposeError:
|
|
129
|
+
docker_compose_version = None
|
|
140
130
|
console.warning(
|
|
141
131
|
f"Docker Compose is not installed, attempting to install v{MINIMUM_DOCKER_COMPOSE_VERSION}"
|
|
142
132
|
)
|
|
143
133
|
|
|
144
134
|
# Extract the version number from the output
|
|
145
|
-
version_output =
|
|
135
|
+
version_output = (
|
|
136
|
+
docker_compose_version if docker_compose_version is not None else ""
|
|
137
|
+
)
|
|
146
138
|
|
|
147
139
|
# Use regex to find the version number
|
|
148
140
|
pattern = r"^(\d+\.\d+\.\d+)"
|
|
@@ -171,7 +163,24 @@ def check_docker_compose_version() -> None:
|
|
|
171
163
|
install_docker_compose()
|
|
172
164
|
|
|
173
165
|
|
|
174
|
-
|
|
166
|
+
def get_docker_compose_version() -> str:
|
|
167
|
+
try:
|
|
168
|
+
result = subprocess.run(
|
|
169
|
+
["docker", "compose", "version", "--short"],
|
|
170
|
+
capture_output=True,
|
|
171
|
+
text=True,
|
|
172
|
+
check=True,
|
|
173
|
+
)
|
|
174
|
+
except subprocess.CalledProcessError as e:
|
|
175
|
+
raise DockerComposeError(
|
|
176
|
+
command="docker compose versions --short",
|
|
177
|
+
returncode=e.returncode,
|
|
178
|
+
stdout=e.stdout,
|
|
179
|
+
stderr=e.stderr,
|
|
180
|
+
)
|
|
181
|
+
return result.stdout.strip()
|
|
182
|
+
|
|
183
|
+
|
|
175
184
|
def get_non_remote_services(
|
|
176
185
|
service_config_path: str, current_env: dict[str, str]
|
|
177
186
|
) -> set[str]:
|
|
@@ -18,6 +18,7 @@ from devservices.utils.dependencies import InstalledRemoteDependency
|
|
|
18
18
|
from devservices.utils.docker_compose import check_docker_compose_version
|
|
19
19
|
from devservices.utils.docker_compose import DockerComposeCommand
|
|
20
20
|
from devservices.utils.docker_compose import get_docker_compose_commands_to_run
|
|
21
|
+
from devservices.utils.docker_compose import get_docker_compose_version
|
|
21
22
|
from devservices.utils.docker_compose import get_non_remote_services
|
|
22
23
|
from devservices.utils.docker_compose import install_docker_compose
|
|
23
24
|
from devservices.utils.services import Service
|
|
@@ -30,6 +31,26 @@ def test_check_docker_compose_version_success(mock_run: mock.Mock) -> None:
|
|
|
30
31
|
check_docker_compose_version() # Should not raise any exception
|
|
31
32
|
|
|
32
33
|
|
|
34
|
+
@mock.patch("subprocess.run")
|
|
35
|
+
def test_get_docker_compose_version(mock_run: mock.Mock) -> None:
|
|
36
|
+
mock_run.return_value.stdout = "2.29.7\n"
|
|
37
|
+
assert get_docker_compose_version() == "2.29.7"
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
@mock.patch(
|
|
41
|
+
"subprocess.run",
|
|
42
|
+
side_effect=subprocess.CalledProcessError(
|
|
43
|
+
returncode=1,
|
|
44
|
+
cmd="docker compose version --short",
|
|
45
|
+
stderr="Docker Compose failed",
|
|
46
|
+
),
|
|
47
|
+
)
|
|
48
|
+
def test_get_docker_compose_version_error(mock_run: mock.Mock) -> None:
|
|
49
|
+
with pytest.raises(DockerComposeError) as e:
|
|
50
|
+
get_docker_compose_version()
|
|
51
|
+
assert e.value.stderr == "Docker Compose failed"
|
|
52
|
+
|
|
53
|
+
|
|
33
54
|
@mock.patch("subprocess.run")
|
|
34
55
|
@mock.patch(
|
|
35
56
|
"devservices.utils.docker_compose.install_docker_compose", side_effect=lambda: None
|
|
@@ -76,18 +97,27 @@ def test_check_docker_compose_docker_daemon_not_running(
|
|
|
76
97
|
"subprocess.run",
|
|
77
98
|
side_effect=[
|
|
78
99
|
0, # First call is to check if docker daemon is running
|
|
79
|
-
subprocess.CalledProcessError(
|
|
80
|
-
returncode=1, cmd="docker compose version --short"
|
|
81
|
-
),
|
|
82
100
|
],
|
|
83
101
|
)
|
|
102
|
+
@mock.patch(
|
|
103
|
+
"devservices.utils.docker_compose.get_docker_compose_version",
|
|
104
|
+
side_effect=DockerComposeError(
|
|
105
|
+
command="docker compose version --short",
|
|
106
|
+
returncode=1,
|
|
107
|
+
stdout="",
|
|
108
|
+
stderr="",
|
|
109
|
+
),
|
|
110
|
+
)
|
|
84
111
|
@mock.patch(
|
|
85
112
|
"devservices.utils.docker_compose.install_docker_compose", side_effect=lambda: None
|
|
86
113
|
)
|
|
87
114
|
def test_check_docker_compose_command_failure(
|
|
88
|
-
mock_install_docker_compose: mock.Mock,
|
|
115
|
+
mock_install_docker_compose: mock.Mock,
|
|
116
|
+
mock_get_docker_compose_version: mock.Mock,
|
|
117
|
+
_mock_run: mock.Mock,
|
|
89
118
|
) -> None:
|
|
90
119
|
check_docker_compose_version()
|
|
120
|
+
mock_get_docker_compose_version.assert_called_once()
|
|
91
121
|
mock_install_docker_compose.assert_called_once()
|
|
92
122
|
|
|
93
123
|
|
|
@@ -139,11 +169,16 @@ def test_install_docker_compose_binary_install_error(
|
|
|
139
169
|
@mock.patch("devservices.utils.install_binary.os.chmod")
|
|
140
170
|
@mock.patch("devservices.utils.install_binary.shutil.move")
|
|
141
171
|
@mock.patch(
|
|
142
|
-
"devservices.utils.docker_compose.
|
|
143
|
-
side_effect=
|
|
172
|
+
"devservices.utils.docker_compose.get_docker_compose_version",
|
|
173
|
+
side_effect=DockerComposeError(
|
|
174
|
+
command="docker compose version --short",
|
|
175
|
+
returncode=1,
|
|
176
|
+
stdout="",
|
|
177
|
+
stderr="Docker Compose failed",
|
|
178
|
+
),
|
|
144
179
|
)
|
|
145
180
|
def test_install_docker_compose_compose_verification_error(
|
|
146
|
-
|
|
181
|
+
_mock_get_docker_compose_version: mock.Mock,
|
|
147
182
|
_mock_shutil_move: mock.Mock,
|
|
148
183
|
_mock_chmod: mock.Mock,
|
|
149
184
|
_mock_urlretrieve: mock.Mock,
|
|
@@ -157,22 +192,18 @@ def test_install_docker_compose_compose_verification_error(
|
|
|
157
192
|
install_docker_compose()
|
|
158
193
|
|
|
159
194
|
|
|
160
|
-
@mock.patch("tempfile.TemporaryDirectory")
|
|
195
|
+
@mock.patch("devservices.utils.install_binary.tempfile.TemporaryDirectory")
|
|
161
196
|
@mock.patch("platform.system", return_value="Darwin")
|
|
162
197
|
@mock.patch("platform.machine", return_value="arm64")
|
|
163
198
|
@mock.patch("devservices.utils.install_binary.urlretrieve")
|
|
164
199
|
@mock.patch("devservices.utils.install_binary.os.chmod")
|
|
165
200
|
@mock.patch("devservices.utils.install_binary.shutil.move")
|
|
166
201
|
@mock.patch(
|
|
167
|
-
"devservices.utils.docker_compose.
|
|
168
|
-
return_value=
|
|
169
|
-
args=["docker", "compose", "version", "--short"],
|
|
170
|
-
returncode=0,
|
|
171
|
-
stdout="2.29.7\n",
|
|
172
|
-
),
|
|
202
|
+
"devservices.utils.docker_compose.get_docker_compose_version",
|
|
203
|
+
return_value="2.29.7\n",
|
|
173
204
|
)
|
|
174
205
|
def test_install_docker_compose_macos_arm64(
|
|
175
|
-
|
|
206
|
+
mock_get_docker_compose_version: mock.Mock,
|
|
176
207
|
mock_shutil_move: mock.Mock,
|
|
177
208
|
mock_chmod: mock.Mock,
|
|
178
209
|
mock_urlretrieve: mock.Mock,
|
|
@@ -191,30 +222,21 @@ def test_install_docker_compose_macos_arm64(
|
|
|
191
222
|
"tempdir/docker-compose",
|
|
192
223
|
os.path.expanduser("~/.docker/cli-plugins/docker-compose"),
|
|
193
224
|
)
|
|
194
|
-
|
|
195
|
-
["docker", "compose", "version", "--short"],
|
|
196
|
-
capture_output=True,
|
|
197
|
-
check=True,
|
|
198
|
-
text=True,
|
|
199
|
-
)
|
|
225
|
+
mock_get_docker_compose_version.assert_called_once()
|
|
200
226
|
|
|
201
227
|
|
|
202
|
-
@mock.patch("tempfile.TemporaryDirectory")
|
|
228
|
+
@mock.patch("devservices.utils.install_binary.tempfile.TemporaryDirectory")
|
|
203
229
|
@mock.patch("platform.system", return_value="Linux")
|
|
204
230
|
@mock.patch("platform.machine", return_value="x86_64")
|
|
205
231
|
@mock.patch("devservices.utils.install_binary.urlretrieve")
|
|
206
232
|
@mock.patch("devservices.utils.install_binary.os.chmod")
|
|
207
233
|
@mock.patch("devservices.utils.install_binary.shutil.move")
|
|
208
234
|
@mock.patch(
|
|
209
|
-
"devservices.utils.docker_compose.
|
|
210
|
-
return_value=
|
|
211
|
-
args=["docker", "compose", "version", "--short"],
|
|
212
|
-
returncode=0,
|
|
213
|
-
stdout="2.29.7\n",
|
|
214
|
-
),
|
|
235
|
+
"devservices.utils.docker_compose.get_docker_compose_version",
|
|
236
|
+
return_value="2.29.7\n",
|
|
215
237
|
)
|
|
216
238
|
def test_install_docker_compose_linux_x86(
|
|
217
|
-
|
|
239
|
+
mock_get_docker_compose_version: mock.Mock,
|
|
218
240
|
mock_shutil_move: mock.Mock,
|
|
219
241
|
mock_chmod: mock.Mock,
|
|
220
242
|
mock_urlretrieve: mock.Mock,
|
|
@@ -233,12 +255,44 @@ def test_install_docker_compose_linux_x86(
|
|
|
233
255
|
"tempdir/docker-compose",
|
|
234
256
|
os.path.expanduser("~/.docker/cli-plugins/docker-compose"),
|
|
235
257
|
)
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
258
|
+
mock_get_docker_compose_version.assert_called_once()
|
|
259
|
+
|
|
260
|
+
|
|
261
|
+
@mock.patch("devservices.utils.install_binary.tempfile.TemporaryDirectory")
|
|
262
|
+
@mock.patch("platform.system", return_value="Darwin")
|
|
263
|
+
@mock.patch("platform.machine", return_value="arm64")
|
|
264
|
+
@mock.patch("devservices.utils.install_binary.urlretrieve")
|
|
265
|
+
@mock.patch("devservices.utils.install_binary.os.chmod")
|
|
266
|
+
@mock.patch("devservices.utils.install_binary.shutil.move")
|
|
267
|
+
@mock.patch(
|
|
268
|
+
"devservices.utils.docker_compose.get_docker_compose_version",
|
|
269
|
+
return_value="2.29.7\n",
|
|
270
|
+
)
|
|
271
|
+
def test_install_docker_compose_custom_docker_config_dir(
|
|
272
|
+
mock_get_docker_compose_version: mock.Mock,
|
|
273
|
+
mock_shutil_move: mock.Mock,
|
|
274
|
+
mock_chmod: mock.Mock,
|
|
275
|
+
mock_urlretrieve: mock.Mock,
|
|
276
|
+
_mock_machine: mock.Mock,
|
|
277
|
+
_mock_system: mock.Mock,
|
|
278
|
+
mock_tempdir: mock.Mock,
|
|
279
|
+
) -> None:
|
|
280
|
+
mock_tempdir.return_value.__enter__.return_value = "tempdir"
|
|
281
|
+
with mock.patch(
|
|
282
|
+
"devservices.utils.docker_compose.DOCKER_USER_PLUGIN_DIR",
|
|
283
|
+
"tempdir/docker/config/cli-plugins",
|
|
284
|
+
):
|
|
285
|
+
install_docker_compose()
|
|
286
|
+
mock_urlretrieve.assert_called_once_with(
|
|
287
|
+
"https://github.com/docker/compose/releases/download/v2.29.7/docker-compose-darwin-aarch64",
|
|
288
|
+
"tempdir/docker-compose",
|
|
289
|
+
)
|
|
290
|
+
mock_chmod.assert_called_once_with("tempdir/docker-compose", 0o755)
|
|
291
|
+
mock_shutil_move.assert_called_once_with(
|
|
292
|
+
"tempdir/docker-compose",
|
|
293
|
+
"tempdir/docker/config/cli-plugins/docker-compose",
|
|
241
294
|
)
|
|
295
|
+
mock_get_docker_compose_version.assert_called_once()
|
|
242
296
|
|
|
243
297
|
|
|
244
298
|
@mock.patch(
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|