def test_find_best_ambiguous(self): """ Test matching for similarly scored profiles """ edid = "office" edidhash = profile.md5(edid) connected_outputs = [ XrandrConnection("LVDS1", Display()), XrandrConnection("DP1", Display(["1920x1080"], edid=edid)) ] profile_outputs = [ Output("LVDS1", Viewport('1366x768'), True), Output("DP1", Viewport('1920x1080')) ] p1 = Profile("p1", profile_outputs, { "LVDS1": Rule(), "DP1": Rule(edidhash) }) p2 = Profile("p2", profile_outputs, { "LVDS1": Rule(), "DP1": Rule(edidhash) }) best = self.matcher.find_best([p1, p2], connected_outputs) self.assertEqual(p1, best)
def test_compose_mode_args(self): xrandr = Xrandr() xrandr.EXECUTABLE = "stub" outputs = [ Output("LVDS1", Geometry(1366, 768), primary=True), Output("DP1", Geometry(1920, 1080, 1366, 0)), Output("VGA1", Geometry(800, 600, 0, 768)) ] p = Profile("default", outputs) xrandr_connections = [XrandrOutput("HDMI1"), XrandrOutput("HDMI2")] command = xrandr.__compose_mode_args__(p, xrandr_connections) num_of_outputs = len(outputs) + len(xrandr_connections) self.assertEqual(num_of_outputs, command.count(xrandr.OUTPUT_KEY)) self.assertEqual(len(outputs), command.count(xrandr.POS_KEY)) self.assertEqual(len(outputs), command.count(xrandr.MODE_KEY)) self.assertEqual(len(xrandr_connections), command.count(xrandr.OFF_KEY)) self.assertEqual(1, command.count(xrandr.PRIMARY_KEY)) self.assertEqual(1, command.count("LVDS1")) self.assertEqual(1, command.count("DP1")) self.assertEqual(1, command.count("VGA1")) self.assertEqual(1, command.count("HDMI1")) self.assertEqual(1, command.count("HDMI2"))
def read_file(self, profile_file_descriptor): try: result = json.load(profile_file_descriptor) rules = result.get('match') priority = int(result.get('priority', 100)) if rules: for k, v in rules.items(): # backward compatibility for match.mode if v.get('mode'): logger.warn( "%s\n\tmatch.mode is deprecated" "\n\tConsider changing to 'supports' or 'prefers'", profile_file_descriptor.name) v['supports'] = v['mode'] del v['mode'] rules[k] = Rule(**v) else: rules = {} primary = result['primary'] outputs_raw = result['outputs'] outputs = [] for name, mode_raw in outputs_raw.items(): output = Output(name, **mode_raw) outputs.append(output) name = os.path.basename(profile_file_descriptor.name) return Profile(name, outputs, rules, primary, priority) except (KeyError, ValueError): raise InvalidProfileException(profile_file_descriptor.name)
def test_priority(self): outputs_default = [ XrandrConnection("LVDS1", Display()), ] outputs_office = [ XrandrConnection("LVDS1", Display()), XrandrConnection("HDMI1", Display(["1920x1080"], edid="office")) ] profiles = [ Profile("default", [Output("LVDS1", "1366x768")], {"LVDS1": Rule()}, priority=50), Profile("office", [Output("HDMI1", "1920x1080")], {"HDMI1": Rule()}, priority=100) # default priority ] best_default = self.matcher.find_best(profiles, outputs_default) best_office = self.matcher.find_best(profiles, outputs_office) self.assertEqual(profiles[0], best_default) self.assertEqual(profiles[1], best_office)
def profile_from_xrandr(self, xrandr_connections: list, name: str='profile'): outputs = [] rules = {} for c in xrandr_connections: if not c.connected or not c.is_active(): continue output = Output(c.name, c.current_geometry, c.primary) outputs.append(output) rule = Rule(md5(c.edid), c.preferred_mode, c.current_geometry.mode) rules[c.name] = rule logger.debug("Extracted %d outputs from %d xrandr connections", len(outputs), len(xrandr_connections)) return Profile(name, outputs, rules)
def write(self, p: Profile, yaml_flow_style: bool = False): """ Write profile to file into configured profile directory. Profile name becomes the name of the file. If name contains illegal characters, only safe part is used. For example, if name is my_home_vga/../../passwd, then file will be written as passwd under profile dir """ os.makedirs(self.write_location, exist_ok=True) dict = p.to_dict() safename = os.path.basename(p.name) fullname = os.path.join(self.write_location, safename) if safename != p.name: logger.warning("Illegal name provided. Writing as %s", fullname) with open(fullname, 'w+') as fp: yaml.dump(dict, fp, default_flow_style=yaml_flow_style)
def write(self, p: Profile, yaml_flow_style: bool=False): """ Write profile to file into configured profile directory. Profile name becomes the name of the file. If name contains illegal characters, only safe part is used. For example, if name is my_home_vga/../../passwd, then file will be written as passwd under profile dir """ os.makedirs(self.write_location, exist_ok=True) dict = p.to_dict() safename = os.path.basename(p.name) fullname = os.path.join(self.write_location, safename) if safename != p.name: logger.warning("Illegal name provided. Writing as %s", fullname) with open(fullname, 'w+') as fp: yaml.dump(dict, fp, default_flow_style=yaml_flow_style)
def profile_from_xrandr(self, xrandr_connections: list, name: str='profile'): outputs = [] rules = {} primary = None for c in xrandr_connections: display = c.display if not display or not c.is_active(): continue output = Output.fromconnection(c) if c.primary: primary = c.name outputs.append(output) rule = Rule(md5(display.edid), display.preferred_mode, display.mode) rules[c.name] = rule logger.debug("Extracted %d outputs from %d xrandr connections", len(outputs), len(xrandr_connections)) return Profile(name, outputs, rules, primary)
def test_compose_mode_args_exact_line(self): xrandr = Xrandr() xrandr.EXECUTABLE = "stub" outputs = [Output("LVDS1", mode='1366x768')] p = Profile("default", outputs, primary="LVDS1") xrandr_connections = [ XrandrConnection("LVDS1"), XrandrConnection("HDMI1") ] command = xrandr._compose_mode_args(p, xrandr_connections) self.assertListEqual([ '--output', 'LVDS1', '--mode', '1366x768', '--pos', '0x0', '--rotate', 'normal', '--panning', '0x0', '--scale', '1x1', '--primary', '--output', 'HDMI1', '--off' ], command)
def test_compose_mode_args(self): xrandr = Xrandr(":0", None) xrandr.EXECUTABLE = "stub" outputs = { "LVDS1": Output(mode='1366x768'), "DP1": Output(mode='1920x1080', pos='1366x0', scale='1.5x1.5', panning='1920x1080'), "VGA1": Output(mode='800x600', pos='0x768') } p = Profile("default", outputs, primary="LVDS1") xrandr_connections = [ XrandrConnection("HDMI1"), XrandrConnection("HDMI2") ] command = xrandr._compose_mode_args(p, xrandr_connections) num_of_outputs = len(outputs) + len(xrandr_connections) self.assertEqual(num_of_outputs, command.count(xrandr.OUTPUT_KEY)) self.assertEqual(len(outputs), command.count(xrandr.POS_KEY)) self.assertEqual(len(outputs), command.count(xrandr.MODE_KEY)) self.assertEqual(len(outputs), command.count(xrandr.PANNING_KEY)) self.assertEqual(len(outputs), command.count(xrandr.ROTATE_KEY)) self.assertEqual(len(outputs), command.count(xrandr.SCALE_KEY)) self.assertEqual(len(xrandr_connections), command.count(xrandr.OFF_KEY)) self.assertEqual(1, command.count(xrandr.PRIMARY_KEY)) self.assertEqual(1, command.count("LVDS1")) self.assertEqual(1, command.count("DP1")) self.assertEqual(1, command.count("VGA1")) self.assertEqual(1, command.count("HDMI1")) self.assertEqual(1, command.count("HDMI2"))
def profile_from_xrandr(self, xrandr_connections: list, profile_name: str = 'profile'): outputs = {} rules = {} primary = None for connection in xrandr_connections: output_name = connection.name display = connection.display if not display or not connection.is_active(): continue output = Output.fromconnection(connection) if connection.primary: primary = output_name outputs[output_name] = output rule = Rule(hash(display.edid), display.preferred_mode, display.mode) rules[output_name] = rule logger.debug("Extracted %d outputs from %d xrandr connections", len(outputs), len(xrandr_connections)) return Profile(profile_name, outputs, rules, primary)
def profile(name: str, match: dict = None, prio: int = 100): # we do not care about actual outputs in these tests, only rules matters return Profile(name, {}, match, priority=prio)
def print(self, p: Profile, yaml_flow_style: bool=False): print(yaml.dump(p.to_dict(), default_flow_style=yaml_flow_style))
def print(self, p: Profile, yaml_flow_style: bool = False): print(yaml.dump(p.to_dict(), default_flow_style=yaml_flow_style))
def test_profile_from_dict(self): # given data = [ ( Profile("no_rules", {"lvds1": Output("800x600")}, priority=100), { 'name': 'no_rules', 'outputs': { 'lvds1': { 'mode': '800x600', 'pos': '0x0', 'rotate': 'normal', 'panning': '0x0', 'scale': '1x1', } }, 'priority': 100 } ), ( Profile( name="with_rules", outputs={ "lvds1": Output("800x600", rate="60"), "vga1": Output("1024x768", pos="800x0", rate="75") }, match={ "lvds1": Rule("edid", "800x600", "800x600") }, primary="lvds1", priority=100 ), { 'name': 'with_rules', 'match': { 'lvds1': { 'edid': 'edid', 'supports': '800x600', 'prefers': '800x600' } }, 'outputs': { 'lvds1': { 'mode': '800x600', 'pos': '0x0', 'rotate': 'normal', 'panning': '0x0', 'scale': '1x1', 'rate': '60' }, 'vga1': { 'mode': '1024x768', 'pos': '800x0', 'rotate': 'normal', 'panning': '0x0', 'scale': '1x1', 'rate': 75 } }, 'primary': 'lvds1', 'priority': 100 } ) ] for expected_profile, dict in data: # when p = Profile.from_dict(dict) # then self.assertEqual(expected_profile, p) self.assertDictEqual(dict, p.to_dict())
class Test_ProfileMatcher(TestCase): logging.basicConfig() matcher = ProfileMatcher() HOME_MD5 = hashlib.md5("home".encode()).hexdigest() OFFICE_MD5 = hashlib.md5("office".encode()).hexdigest() profiles = [ Profile("default", [Output("LVDS1", "1366x768")], {"LVDS1": Rule()}), Profile("DP1_1920x1080", [Output("LVDS1", "1366x768"), Output("DP1", "1920x1080")], { "LVDS1": Rule(), "DP1": Rule(None, None, "1920x1080") }), Profile("DP1_1920x1200", [Output("LVDS1", "1366x768"), Output("DP1", "1920x1200")], { "LVDS1": Rule(), "DP1": Rule(None, "1920x1200", None) }), Profile("home", [Output("LVDS1", "1366x768"), Output("DP1", "1920x1080")], { "LVDS1": Rule(), "DP1": Rule(HOME_MD5) }), Profile("no_rule", [Output("LVDS1", "800x600")]), Profile("office", [Output("LVDS1", "1366x768"), Output("HDMI1", "1920x1080")], { "LVDS1": Rule(), "HDMI1": Rule(OFFICE_MD5) }) ] def test_find_best_default(self): outputs = [XrandrConnection("LVDS1", Display())] best = self.matcher.find_best(self.profiles, outputs) self.assertEqual(self.profiles[0], best) def test_find_best_no_match(self): outputs = [ XrandrConnection("LVDS1", Display()), XrandrConnection("DP1", Display(["1280x1024"], edid="guest")) ] best = self.matcher.find_best(self.profiles, outputs) self.assertIsNone(best) def test_find_best_edid_over_mode(self): outputs = [ XrandrConnection("LVDS1", Display()), XrandrConnection("DP1", Display(["1920x1080"], edid="home")) ] best = self.matcher.find_best(self.profiles, outputs) self.assertEqual(self.profiles[3], best) def test_find_best_prefers_over_supports(self): outputs = [ XrandrConnection("LVDS1", Display()), XrandrConnection( "DP1", Display(["1920x1080", "1920x1200"], "1920x1200", edid="office")) ] best = self.matcher.find_best(self.profiles, outputs) self.assertEqual(self.profiles[2], best) def test_find_best_mode(self): outputs = [ XrandrConnection("LVDS1", Display()), XrandrConnection("DP1", Display(["1920x1080"], edid="office")) ] best = self.matcher.find_best(self.profiles, outputs) self.assertEqual(self.profiles[1], best) def test_find_best_ambiguous(self): """ Test matching for similarly scored profiles """ edid = "office" edidhash = profile.md5(edid) connected_outputs = [ XrandrConnection("LVDS1", Display()), XrandrConnection("DP1", Display(["1920x1080"], edid=edid)) ] profile_outputs = [ Output("LVDS1", Viewport('1366x768'), True), Output("DP1", Viewport('1920x1080')) ] p1 = Profile("p1", profile_outputs, { "LVDS1": Rule(), "DP1": Rule(edidhash) }) p2 = Profile("p2", profile_outputs, { "LVDS1": Rule(), "DP1": Rule(edidhash) }) best = self.matcher.find_best([p1, p2], connected_outputs) self.assertEqual(p1, best)
def test_profile_from_dict(self): # given data = [(Profile("no_rules", {"lvds1": Output("800x600")}, priority=100), { 'name': 'no_rules', 'outputs': { 'lvds1': { 'mode': '800x600', 'pos': '0x0', 'rotate': 'normal', 'panning': '0x0', 'scale': '1x1', } }, 'priority': 100 }), (Profile(name="with_rules", outputs={ "lvds1": Output("800x600", rate="60"), "vga1": Output("1024x768", pos="800x0", rate="75") }, match={"lvds1": Rule("edid", "800x600", "800x600")}, primary="lvds1", priority=100), { 'name': 'with_rules', 'match': { 'lvds1': { 'edid': 'edid', 'supports': '800x600', 'prefers': '800x600' } }, 'outputs': { 'lvds1': { 'mode': '800x600', 'pos': '0x0', 'rotate': 'normal', 'panning': '0x0', 'scale': '1x1', 'rate': '60' }, 'vga1': { 'mode': '1024x768', 'pos': '800x0', 'rotate': 'normal', 'panning': '0x0', 'scale': '1x1', 'rate': 75 } }, 'primary': 'lvds1', 'priority': 100 })] for expected_profile, dict in data: # when p = Profile.from_dict(dict) # then self.assertEqual(expected_profile, p) self.assertDictEqual(dict, p.to_dict())