Fix unittest IO synchronization.
This commit is contained in:
parent
73f77ed659
commit
8178dea15a
@ -6,9 +6,7 @@ import collections
|
|||||||
from dataclasses import dataclass, field
|
from dataclasses import dataclass, field
|
||||||
import math
|
import math
|
||||||
import os
|
import os
|
||||||
import queue
|
|
||||||
import re
|
import re
|
||||||
import threading
|
|
||||||
import time
|
import time
|
||||||
import asyncio
|
import asyncio
|
||||||
from pybambu import BambuClient, commands
|
from pybambu import BambuClient, commands
|
||||||
@ -478,27 +476,6 @@ class BambuVirtualPrinter:
|
|||||||
else:
|
else:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def _writeSdFile(self, filename: str) -> None:
|
|
||||||
self.sendIO(f"Writing to file: {filename}")
|
|
||||||
|
|
||||||
def _finishSdFile(self):
|
|
||||||
# FIXME: maybe remove or move to remote SD card
|
|
||||||
try:
|
|
||||||
self._writingToSdHandle.close()
|
|
||||||
except Exception:
|
|
||||||
pass
|
|
||||||
finally:
|
|
||||||
self._writingToSdHandle = None
|
|
||||||
self._writingToSd = False
|
|
||||||
self._selectedSdFile = None
|
|
||||||
# Most printers don't have RTC and set some ancient date
|
|
||||||
# by default. Emulate that using 2000-01-01 01:00:00
|
|
||||||
# (taken from prusa firmware behaviour)
|
|
||||||
st = os.stat(self._writingToSdFile)
|
|
||||||
os.utime(self._writingToSdFile, (st.st_atime, 946684800))
|
|
||||||
self._writingToSdFile = None
|
|
||||||
self.sendIO("Done saving file")
|
|
||||||
|
|
||||||
def close(self):
|
def close(self):
|
||||||
if self.bambu_client.connected:
|
if self.bambu_client.connected:
|
||||||
self.bambu_client.disconnect()
|
self.bambu_client.disconnect()
|
||||||
|
@ -44,6 +44,7 @@ class PrinterSerialIO(threading.Thread, BufferedIOBase):
|
|||||||
|
|
||||||
self.input_bytes = CharCountingQueue(self._rx_buffer_size, name="RxBuffer")
|
self.input_bytes = CharCountingQueue(self._rx_buffer_size, name="RxBuffer")
|
||||||
self.output_bytes = queue.Queue()
|
self.output_bytes = queue.Queue()
|
||||||
|
self._error_detected: Exception | None = None
|
||||||
|
|
||||||
def _init_logger(self, log_handler):
|
def _init_logger(self, log_handler):
|
||||||
log = logging.getLogger("octoprint.plugins.bambu_printer.BambuPrinter.serial")
|
log = logging.getLogger("octoprint.plugins.bambu_printer.BambuPrinter.serial")
|
||||||
@ -63,7 +64,6 @@ class PrinterSerialIO(threading.Thread, BufferedIOBase):
|
|||||||
try:
|
try:
|
||||||
data = self.input_bytes.get(block=True, timeout=0.01)
|
data = self.input_bytes.get(block=True, timeout=0.01)
|
||||||
data = to_bytes(data, encoding="ascii", errors="replace")
|
data = to_bytes(data, encoding="ascii", errors="replace")
|
||||||
self.input_bytes.task_done()
|
|
||||||
|
|
||||||
buffer += data
|
buffer += data
|
||||||
line, buffer = self._read_next_line(buffer)
|
line, buffer = self._read_next_line(buffer)
|
||||||
@ -71,8 +71,12 @@ class PrinterSerialIO(threading.Thread, BufferedIOBase):
|
|||||||
self._received_lines += 1
|
self._received_lines += 1
|
||||||
self._process_input_gcode_line(line)
|
self._process_input_gcode_line(line)
|
||||||
line, buffer = self._read_next_line(buffer)
|
line, buffer = self._read_next_line(buffer)
|
||||||
|
self.input_bytes.task_done()
|
||||||
except queue.Empty:
|
except queue.Empty:
|
||||||
continue
|
continue
|
||||||
|
except Exception as e:
|
||||||
|
self._error_detected = e
|
||||||
|
break
|
||||||
|
|
||||||
self._log.debug("Closing IO read loop")
|
self._log.debug("Closing IO read loop")
|
||||||
|
|
||||||
@ -92,6 +96,8 @@ class PrinterSerialIO(threading.Thread, BufferedIOBase):
|
|||||||
|
|
||||||
def flush(self):
|
def flush(self):
|
||||||
self.input_bytes.join()
|
self.input_bytes.join()
|
||||||
|
if self._error_detected is not None:
|
||||||
|
raise self._error_detected
|
||||||
|
|
||||||
def write(self, data: bytes) -> int:
|
def write(self, data: bytes) -> int:
|
||||||
data = to_bytes(data, errors="replace")
|
data = to_bytes(data, errors="replace")
|
||||||
|
@ -80,18 +80,12 @@ class RemoteSDCardFileList:
|
|||||||
def _get_existing_files_info(self):
|
def _get_existing_files_info(self):
|
||||||
ftp = self._connect_ftps_server()
|
ftp = self._connect_ftps_server()
|
||||||
|
|
||||||
all_files_info: list[FileInfo] = []
|
file_list = []
|
||||||
|
file_list.extend(ftp.list_files("", ".3mf") or [])
|
||||||
|
file_list.extend(ftp.list_files("cache/", ".3mf") or [])
|
||||||
|
|
||||||
existing_files = []
|
existing_files = []
|
||||||
|
return list(self._scan_ftp_file_list(ftp, file_list, existing_files))
|
||||||
filelist = ftp.list_files("", ".3mf") or []
|
|
||||||
all_files_info.extend(self._scan_ftp_file_list(ftp, filelist, existing_files))
|
|
||||||
|
|
||||||
filelist_cache = ftp.list_files("cache/", ".3mf") or []
|
|
||||||
all_files_info.extend(
|
|
||||||
self._scan_ftp_file_list(ftp, filelist_cache, existing_files)
|
|
||||||
)
|
|
||||||
|
|
||||||
return all_files_info
|
|
||||||
|
|
||||||
def _connect_ftps_server(self):
|
def _connect_ftps_server(self):
|
||||||
host = self._settings.get(["host"])
|
host = self._settings.get(["host"])
|
||||||
|
@ -84,6 +84,8 @@ def files_info_ftp():
|
|||||||
return {
|
return {
|
||||||
"print.3mf": (1000, _f_date(datetime(2024, 5, 6))),
|
"print.3mf": (1000, _f_date(datetime(2024, 5, 6))),
|
||||||
"print2.3mf": (1200, _f_date(datetime(2024, 5, 7))),
|
"print2.3mf": (1200, _f_date(datetime(2024, 5, 7))),
|
||||||
|
"cache/print.3mf": (1200, _f_date(datetime(2024, 5, 7))),
|
||||||
|
"cache/print2.3mf": (1200, _f_date(datetime(2024, 5, 7))),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -104,8 +106,12 @@ def ftps_session_mock(files_info_ftp):
|
|||||||
all_files = list(files_info_ftp.keys())
|
all_files = list(files_info_ftp.keys())
|
||||||
file_registry = DictGetter(
|
file_registry = DictGetter(
|
||||||
{
|
{
|
||||||
("", ".3mf"): all_files,
|
("", ".3mf"): list(
|
||||||
("cache/", ".3mf"): [f"cache/{file}" for file in all_files],
|
filter(lambda f: Path(f).parent == Path("."), all_files)
|
||||||
|
),
|
||||||
|
("cache/", ".3mf"): list(
|
||||||
|
filter(lambda f: Path(f).parent == Path("cache/"), all_files)
|
||||||
|
),
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
ftps_client_mock.list_files.side_effect = lambda folder, ext: file_registry(
|
ftps_client_mock.list_files.side_effect = lambda folder, ext: file_registry(
|
||||||
@ -118,7 +124,7 @@ def ftps_session_mock(files_info_ftp):
|
|||||||
yield
|
yield
|
||||||
|
|
||||||
|
|
||||||
@fixture
|
@fixture(scope="function")
|
||||||
def printer(output_test_folder, settings, profile_manager, log_test, ftps_session_mock):
|
def printer(output_test_folder, settings, profile_manager, log_test, ftps_session_mock):
|
||||||
async def _mock_connection(self):
|
async def _mock_connection(self):
|
||||||
pass
|
pass
|
||||||
@ -145,12 +151,36 @@ def test_list_sd_card(printer: BambuVirtualPrinter):
|
|||||||
printer.write(b"M20\n") # GCode for listing SD card
|
printer.write(b"M20\n") # GCode for listing SD card
|
||||||
printer.flush()
|
printer.flush()
|
||||||
result = printer.readlines()
|
result = printer.readlines()
|
||||||
assert result == "" # Replace with the actual expected result
|
assert result[0] == b"Begin file list"
|
||||||
|
assert result[1].endswith(b'"print.3mf"')
|
||||||
|
assert result[2].endswith(b'"print2.3mf"')
|
||||||
|
assert result[3] == b"End file list"
|
||||||
|
assert result[4] == b"ok"
|
||||||
|
|
||||||
|
|
||||||
def test_start_print(printer: BambuVirtualPrinter):
|
def test_cannot_start_print_without_file(printer: BambuVirtualPrinter):
|
||||||
printer.write(b"M\n")
|
printer.write(b"M24\n")
|
||||||
result = printer.readline()
|
printer.flush()
|
||||||
|
|
||||||
|
result = printer.readlines()
|
||||||
|
assert result[0] == b"ok"
|
||||||
|
assert isinstance(printer.current_state, IdleState)
|
||||||
|
|
||||||
|
|
||||||
|
def test_print_started_with_selected_file(printer: BambuVirtualPrinter):
|
||||||
|
assert printer.file_system.selected_file is None
|
||||||
|
|
||||||
|
printer.write(b"M23 print.3mf\n")
|
||||||
|
printer.flush()
|
||||||
|
|
||||||
|
assert printer.file_system.selected_file is not None
|
||||||
|
assert printer.file_system.selected_file.file_name == "print.3mf"
|
||||||
|
|
||||||
|
printer.write(b"M24\n")
|
||||||
|
printer.flush()
|
||||||
|
|
||||||
|
result = printer.readlines()
|
||||||
|
assert result[0] == b"ok"
|
||||||
assert isinstance(printer.current_state, PrintingState)
|
assert isinstance(printer.current_state, PrintingState)
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user