OctoPrint-BambuPrinter/test/test_gcode_execution.py
2024-07-24 17:15:46 +03:00

186 lines
5.4 KiB
Python

from __future__ import annotations
from collections.abc import Callable
from datetime import datetime, timezone
import logging
from pathlib import Path
import time
from typing import Any
import unittest
from unittest.mock import MagicMock
import unittest.mock
from octoprint_bambu_printer.bambu_print_plugin import BambuPrintPlugin
from octoprint_bambu_printer.printer.bambu_virtual_printer import BambuVirtualPrinter
from octoprint_bambu_printer.printer.remote_sd_card_file_list import (
FileInfo,
RemoteSDCardFileList,
)
from octoprint_bambu_printer.printer.states.idle_state import IdleState
from octoprint_bambu_printer.printer.states.paused_state import PausedState
from octoprint_bambu_printer.printer.states.print_finished_state import (
PrintFinishedState,
)
from octoprint_bambu_printer.printer.states.printing_state import PrintingState
from pytest import fixture
@fixture
def output_test_folder(output_folder: Path):
folder = output_folder / "test_gcode"
folder.mkdir(parents=True, exist_ok=True)
return folder
@fixture
def log_test():
return logging.getLogger("gcode_unittest")
class DictGetter:
def __init__(self, options: dict) -> None:
self._options: dict[str | tuple[str, ...], Any] = options
def __call__(self, key: str | list[str] | tuple[str, ...]):
if isinstance(key, list):
key = tuple(key)
return self._options.get(key, None)
@fixture
def settings(output_test_folder):
_settings = MagicMock()
_settings.get.side_effect = DictGetter(
{
"serial": "BAMBU",
"host": "localhost",
"access_code": "12345",
}
)
_settings.get_boolean.side_effect = DictGetter({"forceChecksum": False})
log_file_path = output_test_folder / "log.txt"
log_file_path.touch()
_settings.get_plugin_logfile_path.return_value = log_file_path.as_posix()
return _settings
@fixture
def profile_manager():
_profile_manager = MagicMock()
_profile_manager.get_current.side_effect = MagicMock()
_profile_manager.get_current().get.side_effect = DictGetter(
{
"heatedChamber": False,
}
)
return _profile_manager
@fixture
def files_info_ftp():
def _f_date(dt: datetime):
return dt.replace(tzinfo=timezone.utc).strftime("%Y%m%d%H%M%S")
return {
"print.3mf": (1000, _f_date(datetime(2024, 5, 6))),
"print2.3mf": (1200, _f_date(datetime(2024, 5, 7))),
}
@fixture
def ftps_session_mock(files_info_ftp):
with unittest.mock.patch(
"octoprint_bambu_printer.printer.ftpsclient.ftpsclient.IoTFTPSClient"
) as ftps_client_mock:
ftps_session = MagicMock()
ftps_session.size.side_effect = DictGetter(
{file: info[0] for file, info in files_info_ftp.items()}
)
ftps_session.sendcmd.side_effect = DictGetter(
{f"MDTM {file}": info[1] for file, info in files_info_ftp.items()}
)
all_files = list(files_info_ftp.keys())
file_registry = DictGetter(
{
("", ".3mf"): all_files,
("cache/", ".3mf"): [f"cache/{file}" for file in all_files],
}
)
ftps_client_mock.list_files.side_effect = lambda folder, ext: file_registry(
(folder, ext)
)
ftps_client_mock.ftps_session = ftps_session
RemoteSDCardFileList._connect_ftps_server = MagicMock(
return_value=ftps_client_mock
)
yield
@fixture
def printer(output_test_folder, settings, profile_manager, log_test, ftps_session_mock):
async def _mock_connection(self):
pass
BambuVirtualPrinter._create_connection_async = _mock_connection
serial_obj = BambuVirtualPrinter(
settings,
profile_manager,
data_folder=output_test_folder,
serial_log_handler=log_test,
read_timeout=5.0,
faked_baudrate=115200,
)
serial_obj._bambu_client = MagicMock()
yield serial_obj
serial_obj.close()
def test_initial_state(printer: BambuVirtualPrinter):
assert isinstance(printer.current_state, IdleState)
def test_list_sd_card(printer: BambuVirtualPrinter):
printer.write(b"M20\n") # GCode for listing SD card
printer.flush()
result = printer.readlines()
assert result == "" # Replace with the actual expected result
def test_start_print(printer: BambuVirtualPrinter):
printer.write(b"M\n")
result = printer.readline()
assert isinstance(printer.current_state, PrintingState)
def test_pause_print(printer: BambuVirtualPrinter):
gcode = b"G28\nG1 X10 Y10\n"
printer.write(gcode)
printer.write(b"M25\n") # GCode for pausing the print
result = printer.readline()
assert isinstance(printer.current_state, PausedState)
def test_get_printing_info(printer: BambuVirtualPrinter):
gcode = b"G28\nG1 X10 Y10\n"
printer.write(gcode)
printer.write(b"M27\n") # GCode for getting printing info
result = printer.readline()
assert result == ""
def test_abort_print(printer: BambuVirtualPrinter):
gcode = b"G28\nG1 X10 Y10\n"
printer.write(gcode)
printer.write(b"M26\n") # GCode for aborting the print
result = printer.readline()
assert isinstance(printer.current_state, IdleState)
def test_print_finished(printer: BambuVirtualPrinter):
gcode = b"G28\nG1 X10 Y10\n"
printer.write(gcode)
result = printer.readline()
assert isinstance(printer.current_state, PrintFinishedState)