def test_connect_to(self): def f(**kwargs): fd(kwargs) def fd(d): opts = AdHocStruct() try: #silence errors since we're expecting them: from xpra.scripts import main as xpra_main try: saved_timeout = xpra_main.CONNECT_TIMEOUT xpra_main.CONNECT_TIMEOUT = 5 saved_werr = xpra_main.werr xpra_main.werr = main.noop conn = connect_to(d, opts) finally: xpra_main.werr = saved_werr xpra_main.CONNECT_TIMEOUT = saved_timeout except Exception: #from xpra.util import get_util_logger #get_util_logger().error("connect_to(%s, %s)", d, opts, exc_info=True) pass else: try: conn.close() except Exception: pass raise Exception("connect_to(%s) should have failed" % (d, )) #without extra arguments to specify the endpoint, #all connections should fail, even if they have a valid type: f(type="invalid", display_name="test") f(type="vsock", display_name="test", vsock=(10, 1000)) fd({ "type": "named-pipe", "display_name": "test", "named-pipe": "TEST-INVALID" }) f(type="unix-domain", display_name=":100000", display="100000") for socktype in ( "tcp", "ssl", "ws", "wss", ): f(type=socktype, display_name="test", host="localhost", port=100000) for paramiko in (True, False): f(type="ssh", display_name="test", host="localhost", port=100000, is_paramiko=paramiko) fd({ "type": "ssl", "display_name": "test", "host": "localhost", "port": 100000, "strict-host-check": False, }) #udp never fails when opening the connection: conn = connect_to( { "type": "udp", "host": "localhost", "port": 20000, "display_name": ":200" }, AdHocStruct()) conn.close()
def test_parse_display_name(self): opts = AdHocStruct() opts.socket_dirs = ["/tmp"] opts.socket_dir = "/tmp" opts.exit_ssh = False opts.ssh = "ssh -v " opts.remote_xpra = "run-xpra" if WIN32: fd = parse_display_name(None, opts, "named-pipe://FOO")["named-pipe"] sd = parse_display_name(None, opts, "FOO")["named-pipe"] else: fd = parse_display_name(None, opts, "socket:///FOO") sd = parse_display_name(None, opts, "/FOO") assert sd == fd, "expected %s but got %s" % (fd, sd) def t(s, e): r = parse_display_name(None, opts, s) if e: for k, v in e.items(): actual = r.get(k) assert actual == v, "expected %s but got %s from parse_display_name(%s)=%s" % ( v, actual, s, r) def e(s): try: parse_display_name(None, opts, s) except Exception: pass else: raise Exception("parse_display_name should fail for %s" % s) if POSIX: e("ZZZZZZ") t("10", { "display_name": "10", "local": True, "type": "unix-domain" }) t("/tmp/thesocket", {"display_name": "socket:///tmp/thesocket"}) t("socket:/tmp/thesocket", {"display_name": "socket:/tmp/thesocket"}) e("tcp://*****:*****@host/", {"username": "******", "password": None}) for socktype in ("tcp", "udp", "ws", "wss", "ssl", "ssh"): #e(socktype+"://a/b/c/d") t( socktype + "://username:password@host:10000/DISPLAY?key1=value1", { "type": socktype, "display": "DISPLAY", "key1": "value1", "username": "******", "password": "******", "port": 10000, "host": "host", "local": False, }) t("tcp://fe80::c1:ac45:7351:ea69:14500", { "host": "fe80::c1:ac45:7351:ea69", "port": 14500 }) t("tcp://fe80::c1:ac45:7351:ea69%eth1:14500", { "host": "fe80::c1:ac45:7351:ea69%eth1", "port": 14500 }) t("tcp://[fe80::c1:ac45:7351:ea69]:14500", { "host": "fe80::c1:ac45:7351:ea69", "port": 14500 }) t("tcp://host/100,key1=value1", {"key1": "value1"}) t("tcp://host/key1=value1", {"key1": "value1"}) try: from xpra.net.vsock import CID_ANY, PORT_ANY #@UnresolvedImport t("vsock://any:any/", {"vsock": (CID_ANY, PORT_ANY)}) t("vsock://10:2000/", {"vsock": (10, 2000)}) except ImportError: pass
def test_webcam(self): if not POSIX or OSX: get_util_logger().info("webcam test skipped: %s not supported yet", sys.platform) return from xpra.platform.xposix.webcam import get_virtual_video_devices, check_virtual_dir if not check_virtual_dir(): get_util_logger().info( "webcam test skipped: no virtual video device directory") return devices = get_virtual_video_devices() if not devices: get_util_logger().info( "webcam test skipped: no virtual video devices found") return from xpra.server.source.webcam_mixin import WebcamMixin server = AdHocStruct() wm = WebcamMixin() server.webcam_enabled = True server.webcam_device = None server.webcam_encodings = ["png", "jpeg"] wm.init_from(None, server) wm.init_state() wm.hello_sent = True packets = [] def send(*args): packets.append(args) #wm.send = send wm.send_async = send try: assert wm.get_info() device_id = 0 w, h = 640, 480 assert wm.start_virtual_webcam(device_id, w, h) assert wm.get_info().get("webcam", {}).get("active-devices", 0) == 1 assert len(packets) == 1 #ack sent assert packets[0][0] == "webcam-ack" frame_no = 0 from PIL import Image image = Image.new('RGB', size=(w, h), color=(155, 0, 0)) buf = BytesIO() image.save(buf, "png") data = buf.getvalue() buf.close() assert wm.process_webcam_frame(device_id, frame_no, "png", w, h, data) assert len(packets) == 2 #ack sent assert packets[1][0] == "webcam-ack" #now send a jpeg as png, #which should fail and stop: buf = BytesIO() image.save(buf, "jpeg") data = buf.getvalue() buf.close() #suspend error logging to avoid the scary message: from xpra.server.source.webcam_mixin import log as webcam_log elog = webcam_log.error try: webcam_log.error = webcam_log.debug assert not wm.process_webcam_frame(device_id, frame_no, "png", w, h, data) finally: #restore it: webcam_log.error = elog assert len(packets) == 3 assert packets[2][0] == "webcam-stop" finally: wm.cleanup()
def test_find_session_by_name(self): opts = AdHocStruct() opts.socket_dirs = ["/tmp"] opts.socket_dir = "/tmp" assert find_session_by_name(opts, "not-a-valid-session") is None
def test_xsettings(self): from xpra.x11.xsettings_prop import ( get_settings, set_settings, get_local_byteorder, XSettingsTypeInteger, XSettingsTypeString, XSettingsTypeColor, log, ) #silence warnings: log.error = log.warn = log.debug disp = AdHocStruct() for DEBUG_XSETTINGS in (True, False): with OSEnvContext(): os.environ["XPRA_XSETTINGS_DEBUG"] = str(int(DEBUG_XSETTINGS)) serial = 1 data = b"" l = len(data) v = struct.pack(b"=BBBBII", get_local_byteorder(), 0, 0, 0, serial, l) + data + b"\0" v1 = get_settings(disp, v) assert v #get from cache: v2 = get_settings(disp, v) assert v1 == v2 #test all types, set then get: #setting_type, prop_name, value, last_change_serial = setting settings = ( (XSettingsTypeInteger, "int1", 1, 0), (XSettingsTypeString, "str1", "1", 0), (XSettingsTypeColor, "color1", (128, 128, 64, 32), 0), ) serial = 2 data = set_settings(disp, (serial, settings)) assert data #parse it back: v = get_settings(disp, data) rserial, rsettings = v assert rserial == serial assert len(rsettings) == len(settings) #test error handling: for settings in ( ( #invalid color causes exception (XSettingsTypeColor, "bad-color", (128, ), 0), ), ( #invalid setting type is skipped with an error message: (255, "invalid-setting-type", 0, 0), ), ): serial = 3 data = set_settings(disp, (serial, settings)) assert data v = get_settings(disp, data) rserial, rsettings = v assert rserial == serial assert len(rsettings) == 0 #parsing an invalid data type (9) should fail: hexdata = b"000000000200000001000000090004007374723100000000010000003100000000" data = binascii.unhexlify(hexdata) v = get_settings(disp, data) rserial, rsettings = v assert len(rsettings) == 0
def SetWorkarea(self, x, y, w, h): workarea = AdHocStruct() workarea.x, workarea.y, workarea.width, workarea.height = ni(x), ni(y), ni(w), ni(h) self.server.set_workarea(workarea)
def do_test_command_server(self): from xpra.server.mixins.child_command_server import ChildCommandServer, log opts = AdHocStruct() opts.exit_with_children = True opts.terminate_children = True opts.start_new_commands = True opts.start = [] opts.start_child = [] opts.start_after_connect = [] opts.start_child_after_connect = [] opts.start_on_connect = [] opts.start_child_on_connect = [] opts.start_on_last_client_exit = [] opts.start_child_on_last_client_exit = [] opts.exec_wrapper = None opts.start_env = [] opts.source_start = [] #pynotify can cause crashes, #probably due to threading issues? def noop(): pass def _ChildCommandServer(): ccs = ChildCommandServer() ccs.setup_menu_watcher = noop return ccs self._test_mixin_class(_ChildCommandServer, opts) if not POSIX: return #test creating a temp file: import tempfile tmpfile = os.path.join(tempfile.gettempdir(), "xpra-test-start-command-%s" % os.getpid()) assert not os.path.exists(tmpfile) command = (b"touch", tmpfile.encode("utf8")) self.handle_packet(("start-command", b"test", command, True)) time.sleep(1) info = self.mixin.get_info(self.protocol) commands = info.get("commands") assert commands proc_info = commands.get(0) assert proc_info pid = proc_info.get("pid") assert pid assert os.path.exists(tmpfile) os.unlink(tmpfile) #test signals: self.handle_packet(("start-command", b"sleep", b"sleep 10", True)) time.sleep(1) info = self.mixin.get_info(self.protocol) commands = info.get("commands") assert commands proc_info = commands.get(1) assert proc_info pid = proc_info.get("pid") assert pid assert proc_info.get("name")=="sleep" assert proc_info.get("dead") is False #send it a SIGINT: with silence_info(log): self.handle_packet(("command-signal", pid, "SIGINT")) time.sleep(1) self.mixin.child_reaper.poll() info = self.mixin.get_info(self.protocol) commands = info.get("commands") assert commands proc_info = commands.get(1) assert proc_info.get("dead") is True import signal assert proc_info.get("returncode") == -signal.SIGINT
def test_invalid(self): l = LoggingServer() opts = AdHocStruct() opts.remote_logging = "on" l.init(opts) l._process_logging(None, None)
def test_mmap_path(self): opts = AdHocStruct() opts.mmap = "/tmp/mmap-test-file" self._test_mmap(opts)
def test_mmap(self): from xpra.server.mixins.mmap_server import MMAP_Server opts = AdHocStruct() opts.mmap = "on" self._test_mixin_class(MMAP_Server, opts) assert self.mixin.get_info().get("mmap", {}).get("supported") is True
def test_mmap_on(self): opts = AdHocStruct() opts.mmap = "on" self._test_mmap(opts)
def test_encoding(self): opts = AdHocStruct() opts.encoding = "" opts.encodings = ["rgb", "png", "jpeg"] opts.quality = 1 opts.min_quality = 20 opts.speed = 0 opts.min_speed = 20 opts.video_scaling = "no" opts.video_decoders = [] opts.csc_modules = [] opts.video_encoders = [] m = self._test_mixin_class( encodings.Encodings, opts, { "encodings": ["rgb"], "encodings.core": ["rgb32", "rgb24", "png"], "encodings.problematic": [], "encoding": "" }) m.set_encoding("auto") def f(fn, err): try: fn() except Exception: pass else: raise Exception(err) def set_invalid_encoding(): m.set_encoding("invalid") f(set_invalid_encoding, "should not be able to set encoding 'invalid'") #this will trigger a warning: with silence_error(encodings): m.set_encoding("jpeg") #quality: for q in (-1, 0, 1, 99, 100): m.quality = q m.send_quality() for q in (-2, 101): m.quality = q f(m.send_quality, "should not be able to send invalid quality %i" % q) #min-quality: for q in (-1, 0, 1, 99, 100): m.min_quality = q m.send_min_quality() for q in (-2, 101): m.min_quality = q f(m.send_min_quality, "should not be able to send invalid min-quality %i" % q) #speed: for s in (-1, 0, 1, 99, 100): m.speed = s m.send_speed() for s in (-2, 101): m.speed = s f(m.send_speed, "should not be able to send invalid speed %i" % s) #min-speed: for s in (-1, 0, 1, 99, 100): m.min_speed = s m.send_min_speed() for s in (-2, 101): m.min_speed = s f(m.send_min_speed, "should not be able to send invalid min-speed %i" % s)
def test_pipeline_score(self): MINW = 32 MINH = 32 MAXW = 3840 MAXH = 2160 encoder_spec = AdHocStruct() encoder_spec.width_mask = 0xfffe encoder_spec.height_mask = 0xfffe encoder_spec.quality = 100 encoder_spec.speed = 100 encoder_spec.size_efficiency = 50 encoder_spec.min_w = MINW encoder_spec.max_w = MAXW encoder_spec.min_h = MINH encoder_spec.max_h = MAXH encoder_spec.setup_cost = 10 encoder_spec.score_boost = 0 encoder_spec.gpu_cost = 0 encoder_spec.cpu_cost = 10 encoder_spec.codec_type = "test codec" test_csc_spec = AdHocStruct() test_csc_spec.width_mask = 0xffff test_csc_spec.height_mask = 0xffff test_csc_spec.score_boost = 0 test_csc_spec.quality = 10 test_csc_spec.speed = 20 test_csc_spec.setup_cost = 10 test_csc_spec.get_runtime_factor = lambda: 10 test_csc_spec.codec_class = AdHocStruct current_csc = AdHocStruct() current_csc.get_dst_format = lambda: "BGRA" current_csc.get_src_height = lambda: 1080 current_csc.get_src_width = lambda: 1920 for rgb_format in ("BGRA", "RGB"): for csc_spec in (None, test_csc_spec): for can_scale in (True, False): test_csc_spec.can_scale = can_scale encoder_spec.can_scale = can_scale for has_lossless_mode in (True, False): encoder_spec.has_lossless_mode = has_lossless_mode for scaling in ((1, 1), (2, 3)): #too small: for w, h in ((MINW - 1, MINH + 1), (MINW + 1, MINH - 1)): s = get_pipeline_score(rgb_format, csc_spec, encoder_spec, w, h, scaling, 100, 10, 100, 10, None, None, 0, 10, True) assert s is None s = get_pipeline_score(rgb_format, csc_spec, encoder_spec, 1920, 1080, scaling, 100, 10, 100, 10, current_csc, None, 0, 10, True) if can_scale is False and scaling != (1, 1): assert s is None continue #mask will round down, so this should be OK: s = get_pipeline_score(rgb_format, csc_spec, encoder_spec, MAXW + 1, MAXH + 1, scaling, 100, 10, 100, 10, None, None, 0, 10, True) assert s if scaling == (1, 1): #but this is not: s = get_pipeline_score(rgb_format, csc_spec, encoder_spec, MAXW + 2, MAXH + 2, scaling, 100, 10, 100, 10, None, None, 0, 10, True) assert s is None
def test_invalid(self): l = LoggingServer() opts = AdHocStruct() opts.remote_logging = "on" l.init(opts) l._process_logging(None, None) #pylint: disable=protected-access
def main(): # pragma: no cover from xpra.platform import program_context from xpra.platform.gui import ready as gui_ready, init as gui_init gui_init() with program_context("Start-New-Command", "Start New Command"): #logging init: if "-v" in sys.argv: enable_debug_for("util") client = AdHocStruct() client.server_last_info_time = monotonic() commands_info = { 0: { 'returncode': None, 'name': 'xterm', 'pid': 542, 'dead': False, 'ignore': True, 'command': ('xterm', ), 'forget': False }, 'start-child': (), 'start-new': True, 'start-after-connect-done': True, 'start': ('xterm', ), 'start-after-connect': (), 'start-child-on-connect': (), 'exit-with-children': False, 'start-child-after-connect': (), 'start-on-connect': (), } client.server_last_info = {"commands": commands_info} client.server_start_new_commands = True client.server_commands_signals = ("SIGINT", "SIGTERM", "SIGUSR1") def nosend(*_args): """ this is for testing only - we are not connected to a server """ client.send_info_request = nosend client.send = nosend window1 = AdHocStruct() window1._metadata = {"pid": 542} #pylint: disable=protected-access client._id_to_window = { #pylint: disable=protected-access 1: window1 } def show_start_new_command(*_args): from xpra.client.gtk_base.start_new_command import getStartNewCommand getStartNewCommand(None).show() client.show_start_new_command = show_start_new_command app = ServerCommandsWindow(client) app.close = app.quit register_os_signals(app.quit) try: gui_ready() app.show() app.run() except KeyboardInterrupt: pass return 0
def test_networkstate(self): with OSEnvContext(): os.environ["XPRA_PING_TIMEOUT"] = "1" from xpra.server.mixins.networkstate_server import NetworkStateServer, MAX_BANDWIDTH_LIMIT, log, bandwidthlog from xpra.server.source.networkstate_mixin import NetworkStateMixin assert NetworkStateMixin.is_needed(typedict()) opts = AdHocStruct() opts.pings = 1 opts.bandwidth_limit = "1Gbps" #the limit for all clients: capped_at = 1 * 1000 * 1000 * 1000 #=="1Gbps" with silence_info(log): self._test_mixin_class(NetworkStateServer, opts, {}, NetworkStateMixin) self.assertEqual(capped_at, self.mixin.get_info().get("bandwidth-limit")) self.handle_packet(("ping", 10)) self.handle_packet(("ping", -1000)) self.handle_packet(("ping_echo", 10, 500, 500, 600, 10)) for v in (None, "foo", 1, 2.0, [], (), set()): try: self.handle_packet(("connection-data", v)) except TypeError: pass else: raise Exception( "should not allow %s (%s) as connection-data" % (v, type(v))) self.handle_packet(("connection-data", {})) for v in (None, "foo", 2.0, [], (), set()): try: self.handle_packet(("bandwidth-limit", v)) except TypeError: pass else: raise Exception( "should not allow %s (%s) as connection-data" % (v, type(v))) with silence_info(bandwidthlog): self.handle_packet(("bandwidth-limit", 10 * 1024 * 1024)) def get_limit(): return self.source.get_info().get("bandwidth-limit", {}).get("setting", 0) self.assertEqual(10 * 1024 * 1024, get_limit()) with silence_info(bandwidthlog): self.handle_packet( ("bandwidth-limit", MAX_BANDWIDTH_LIMIT + 1)) self.assertEqual(min(capped_at, MAX_BANDWIDTH_LIMIT), get_limit()) #test source: timeouts = [] def timeout(*args): timeouts.append(args) self.source.disconnect = timeout assert self.source.get_caps() self.source.ping() self.source.check_ping_echo_timeout(0, 0) #give time for the timeout to fire: self.glib.timeout_add(2000, self.main_loop.quit) self.main_loop.run()
def test_mixin(self): opts = AdHocStruct() self._test_mixin_class(StubClientMixin, opts, {})
def main(): from xpra.platform import program_context from xpra.platform.gui import ready as gui_ready with program_context("Start-New-Command", "Start New Command"): #logging init: if "-v" in sys.argv: enable_debug_for("util") from xpra.os_util import SIGNAMES from xpra.gtk_common.quit import gtk_main_quit_on_fatal_exceptions_enable gtk_main_quit_on_fatal_exceptions_enable() client = AdHocStruct() client.server_last_info_time = monotonic_time() commands_info = { 0: { 'returncode': None, 'name': 'xterm', 'pid': 542, 'dead': False, 'ignore': True, 'command': ('xterm', ), 'forget': False }, 'start-child': (), 'start-new': True, 'start-after-connect-done': True, 'start': ('xterm', ), 'start-after-connect': (), 'start-child-on-connect': (), 'exit-with-children': False, 'start-child-after-connect': (), 'start-on-connect': (), } client.server_last_info = {"commands": commands_info} client.server_start_new_commands = True client.server_commands_signals = ("SIGINT", "SIGTERM", "SIGUSR1") def noop(*_args): pass client.send_info_request = noop client.send = noop window1 = AdHocStruct() window1._metadata = {"pid": 542} client._id_to_window = {1: window1} def show_start_new_command(*_args): from xpra.client.gtk_base.start_new_command import getStartNewCommand getStartNewCommand(None).show() client.show_start_new_command = show_start_new_command app = ServerCommandsWindow(client) app.hide = app.quit def app_signal(signum, _frame): print("") log.info("got signal %s", SIGNAMES.get(signum, signum)) app.quit() signal.signal(signal.SIGINT, app_signal) signal.signal(signal.SIGTERM, app_signal) try: gui_ready() app.show() app.run() except KeyboardInterrupt: pass return 0
def test_mmap_path(self): opts = AdHocStruct() opts.mmap = tempfile.gettempdir() + "/mmap-test-file" self._test_mmap(opts)