async def full_server(base_server: Server) -> AsyncIterator[Server]: base_server.load_components() ret = base_server.server_init(start_server=False) await asyncio.wait_for(ret, 4.) yield base_server if base_server.event_loop.aioloop.is_running(): await base_server._stop_server(exit_reason="terminate")
async def test_send_async_event(full_server: Server): evtloop = full_server.get_event_loop() fut = evtloop.create_future() async def test_func(arg): fut.set_result(arg) full_server.register_event_handler("test:my_test", test_func) full_server.send_event("test:my_test", "test") result = await fut assert result == "test"
async def test_klippy_shutdown(ready_server: Server, klippy: KlippyProcess): evtloop = ready_server.get_event_loop() fut = evtloop.create_future() def on_shutdown(): if not fut.done(): fut.set_result("shutdown") ready_server.register_event_handler("server:klippy_shutdown", on_shutdown) klippy.send_gcode("M112") await asyncio.wait_for(fut, 2.) assert fut.result() == "shutdown"
async def test_gcode_response(ready_server: Server, klippy: KlippyProcess): evtloop = ready_server.get_event_loop() fut = evtloop.create_future() def on_gc_resp(resp: str): if not fut.done(): fut.set_result(resp) ready_server.register_event_handler("server:gcode_response", on_gc_resp) klippy.send_gcode("M118 Moonraker Test") await asyncio.wait_for(fut, 1.) assert "Moonraker Test" in fut.result()
async def test_klippy_reconnect(ready_server: Server, klippy: KlippyProcess): evtloop = ready_server.get_event_loop() futs = [evtloop.create_future() for _ in range(2)] events = { "server:klippy_disconnect": lambda: futs[0].set_result("disconnect"), "server:klippy_ready": lambda: futs[1].set_result("ready") } for name, func in events.items(): ready_server.register_event_handler(name, func) klippy.restart() ret = await asyncio.wait_for(asyncio.gather(*futs), 6.) assert ret == ["disconnect", "ready"]
async def test_notification(self, base_server: Server): base_server.register_notification("test:test_event") fut = base_server.event_loop.create_future() wsm = base_server.lookup_component("websockets") wsm.websockets[1] = MockWebsocket(fut) base_server.send_event("test:test_event", "test") ret = await fut expected = { 'jsonrpc': "2.0", 'method': "notify_test_event", 'params': ["test"] } assert expected == ret
async def test_klippy_startup(full_server: Server): evtloop = full_server.get_event_loop() futs = [evtloop.create_future() for _ in range(3)] events = { "server:klippy_identified": lambda: futs[0].set_result("id"), "server:klippy_started": lambda x: futs[1].set_result("started"), "server:klippy_ready": lambda: futs[2].set_result("ready") } for name, func in events.items(): full_server.register_event_handler(name, func) await full_server.start_server() ret = await asyncio.wait_for(asyncio.gather(*futs), 4.) assert (ret == ["id", "started", "ready"] and full_server.klippy_connection.is_connected())
async def test_call_remote_method(base_server: Server, klippy: KlippyProcess): fut = base_server.get_event_loop().create_future() def method_test(result): fut.set_result(result) base_server.register_remote_method("moonraker_test", method_test) base_server.load_components() await base_server.server_init() ret = base_server.klippy_connection.wait_connected() await asyncio.wait_for(ret, 4.) klippy.send_gcode("TEST_REMOTE_METHOD") await fut await base_server._stop_server("terminate") assert fut.result() == "test"
async def test_status_update(ready_server: Server, klippy: KlippyProcess): evtloop = ready_server.get_event_loop() fut = evtloop.create_future() def on_status_update(data): if not fut.done(): fut.set_result(data) ready_server.register_event_handler("server:status_update", on_status_update) kapis = ready_server.klippy_connection.klippy_apis await kapis.subscribe_objects({"toolhead": None}) klippy.send_gcode("G28") await asyncio.wait_for(fut, 2.) assert isinstance(fut.result(), dict)
def __init__( self, server: Server, dest_path: Optional[StrOrPath], download_size: int, progress_callback: Optional[Callable[[int, int, int], None]]) -> None: self.server = server self.event_loop = server.get_event_loop() self.need_content_length: bool = True self.need_content_disposition: bool = False self.request_ok: bool = False if dest_path is None: # If no destination is provided initialize to a procedurally # generated temp file. We will attempt to extract the filename # from the Content-Disposition Header tmp_dir = tempfile.gettempdir() loop_time = int(self.event_loop.get_loop_time()) tmp_fname = f"moonraker.download-{loop_time}.mrd" self.dest_file = pathlib.Path(tmp_dir).joinpath(tmp_fname) self.need_content_disposition = True elif isinstance(dest_path, str): self.dest_file = pathlib.Path(dest_path) else: self.dest_file = dest_path self.filename = self.dest_file.name self.file_hdl: Optional[BufferedWriter] = None self.total_recd: int = 0 self.download_size: int = download_size self.pct_done: int = 0 self.chunk_buffer: List[bytes] = [] self.progress_callback = progress_callback self.busy_evt: asyncio.Event = asyncio.Event() self.busy_evt.set()
def test_app_args(self, path_args: Dict[str, pathlib.Path], base_server: Server): args = { 'config_file': str(path_args['moonraker.conf']), 'log_file': str(path_args.get("moonlog", "")), 'software_version': "moonraker-pytest" } assert base_server.get_app_args() == args
def test_host_info(self, base_server: Server): hinfo = { 'hostname': socket.gethostname(), 'address': "0.0.0.0", 'port': 7010, 'ssl_port': 7011 } assert base_server.get_host_info() == hinfo
def test_invalid_config(path_args: Dict[str, pathlib.Path]): evtloop = EventLoop() args = { 'config_file': str(path_args['moonraker.conf']), 'log_file': "", 'software_version': "moonraker-pytest" } with pytest.raises(ConfigError): Server(args, None, evtloop)
async def test_init_error(base_server: Server): base_server.server_running = True kconn = base_server.klippy_connection def mock_is_connected(): return kconn.init_attempts < 3 kconn.is_connected = mock_is_connected ret = await kconn._init_klippy_connection() assert ret is False
async def test_no_uds(base_server: Server): attempts = [1, 2, 3] def mock_is_running(): attempts.pop(0) return len(attempts) > 0 base_server.is_running = mock_is_running ret = await base_server.klippy_connection._do_connect() assert ret is False
def __init__(self, server: Server) -> None: self.server = server self.klippy: Klippy = server.lookup_component("klippy_connection") self.websockets: Dict[int, WebSocket] = {} self.rpc = JsonRPC() self.closed_event: Optional[asyncio.Event] = None self.rpc.register_method("server.websocket.id", self._handle_id_request) self.rpc.register_method("server.connection.identify", self._handle_identify)
def test_config_and_log_warnings(path_args: Dict[str, pathlib.Path]): evtloop = EventLoop() args = { 'config_file': str(path_args['moonraker.conf']), 'log_file': "", 'software_version': "moonraker-pytest", 'log_warning': "Log Warning Test", 'config_warning': "Config Warning Test" } expected = ["Log Warning Test", "Config Warning Test"] server = Server(args, None, evtloop) assert server.warnings == expected
async def test_no_uds_access(base_server: Server, path_args: Dict[str, pathlib.Path]): attempts = [1, 2, 3] uds_path = path_args['klippy_uds_path'] uds_path.write_text("test") uds_path.chmod(mode=222) def mock_is_running(): attempts.pop(0) return len(attempts) > 0 base_server.is_running = mock_is_running ret = await base_server.klippy_connection._do_connect() assert ret is False
def base_server(path_args: Dict[str, pathlib.Path], event_loop: asyncio.AbstractEventLoop) -> Iterator[Server]: evtloop = EventLoop() args = { 'config_file': str(path_args['moonraker.conf']), 'log_file': str(path_args.get("moonraker.log", "")), 'software_version': "moonraker-pytest" } ql = logger = None if args["log_file"]: ql, logger, warning = utils.setup_logging(args) if warning: args["log_warning"] = warning yield Server(args, logger, evtloop) if ql is not None: ql.stop()
def from_web_request(cls, server: Server, web_request: WebRequest) -> WebCam: webcam: Dict[str, Any] = {} webcam["name"] = web_request.get_str("name") webcam["location"] = web_request.get_str("location", "printer") webcam["service"] = web_request.get_str("service", "mjpegstreamer") webcam["target_fps"] = web_request.get_int("target_fps", 15) webcam["stream_url"] = web_request.get_str("stream_url") webcam["snapshot_url"] = web_request.get_str("snapshot_url") webcam["flip_horizontal"] = web_request.get_boolean( "flip_horizontal", False) webcam["flip_vertical"] = web_request.get_boolean( "flip_vertical", False) webcam["rotation"] = web_request.get_str("rotation", 0) if webcam["rotation"] not in [0, 90, 180, 270]: raise server.error("Invalid value for parameter 'rotate'") webcam["source"] = "database" return cls(server, **webcam)
def test_pending_tasks(self, base_server: Server): loop = base_server.get_event_loop().aioloop assert len(asyncio.all_tasks(loop)) == 0
def test_running(self, server: Server): assert server.is_running() is True
def test_api_version(self, base_server: Server): ver = base_server.get_api_version() assert ver == API_VERSION
def test_signal_handler(base_server: Server, event_loop: asyncio.AbstractEventLoop): base_server._handle_term_signal() event_loop.run_forever() assert base_server.exit_reason == "terminate"
def test_running(self, base_server: Server): assert base_server.is_running() is False
def test_http_servers(self, server: Server): app = server.lookup_component("application") assert (app.http_server is not None and app.secure_server is not None)
async def test_register_remote_method_running(full_server: Server): await full_server.start_server(connect_to_klippy=False) with pytest.raises(ServerError): full_server.register_remote_method("moonraker_test", lambda: None)
async def test_component_init_error(base_server: Server): base_server.register_component("testcomp", MockComponent(err_init=True)) await base_server.server_init(False) assert "testcomp" in base_server.failed_components
def test_register_async_event(base_server: Server): async def test_func(): pass base_server.register_event_handler("test:my_test", test_func) assert base_server.events["test:my_test"] == [test_func]
async def test_component_close_error(base_server: Server, caplog: pytest.LogCaptureFixture): base_server.register_component("testcomp", MockComponent(err_close=True)) await base_server._stop_server("terminate") expected = "Error executing 'close()' for component: testcomp" assert expected in caplog.messages