Skip to content

Commit

Permalink
Add test case and update Makefile (#21)
Browse files Browse the repository at this point in the history
* test: add test case and update Makefile

* fix: update makefile and gitignore
  • Loading branch information
touero authored Nov 22, 2024
1 parent a7c9edd commit 1080c99
Show file tree
Hide file tree
Showing 3 changed files with 98 additions and 88 deletions.
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@
__pycache__/
dist/
easier_docker.egg-info/
example.egg-info/
venv/
build/
.coverage
easierdocker/easier_docker.egg-info/
htmlcov
easierdocker/easier_docker.egg-info/
6 changes: 5 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,17 @@ all: clean build
test:
coverage run -m unittest discover
coverage report
coverage html
google-chrome htmlcov/index.html


clean:
find . -name '__pycache__' -type d -exec rm -rf {} +
find . -name 'easier_docker.egg-info' -type d -exec rm -rf {} +
rm -rf build
rm -rf dist
rm -rf .coverage
rm -rf htmlcov

build:
python -m build
Expand All @@ -24,4 +28,4 @@ upload:
echo "Error: TWINE_API_TOKEN is not set. Please export it as an environment variable."; \
exit 1; \
fi
$(TWINE_UPLOAD) dist/*
$(TWINE_UPLOAD) dist/*
176 changes: 90 additions & 86 deletions tests/test_easier_docker.py
Original file line number Diff line number Diff line change
@@ -1,98 +1,102 @@
import os

import unittest
from unittest.mock import patch, MagicMock

from docker.errors import ImageNotFound, APIError, NotFound, DockerException
from easierdocker import EasierDocker
from easierdocker.exceptions import DockerConnectionError, NotFoundImageInDockerHub


class TestEasierDocker(unittest.TestCase):
@patch('docker.from_env')
def test_init(self, mock_from_env):
parent_dir = os.path.dirname(os.getcwd())
host_script = os.path.join(parent_dir, 'example')
container_script = '/path/to/container'
container_config = {
'image': 'python:3.9',
'name': 'python_test',
'volumes': {
f'{host_script}': {'bind': container_script, 'mode': 'rw'}
},
'detach': True,
'command': ["sh", "-c", f'cd {container_script} &&'
'python docker_example.py'],
def setUp(self):
self.container_config = {
"image": "test_image",
"name": "test_container",
"detach": True
}
self.network_config = {"name": "test_network"}
self.easier_docker = EasierDocker(self.container_config, self.network_config)

network_config = {
'name': 'bridge',
'driver': 'bridge',
}
@patch("docker.from_env")
def test_docker_connection_error(self, mock_from_env):
mock_from_env.side_effect = DockerException("Docker connection failed")
with self.assertRaises(DockerConnectionError):
EasierDocker(container_config={}, network_config={})

mock_client = MagicMock()
mock_from_env.return_value = mock_client
easier_docker = EasierDocker(container_config=container_config, network_config={})

self.assertEqual(easier_docker._container_config, container_config)
self.assertEqual(easier_docker._network_config, {})

mock_from_env.assert_called_once()
self.assertEqual(easier_docker._client, mock_client)

easier_docker = EasierDocker(container_config=container_config, network_config=network_config)
self.assertEqual(easier_docker._container_config, container_config)
self.assertEqual(easier_docker._network_config, network_config)

@patch('docker.from_env')
def test_properties(self, mock_from_env):
parent_dir = os.path.dirname(os.getcwd())
host_script = os.path.join(parent_dir, 'example')
container_script = '/path/to/container'
container_config = {
'image': 'python:3.9',
'name': 'python_test',
'volumes': {
f'{host_script}': {'bind': container_script, 'mode': 'rw'}
},
'detach': True,
'command': ["sh", "-c", f'cd {container_script} &&'
'python docker_example.py'],
}
@patch("docker.from_env")
def test_init_success(self, mock_from_env):
client_mock = MagicMock()
mock_from_env.return_value = client_mock
docker_instance = EasierDocker(self.container_config)
self.assertIsNotNone(docker_instance.client)

network_config = {
'name': 'bridge',
'driver': 'bridge',
}
mock_client = MagicMock()
mock_from_env.return_value = mock_client
easier_docker = EasierDocker(container_config=container_config, network_config=network_config)
self.assertEqual(easier_docker.container_config, container_config)
self.assertEqual(easier_docker.network_config, network_config)
self.assertEqual(easier_docker.client, mock_client)
self.assertEqual(easier_docker.image_name, container_config['image'])
self.assertEqual(easier_docker.container_name, container_config['name'])

@patch('docker.from_env')
def test_get_images(self, mock_from_env):
parent_dir = os.path.dirname(os.getcwd())
host_script = os.path.join(parent_dir, 'example')
container_script = '/path/to/container'
container_config = {
'image': 'python:3.9',
'name': 'python_test',
'volumes': {
f'{host_script}': {'bind': container_script, 'mode': 'rw'}
},
'detach': True,
'command': ["sh", "-c", f'cd {container_script} &&'
'python docker_example.py'],
}
@patch("docker.from_env", side_effect=DockerConnectionError("Docker connection failed"))
def test_init_failure(self, mock_from_env):
with self.assertRaises(DockerConnectionError):
EasierDocker(self.container_config)

network_config = {
'name': 'bridge',
'driver': 'bridge',
}
mock_client = MagicMock()
mock_from_env.return_value = mock_client
easier_docker = EasierDocker(container_config=container_config, network_config=network_config)
easier_docker._EasierDocker__get_image()
mock_client.images.get.assert_called_once_with(easier_docker.image_name)
@patch("docker.models.images.ImageCollection.get")
def test_get_image_found_locally(self, mock_image_get):
self.easier_docker._EasierDocker__get_image()
mock_image_get.assert_called_once_with("test_image")

@patch("docker.models.images.ImageCollection.get", side_effect=ImageNotFound("Image not found"))
@patch("docker.api.APIClient.pull", return_value=[
'{"status": "Pulling", "progress": "50%"}'.encode("utf-8"),
'{"status": "Complete"}'.encode("utf-8")
])
def test_get_image_pull_success(self, mock_pull, mock_image_get):
self.easier_docker._EasierDocker__get_image()
mock_pull.assert_called_once_with("test_image", stream=True)

@patch("docker.models.images.ImageCollection.get", side_effect=ImageNotFound("Image not found"))
@patch("docker.api.APIClient.pull", side_effect=NotFound("Image not in Docker Hub"))
def test_get_image_pull_failure(self, mock_pull, mock_image_get):
with self.assertRaises(NotFoundImageInDockerHub):
self.easier_docker._EasierDocker__get_image()

@patch("docker.models.containers.ContainerCollection.list", return_value=[])
@patch("docker.models.containers.ContainerCollection.run")
def test_run_container_success(self, mock_run, mock_list):
container_mock = MagicMock()
container_mock.attrs = {"NetworkSettings": {"IPAddress": "127.0.0.1"}, "Created": "now"}
container_mock.name = "test_container"
container_mock.short_id = "12345"
mock_run.return_value = container_mock

self.easier_docker._EasierDocker__run_container()
mock_run.assert_called_once_with(**self.container_config)

@patch("docker.models.containers.ContainerCollection.list", return_value=[])
@patch("docker.models.containers.ContainerCollection.run", side_effect=APIError("API Error"))
def test_run_container_failure(self, mock_run, mock_list):
with self.assertRaises(APIError):
self.easier_docker._EasierDocker__run_container()

@patch("docker.models.containers.ContainerCollection.list", return_value=[MagicMock()])
def test_get_container_found(self, mock_list):
container_mock = mock_list.return_value[0]
container_mock.name = "test_container"
container_mock.attrs = {"NetworkSettings": {"IPAddress": "127.0.0.1"}, "Created": "now"}
container_mock.start = MagicMock()

container = self.easier_docker._EasierDocker__get_container()
self.assertEqual(container_mock, container)
container_mock.start.assert_called_once()

@patch("docker.models.containers.ContainerCollection.list", return_value=[])
def test_get_container_not_found(self, mock_list):
container = self.easier_docker._EasierDocker__get_container()
self.assertIsNone(container)

@patch("docker.models.networks.NetworkCollection.list", return_value=[])
@patch("docker.models.networks.NetworkCollection.create")
def test_create_network(self, mock_create, mock_list):
self.easier_docker._EasierDocker__create_network()
mock_create.assert_called_once_with(**self.network_config)

@patch("docker.client.DockerClient.networks", new_callable=MagicMock)
def test_create_network_exists(self, mock_networks):
mock_network = MagicMock(name="test_network", short_id="short_id_1")
mock_networks.list.return_value = [mock_network]
self.easier_docker._EasierDocker__create_network()
mock_networks.list.assert_called_once()

0 comments on commit 1080c99

Please sign in to comment.