This repository was archived by the owner on Sep 30, 2025. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathtest_docker.py
More file actions
207 lines (151 loc) · 6.94 KB
/
test_docker.py
File metadata and controls
207 lines (151 loc) · 6.94 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
import typing as t
from pathlib import Path
import pytest
import dreadnode_cli.agent.docker as docker
from dreadnode_cli.config import ServerConfig
from dreadnode_cli.defaults import DOCKER_REGISTRY_IMAGE_TAG
class MockImage:
def __init__(self, tags: list[str] | None = None) -> None:
self.tags = tags or []
def tag(self, *args: t.Any, **kwargs: t.Any) -> None:
pass
class MockContainer:
def __init__(self, image_tags: list[str], attrs: dict[str, t.Any]) -> None:
self.image = MockImage(image_tags)
self.attrs = attrs
class MockDockerClient:
"""Simple mock Docker client for testing."""
class api:
@staticmethod
def build(*args: t.Any, **kwargs: t.Any) -> list[dict[str, t.Any]]:
return [{"stream": "Step 1/1 : FROM hello-world\n"}, {"aux": {"ID": "sha256:mock123"}}]
@staticmethod
def push(*args: t.Any, **kwargs: t.Any) -> list[dict[str, t.Any]]:
return [
{"status": "Preparing", "id": "layer1"},
{"status": "Layer already exists", "id": "layer1"},
{"status": "Pushed", "id": "layer1"},
]
@staticmethod
def login(*args: t.Any, **kwargs: t.Any) -> dict[str, t.Any]:
return {"Status": "Login Succeeded"}
class images:
@staticmethod
def get(id: str) -> MockImage:
return MockImage()
class containers:
containers: list[MockContainer] = []
@staticmethod
def list(*args: t.Any, **kwargs: t.Any) -> list[MockContainer]:
return MockDockerClient.containers.containers
def _create_test_server_config(url: str = "https://platform.dreadnode.io") -> ServerConfig:
return ServerConfig(
url=url,
email="test@example.com",
username="test",
api_key="test",
access_token="test",
refresh_token="test",
)
def test_docker_not_available_get_registry() -> None:
docker.client = None
with pytest.raises(Exception, match="Docker not available"):
docker.get_registry(_create_test_server_config())
def test_docker_not_available_build(tmp_path: Path) -> None:
docker.client = None
with pytest.raises(Exception, match="Docker not available"):
dockerfile = tmp_path / "Dockerfile"
dockerfile.write_text("FROM hello-world")
image = docker.build(tmp_path)
assert image is None
def test_docker_not_available_push() -> None:
docker.client = None
with pytest.raises(Exception, match="Docker not available"):
image = MockImage()
docker.push(image, "test-repo", "latest")
def test_build(tmp_path: Path) -> None:
# set mock client
docker.client = MockDockerClient()
# Create a test Dockerfile
dockerfile = tmp_path / "Dockerfile"
dockerfile.write_text("FROM hello-world")
# Test building image
image = docker.build(tmp_path)
assert image is not None
def test_push(tmp_path: Path) -> None:
# set mock client
docker.client = MockDockerClient()
# Create and build test image
dockerfile = tmp_path / "Dockerfile"
dockerfile.write_text("FROM hello-world")
image = docker.build(tmp_path)
# Test pushing image
docker.push(image, "test-repo", "latest")
def test_get_registry() -> None:
# Test production registry
config = _create_test_server_config()
assert docker.get_registry(config) == "registry.dreadnode.io"
# Test staging registry
config = _create_test_server_config("https://staging-platform.dreadnode.io")
assert docker.get_registry(config) == "staging-registry.dreadnode.io"
config = _create_test_server_config("https://staging-platform.dreadnode.io")
assert docker.get_registry(config) == "staging-registry.dreadnode.io"
# Test dev registry
config = _create_test_server_config("https://dev-platform.dreadnode.io")
assert docker.get_registry(config) == "dev-registry.dreadnode.io"
config = _create_test_server_config("https://dev-platform.dreadnode.io")
assert docker.get_registry(config) == "dev-registry.dreadnode.io"
# Test localhost registry
config = _create_test_server_config("http://localhost:8000")
assert docker.get_registry(config) == "localhost:5005"
def test_get_local_registry_port_with_running_registry_container() -> None:
with pytest.MonkeyPatch.context() as mp:
mp.setattr(
docker.client.containers,
"containers",
[
MockContainer(
[DOCKER_REGISTRY_IMAGE_TAG], {"NetworkSettings": {"Ports": {"5000/tcp": [{"HostPort": "12345"}]}}}
)
],
)
assert docker.get_registry(_create_test_server_config("http://localhost:8000")) == "localhost:12345"
def test_get_registry_without_schema() -> None:
# Test without schema
config = _create_test_server_config("platform.dreadnode.io")
assert docker.get_registry(config) == "registry.dreadnode.io"
config = _create_test_server_config("staging-platform.dreadnode.io")
assert docker.get_registry(config) == "staging-registry.dreadnode.io"
config = _create_test_server_config("dev-platform.dreadnode.io")
assert docker.get_registry(config) == "dev-registry.dreadnode.io"
config = _create_test_server_config("localhost:8000")
assert docker.get_registry(config) == "localhost:5005"
def test_get_registry_custom_platform_base_domain() -> None:
# Test custom platform base domain
config = _create_test_server_config("platform.example.com")
with pytest.MonkeyPatch.context() as mp:
mp.setattr("dreadnode_cli.agent.docker.PLATFORM_BASE_DOMAIN", "example.com")
assert docker.get_registry(config) == "registry.example.com"
config = _create_test_server_config("staging-platform.example.com")
assert docker.get_registry(config) == "staging-registry.example.com"
config = _create_test_server_config("dev-platform.example.com")
assert docker.get_registry(config) == "dev-registry.example.com"
def test_sanitized_name() -> None:
# Test basic name
assert docker.sanitized_name("test-agent") == "test-agent"
assert docker.sanitized_name("test- agent") == "test-agent"
assert docker.sanitized_name("test_agent") == "test_agent"
# Test spaces
assert docker.sanitized_name("test agent") == "test-agent"
assert docker.sanitized_name("test multiple spaces") == "test-multiple-spaces"
# Test special characters
assert docker.sanitized_name("test!@#$%^&*()agent") == "testagent"
assert docker.sanitized_name("test_agent.123") == "test_agent123"
assert docker.sanitized_name("test/agent\\path") == "testagentpath"
# Test mixed case
assert docker.sanitized_name("TestAgent") == "testagent"
assert docker.sanitized_name("TEST AGENT") == "test-agent"
# Test edge cases
assert docker.sanitized_name(" spaced name ") == "spaced-name"
assert docker.sanitized_name("!!!###") == ""
assert docker.sanitized_name("123 456") == "123-456"