Public Access
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ea4ee0d303 | ||
|
|
16fba17b03 |
@@ -2,6 +2,12 @@
|
|||||||
|
|
||||||
All notable changes to this project will be documented in this file.
|
All notable changes to this project will be documented in this file.
|
||||||
|
|
||||||
|
## [0.9.3] - 2026-06-24
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
- Use tempfile for dockerd log to fix CI permission error
|
||||||
|
|
||||||
## [0.9.2] - 2026-06-24
|
## [0.9.2] - 2026-06-24
|
||||||
|
|
||||||
### Bug Fixes
|
### Bug Fixes
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
"""devx — reusable development and CI/CD tools for oblachno-oss projects."""
|
"""devx — reusable development and CI/CD tools for oblachno-oss projects."""
|
||||||
|
|
||||||
__version__ = "0.9.2"
|
__version__ = "0.9.3"
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ from __future__ import annotations
|
|||||||
|
|
||||||
import subprocess # nosec B404
|
import subprocess # nosec B404
|
||||||
import sys
|
import sys
|
||||||
|
import tempfile
|
||||||
import time
|
import time
|
||||||
|
|
||||||
import click
|
import click
|
||||||
@@ -22,7 +23,6 @@ import click
|
|||||||
from devx.i18n import _
|
from devx.i18n import _
|
||||||
|
|
||||||
DEFAULT_TIMEOUT = 30
|
DEFAULT_TIMEOUT = 30
|
||||||
DOCKERD_LOG = "/var/log/dockerd.log"
|
|
||||||
|
|
||||||
|
|
||||||
def is_docker_ready() -> bool:
|
def is_docker_ready() -> bool:
|
||||||
@@ -46,7 +46,9 @@ def start_docker_daemon(timeout: int = DEFAULT_TIMEOUT) -> bool:
|
|||||||
start within the timeout.
|
start within the timeout.
|
||||||
"""
|
"""
|
||||||
click.echo(_("Starting Docker daemon..."))
|
click.echo(_("Starting Docker daemon..."))
|
||||||
log_file = open(DOCKERD_LOG, "w") # noqa: SIM115
|
log_file = tempfile.NamedTemporaryFile( # noqa: SIM115
|
||||||
|
mode="w", suffix="dockerd.log", delete=False
|
||||||
|
)
|
||||||
subprocess.Popen( # nosec B603 B607
|
subprocess.Popen( # nosec B603 B607
|
||||||
["dockerd", "--storage-driver", "vfs"],
|
["dockerd", "--storage-driver", "vfs"],
|
||||||
stdout=log_file,
|
stdout=log_file,
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
"""Unit tests for devx.molecule.start_docker."""
|
"""Unit tests for devx.molecule.start_docker."""
|
||||||
|
|
||||||
from unittest.mock import MagicMock, mock_open, patch
|
from unittest.mock import MagicMock, patch
|
||||||
|
|
||||||
from click.testing import CliRunner
|
from click.testing import CliRunner
|
||||||
|
|
||||||
@@ -24,14 +24,15 @@ class TestStartDockerDaemon:
|
|||||||
@patch("devx.molecule.start_docker.time.sleep")
|
@patch("devx.molecule.start_docker.time.sleep")
|
||||||
@patch("devx.molecule.start_docker.is_docker_ready")
|
@patch("devx.molecule.start_docker.is_docker_ready")
|
||||||
@patch("devx.molecule.start_docker.subprocess.Popen")
|
@patch("devx.molecule.start_docker.subprocess.Popen")
|
||||||
@patch("builtins.open", new_callable=mock_open)
|
@patch("devx.molecule.start_docker.tempfile.NamedTemporaryFile")
|
||||||
def test_starts_successfully(
|
def test_starts_successfully(
|
||||||
self,
|
self,
|
||||||
mock_file: MagicMock,
|
mock_ntf: MagicMock,
|
||||||
mock_popen: MagicMock,
|
mock_popen: MagicMock,
|
||||||
mock_ready: MagicMock,
|
mock_ready: MagicMock,
|
||||||
mock_sleep: MagicMock,
|
mock_sleep: MagicMock,
|
||||||
) -> None:
|
) -> None:
|
||||||
|
mock_ntf.return_value = MagicMock()
|
||||||
# First loop iteration: dockerd not ready yet. Second: ready.
|
# First loop iteration: dockerd not ready yet. Second: ready.
|
||||||
mock_ready.side_effect = [False, True]
|
mock_ready.side_effect = [False, True]
|
||||||
assert start_docker_daemon(timeout=5) is True
|
assert start_docker_daemon(timeout=5) is True
|
||||||
@@ -41,14 +42,15 @@ class TestStartDockerDaemon:
|
|||||||
@patch("devx.molecule.start_docker.time.sleep")
|
@patch("devx.molecule.start_docker.time.sleep")
|
||||||
@patch("devx.molecule.start_docker.is_docker_ready", return_value=False)
|
@patch("devx.molecule.start_docker.is_docker_ready", return_value=False)
|
||||||
@patch("devx.molecule.start_docker.subprocess.Popen")
|
@patch("devx.molecule.start_docker.subprocess.Popen")
|
||||||
@patch("builtins.open", new_callable=mock_open)
|
@patch("devx.molecule.start_docker.tempfile.NamedTemporaryFile")
|
||||||
def test_fails_after_timeout(
|
def test_fails_after_timeout(
|
||||||
self,
|
self,
|
||||||
mock_file: MagicMock,
|
mock_ntf: MagicMock,
|
||||||
mock_popen: MagicMock,
|
mock_popen: MagicMock,
|
||||||
mock_ready: MagicMock,
|
mock_ready: MagicMock,
|
||||||
mock_sleep: MagicMock,
|
mock_sleep: MagicMock,
|
||||||
) -> None:
|
) -> None:
|
||||||
|
mock_ntf.return_value = MagicMock()
|
||||||
assert start_docker_daemon(timeout=3) is False
|
assert start_docker_daemon(timeout=3) is False
|
||||||
mock_popen.assert_called_once()
|
mock_popen.assert_called_once()
|
||||||
assert mock_sleep.call_count == 3
|
assert mock_sleep.call_count == 3
|
||||||
@@ -56,14 +58,15 @@ class TestStartDockerDaemon:
|
|||||||
@patch("devx.molecule.start_docker.time.sleep")
|
@patch("devx.molecule.start_docker.time.sleep")
|
||||||
@patch("devx.molecule.start_docker.is_docker_ready")
|
@patch("devx.molecule.start_docker.is_docker_ready")
|
||||||
@patch("devx.molecule.start_docker.subprocess.Popen")
|
@patch("devx.molecule.start_docker.subprocess.Popen")
|
||||||
@patch("builtins.open", new_callable=mock_open)
|
@patch("devx.molecule.start_docker.tempfile.NamedTemporaryFile")
|
||||||
def test_ready_on_first_check(
|
def test_ready_on_first_check(
|
||||||
self,
|
self,
|
||||||
mock_file: MagicMock,
|
mock_ntf: MagicMock,
|
||||||
mock_popen: MagicMock,
|
mock_popen: MagicMock,
|
||||||
mock_ready: MagicMock,
|
mock_ready: MagicMock,
|
||||||
mock_sleep: MagicMock,
|
mock_sleep: MagicMock,
|
||||||
) -> None:
|
) -> None:
|
||||||
|
mock_ntf.return_value = MagicMock()
|
||||||
mock_ready.return_value = True
|
mock_ready.return_value = True
|
||||||
assert start_docker_daemon(timeout=5) is True
|
assert start_docker_daemon(timeout=5) is True
|
||||||
mock_popen.assert_called_once()
|
mock_popen.assert_called_once()
|
||||||
@@ -72,14 +75,15 @@ class TestStartDockerDaemon:
|
|||||||
@patch("devx.molecule.start_docker.time.sleep")
|
@patch("devx.molecule.start_docker.time.sleep")
|
||||||
@patch("devx.molecule.start_docker.is_docker_ready")
|
@patch("devx.molecule.start_docker.is_docker_ready")
|
||||||
@patch("devx.molecule.start_docker.subprocess.Popen")
|
@patch("devx.molecule.start_docker.subprocess.Popen")
|
||||||
@patch("builtins.open", new_callable=mock_open)
|
@patch("devx.molecule.start_docker.tempfile.NamedTemporaryFile")
|
||||||
def test_custom_timeout(
|
def test_custom_timeout(
|
||||||
self,
|
self,
|
||||||
mock_file: MagicMock,
|
mock_ntf: MagicMock,
|
||||||
mock_popen: MagicMock,
|
mock_popen: MagicMock,
|
||||||
mock_ready: MagicMock,
|
mock_ready: MagicMock,
|
||||||
mock_sleep: MagicMock,
|
mock_sleep: MagicMock,
|
||||||
) -> None:
|
) -> None:
|
||||||
|
mock_ntf.return_value = MagicMock()
|
||||||
# 9 iterations not ready, 10th ready.
|
# 9 iterations not ready, 10th ready.
|
||||||
mock_ready.side_effect = [False] * 9 + [True]
|
mock_ready.side_effect = [False] * 9 + [True]
|
||||||
assert start_docker_daemon(timeout=10) is True
|
assert start_docker_daemon(timeout=10) is True
|
||||||
|
|||||||
Reference in New Issue
Block a user