mirror of
https://github.com/ChristianLight/tutor.git
synced 2024-12-13 14:43:03 +00:00
fix: utils tests on macOS
test_utils tests were failing on macOS when the settings file was properly defined and present. Close #560.
This commit is contained in:
parent
37be2bf122
commit
43d5da83e4
@ -4,7 +4,7 @@ import sys
|
|||||||
import tempfile
|
import tempfile
|
||||||
import unittest
|
import unittest
|
||||||
from io import StringIO
|
from io import StringIO
|
||||||
from unittest.mock import MagicMock, patch
|
from unittest.mock import MagicMock, mock_open, patch
|
||||||
|
|
||||||
from tutor import exceptions, utils
|
from tutor import exceptions, utils
|
||||||
|
|
||||||
@ -152,9 +152,59 @@ class UtilsTests(unittest.TestCase):
|
|||||||
process.kill.assert_called_once()
|
process.kill.assert_called_once()
|
||||||
|
|
||||||
@patch("sys.platform", "win32")
|
@patch("sys.platform", "win32")
|
||||||
def test_check_macos_memory_win32_should_skip(self) -> None:
|
def test_check_macos_docker_memory_win32_should_skip(self) -> None:
|
||||||
utils.check_macos_memory()
|
utils.check_macos_docker_memory()
|
||||||
|
|
||||||
@patch("sys.platform", "darwin")
|
@patch("sys.platform", "darwin")
|
||||||
def test_check_macos_memory_darwin_filenotfound(self) -> None:
|
def test_check_macos_docker_memory_darwin(self) -> None:
|
||||||
self.assertRaises(exceptions.TutorError, utils.check_macos_memory)
|
with patch("tutor.utils.open", mock_open(read_data='{"memoryMiB": 4096}')):
|
||||||
|
utils.check_macos_docker_memory()
|
||||||
|
|
||||||
|
@patch("sys.platform", "darwin")
|
||||||
|
def test_check_macos_docker_memory_darwin_filenotfound(self) -> None:
|
||||||
|
with patch("tutor.utils.open", mock_open()) as mock_open_settings:
|
||||||
|
mock_open_settings.return_value.__enter__.side_effect = FileNotFoundError
|
||||||
|
with self.assertRaises(exceptions.TutorError) as e:
|
||||||
|
utils.check_macos_docker_memory()
|
||||||
|
self.assertIn("Error accessing Docker settings file", e.exception.args[0])
|
||||||
|
|
||||||
|
@patch("sys.platform", "darwin")
|
||||||
|
def test_check_macos_docker_memory_darwin_json_decode_error(self) -> None:
|
||||||
|
with patch("tutor.utils.open", mock_open(read_data="invalid")):
|
||||||
|
with self.assertRaises(exceptions.TutorError) as e:
|
||||||
|
utils.check_macos_docker_memory()
|
||||||
|
self.assertIn("invalid JSON", e.exception.args[0])
|
||||||
|
|
||||||
|
@patch("sys.platform", "darwin")
|
||||||
|
def test_check_macos_docker_memory_darwin_key_error(self) -> None:
|
||||||
|
with patch("tutor.utils.open", mock_open(read_data="{}")):
|
||||||
|
with self.assertRaises(exceptions.TutorError) as e:
|
||||||
|
utils.check_macos_docker_memory()
|
||||||
|
self.assertIn("key 'memoryMiB' not found", e.exception.args[0])
|
||||||
|
|
||||||
|
@patch("sys.platform", "darwin")
|
||||||
|
def test_check_macos_docker_memory_darwin_type_error(self) -> None:
|
||||||
|
with patch(
|
||||||
|
"tutor.utils.open", mock_open(read_data='{"memoryMiB": "invalidstring"}')
|
||||||
|
):
|
||||||
|
with self.assertRaises(exceptions.TutorError) as e:
|
||||||
|
utils.check_macos_docker_memory()
|
||||||
|
self.assertIn("Unexpected JSON data", e.exception.args[0])
|
||||||
|
|
||||||
|
@patch("sys.platform", "darwin")
|
||||||
|
def test_check_macos_docker_memory_darwin_insufficient_memory(self) -> None:
|
||||||
|
with patch("tutor.utils.open", mock_open(read_data='{"memoryMiB": 4095}')):
|
||||||
|
with self.assertRaises(exceptions.TutorError) as e:
|
||||||
|
utils.check_macos_docker_memory()
|
||||||
|
self.assertEqual(
|
||||||
|
"Docker is configured to allocate 4095 MiB RAM, less than the recommended 4096 MiB",
|
||||||
|
e.exception.args[0],
|
||||||
|
)
|
||||||
|
|
||||||
|
@patch("sys.platform", "darwin")
|
||||||
|
def test_check_macos_docker_memory_darwin_encoding_error(self) -> None:
|
||||||
|
with patch("tutor.utils.open", mock_open()) as mock_open_settings:
|
||||||
|
mock_open_settings.return_value.__enter__.side_effect = TypeError
|
||||||
|
with self.assertRaises(exceptions.TutorError) as e:
|
||||||
|
utils.check_macos_docker_memory()
|
||||||
|
self.assertIn("Text encoding error", e.exception.args[0])
|
||||||
|
@ -45,16 +45,14 @@ def local(context: click.Context) -> None:
|
|||||||
@click.pass_context
|
@click.pass_context
|
||||||
def quickstart(context: click.Context, non_interactive: bool, pullimages: bool) -> None:
|
def quickstart(context: click.Context, non_interactive: bool, pullimages: bool) -> None:
|
||||||
try:
|
try:
|
||||||
utils.check_macos_memory()
|
utils.check_macos_docker_memory()
|
||||||
except exceptions.TutorError as e:
|
except exceptions.TutorError as e:
|
||||||
fmt.echo_alert(
|
fmt.echo_alert(
|
||||||
"""Could not verify sufficient RAM allocation in Docker:
|
f"""Could not verify sufficient RAM allocation in Docker:
|
||||||
{}
|
{e}
|
||||||
Tutor may not work if Docker is configured with < 4 GB RAM. Please follow instructions from:
|
Tutor may not work if Docker is configured with < 4 GB RAM. Please follow the instructions from:
|
||||||
https://docs.tutor.overhang.io/install.html
|
https://docs.tutor.overhang.io/install.html
|
||||||
""".format(
|
"""
|
||||||
str(e)
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
|
|
||||||
if tutor_env.needs_major_upgrade(context.obj.root):
|
if tutor_env.needs_major_upgrade(context.obj.root):
|
||||||
|
@ -222,9 +222,12 @@ def check_output(*command: str) -> bytes:
|
|||||||
) from e
|
) from e
|
||||||
|
|
||||||
|
|
||||||
def check_macos_memory() -> None:
|
def check_macos_docker_memory() -> None:
|
||||||
"""
|
"""
|
||||||
Try to check that the RAM allocated to the Docker VM on macOS is at least 4 GB.
|
Try to check that the RAM allocated to the Docker VM on macOS is at least 4 GB.
|
||||||
|
|
||||||
|
Parse macOS Docker settings file from user directory and return the max
|
||||||
|
allocated memory. Will raise TutorError in case of parsing/loading error.
|
||||||
"""
|
"""
|
||||||
if sys.platform != "darwin":
|
if sys.platform != "darwin":
|
||||||
return
|
return
|
||||||
@ -238,27 +241,25 @@ def check_macos_memory() -> None:
|
|||||||
data = json.load(fp)
|
data = json.load(fp)
|
||||||
memory_mib = int(data["memoryMiB"])
|
memory_mib = int(data["memoryMiB"])
|
||||||
except OSError as e:
|
except OSError as e:
|
||||||
raise exceptions.TutorError(
|
raise exceptions.TutorError(f"Error accessing Docker settings file: {e}") from e
|
||||||
"Error accessing {}: [{}] {}".format(settings_path, e.errno, e.strerror)
|
|
||||||
) from e
|
|
||||||
except json.JSONDecodeError as e:
|
except json.JSONDecodeError as e:
|
||||||
raise exceptions.TutorError(
|
raise exceptions.TutorError(
|
||||||
"Error reading {}: invalid JSON: {} [{}:{}]".format(
|
f"Error reading {settings_path}, invalid JSON: {e}"
|
||||||
settings_path, e.msg, e.lineno, e.colno
|
|
||||||
)
|
|
||||||
) from e
|
) from e
|
||||||
except (ValueError, TypeError, OverflowError) as e:
|
except ValueError as e:
|
||||||
# ValueError from open() indicates an encoding error
|
|
||||||
raise exceptions.TutorError(
|
raise exceptions.TutorError(
|
||||||
"Text encoding error or unexpected JSON data: in {}: {}".format(
|
f"Unexpected JSON data in {settings_path}: {e}"
|
||||||
settings_path, str(e)
|
|
||||||
)
|
|
||||||
) from e
|
) from e
|
||||||
except KeyError as e:
|
except KeyError as e:
|
||||||
# Value is absent (Docker creates the file with the default setting of 2048 explicitly
|
# Value is absent (Docker creates the file with the default setting of 2048 explicitly
|
||||||
# written in, so we shouldn't need to assume a default value here.)
|
# written in, so we shouldn't need to assume a default value here.)
|
||||||
raise exceptions.TutorError(
|
raise exceptions.TutorError(
|
||||||
"key 'memoryMiB' not found in {}".format(settings_path)
|
f"key 'memoryMiB' not found in {settings_path}"
|
||||||
|
) from e
|
||||||
|
except (TypeError, OverflowError) as e:
|
||||||
|
# TypeError from open() indicates an encoding error
|
||||||
|
raise exceptions.TutorError(
|
||||||
|
f"Text encoding error in {settings_path}: {e}"
|
||||||
) from e
|
) from e
|
||||||
|
|
||||||
if memory_mib < 4096:
|
if memory_mib < 4096:
|
||||||
|
Loading…
Reference in New Issue
Block a user