Пример #1
0
    def run(self):
        self.logger.info("Typing '{}' into {}.".format(self.command,
                                                       self.machine.name))

        # Capture the screen before typing the command.
        self.machine.capture_vterm()

        self.machine.type(self.command)

        # Wait until the command is fully displayed on the screen.
        # That is needed to properly detect the newly displayed lines.
        # FIXME: this will not work for long commands spanning multiple lines
        for xxx in retries(timeout=60,
                           interval=2,
                           name="vterm-type",
                           message="Failed to type command"):
            self.machine.vterm = []
            self.machine.capture_vterm()
            lines = self.machine.vterm

            if len(lines) > 0:
                line = lines[0].strip()
                if line.endswith("_"):
                    line = line[0:-1]
                if line.endswith(self.command.strip()):
                    break

        self.machine.vterm = []
        self.machine.type('\n')

        # Read output of the command.
        # We wait until prompt reappears or we find some text that is not
        # supposed to be there.
        for xxx in retries(timeout=60,
                           interval=2,
                           name="vterm-run",
                           message="Failed to run command"):
            self.logger.debug("self.vterm = {}".format(self.machine.vterm))
            self.machine.capture_vterm()
            lines = self.machine.vterm
            self.logger.debug("Read lines {}".format(lines))
            self.machine.vterm = []
            if not self.ignore_abort:
                if self._grep('Cannot spawn', lines) or self._grep(
                        'Command failed', lines):
                    raise Exception('Failed to run command')
            if 'negassert' in self.args:
                if self._grep(self.args['negassert'], lines):
                    raise Exception('Found forbidden text {} ...'.format(
                        self.args['negassert']))
            if 'assert' in self.args:
                if self._grep(self.args['assert'], lines):
                    break
            if self._grep('# _', lines):
                if 'assert' in self.args:
                    raise Exception('Missing expected text {} ...'.format(
                        self.args['assert']))
                break
        self.logger.info("Command '{}' done.".format(self.command))
Пример #2
0
    def boot(self, **kwargs):
        self.monitor_file = self.get_temp('monitor')
        cmd = []
        for opt in QemuVMController.config[self.arch]:
            if opt == '{BOOT}':
                opt = self.boot_image
            elif opt == '{MEMORY}':
                opt = '{}'.format(self.memory)
            cmd.append(opt)
        if self.disk_image is not None:
            cmd.append('-drive')
            cmd.append('file={},index=0,media=disk,format=raw'.format(self.disk_image))
        if self.is_headless:
            cmd.append('-display')
            cmd.append('none')
        cmd.append('-monitor')
        cmd.append('unix:{},server,nowait'.format(self.monitor_file))
        for opt in self.extra_options:
            cmd.append(opt)
        self.logger.debug("Starting QEMU: {}".format(format_command(cmd)))

        self.proc = subprocess.Popen(cmd)
        self.monitor = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
        for xxx in retries(timeout=30, interval=2, name="ctl-socket", message="Failed to connect to QEMU control socket."):
            try:
                self.monitor.connect(self.monitor_file)
                break
            except FileNotFoundError:
                pass
            except ConnectionRefusedError:
                pass
            if self.proc.poll():
                raise Exception("QEMU not started, aborting.")

        self.booted = True
        self.logger.info("Machine started.")

        # Skip past GRUB
        self.type('\n')

        uspace_booted = False
        for xxx in retries(timeout=3*60, interval=5, name="vterm", message="Failed to boot into userspace"):
            self.vterm = []
            self.capture_vterm()
            for l in self.vterm:
                if l.find('to see a few survival tips') != -1:
                    uspace_booted = True
                    break
            if uspace_booted:
                break

        assert uspace_booted
        self.full_vterm = self.vterm

        self.logger.info("Machine booted into userspace.")

        return
Пример #3
0
    def capture_vterm_impl(self):
        try:
            os.remove(self.screendump_file)
        except IOError as e:
            pass
        try:
            os.remove(self.screenshot_filename)
        except IOError as e:
            pass
        self._xdotool_key('alt+s')
        screenshooter = subprocess.Popen([
            'import', '-display', self.x11_display, '-window', 'root',
            self.screenshot_filename
        ])
        screenshooter.wait()

        for xxx in retries(timeout=5,
                           interval=1,
                           name="xterm-dump",
                           message="Failed to read XTerm screendump"):
            try:
                with open(self.screendump_file, 'r') as f:
                    lines = [l.strip('\n') for l in f.readlines()]
                    if len(lines) != 24:
                        continue
                    self.logger.debug("Captured text:")
                    for l in lines:
                        self.logger.debug("| " + l)
                    return lines
            except IOError as e:
                pass
Пример #4
0
Файл: msim.py Проект: jermar/ci
    def boot(self, **kwargs):
        self.screenshot_filename = self.get_temp('screenshot.png')
        self.screendump_file = self.get_temp('xterm.screendump')
        config_file = self.get_temp('rewr.msim.conf')
        with open(config_file, 'w') as f:
            config_lines = self._rewrite_configuration()
            for l in config_lines:
                print(l, file=f)

        self._start_xserver()

        self.booted = True

        xterm_env = os.environ.copy()
        xterm_env['DISPLAY'] = self.x11_display
        self.xterm = subprocess.Popen([
            'xterm', '-xrm', 'XTerm*printAttributes: 0', '-xrm',
            'XTerm*printerCommand: cat - > "{}"'.format(
                self.screendump_file), '-xrm',
            'XTerm.VT100.translations: #override Meta <KeyPress> S: print() \n',
            '-e', 'msim -c ' + config_file
        ],
                                      env=xterm_env)

        time.sleep(2)

        if self.xterm.poll() is not None:
            self.screendump_file = None
            self.screenshot_filename = None
            raise Exception("Failed to start MSIM")

        self.logger.info("Machine started.")

        uspace_booted = False
        for xxx in retries(timeout=10 * 60,
                           interval=5,
                           name="vterm",
                           message="Failed to boot into userspace"):
            self.vterm = []
            self.full_vterm = []
            self.capture_vterm()
            for l in self.vterm:
                if l.find('to see a few survival tips') != -1:
                    uspace_booted = True
                    break
            if uspace_booted:
                break

        assert uspace_booted
        self.full_vterm = self.vterm

        self.logger.info("Machine booted into userspace.")

        return
Пример #5
0
    def capture_vterm_impl(self):
        screenshot_full = self.get_temp('screen-full.ppm')
        screenshot_term = self.get_temp('screen-term.png')
        screenshot_text = self.get_temp('screen-term.txt')

        try:
            os.remove(screenshot_full)
        except IOError as e:
            pass

        self._send_command('screendump ' + screenshot_full)

        for xxx in retries(timeout=10, interval=1, name="scrdump", message="Failed to capture screen"):
            try:
                self._run_command([
                    'convert',
                    screenshot_full,
                    '-crop', '640x480+4+24',
                    '+repage',
                    '-colors', '2',
                    '-monochrome',
                    screenshot_term
                ])
                break
            except:
                pass

        width, height = self._get_image_dimensions(screenshot_term)
        cols = width // 8
        rows = height // 16
        self._run_pipe([
            [
                'convert',
                screenshot_term,
                '-crop', '{}x{}'.format(cols * 8, rows * 16),
                '+repage',
                '-crop', '8x16',
                '+repage',
                '+adjoin',
                'txt:-',
            ],
            [
                'sed',
                '-e', 's|[0-9]*,[0-9]*: ([^)]*)[ ]*#\\([0-9A-Fa-f]\\{6\\}\\).*|\\1|',
                '-e', 's:^#.*:@:',
                '-e', 's#000000#0#g',
                '-e', 's#FFFFFF#F#',
            ],
            [ 'tee', self.get_temp('1.txt') ],
            [
                'sed',
                '-e', ':a',
                '-e', 'N;s#\\n##;s#^@##;/@$/{s#@$##p;d}',
                '-e', 't a',
            ],
            [ 'tee', self.get_temp('2.txt') ],
            [
                'sed',
                '-f', QemuVMController.ocr_sed,
            ],
            [
                'sed',
                '/../s#.*#?#',
            ],
            [ 'tee', self.get_temp('3.txt') ],
            [
                'paste',
                '-sd', '',
            ],
            [
                'fold',
                '-w', '{}'.format(cols),
            ],
            [ 'tee', self.get_temp('4.txt') ],
            [
                'head',
                '-n', '{}'.format(rows),
            ],
            [
                'tee',
                screenshot_text,
            ]
        ])

        self.screenshot_filename = screenshot_full

        with open(screenshot_text, 'r') as f:
            lines = [ l.strip('\n') for l in f.readlines() ]
            self.logger.debug("Captured text:")
            for l in lines:
                self.logger.debug("| " + l)
            return lines
Пример #6
0
    def run(self):
        self.logger.info("Typing '{}' into {}.".format(self.command,
                                                       self.machine.name))

        cursor_symbol = self.machine.get_vterm_cursor_symbol()
        cursor_symbol_spaced = '' if cursor_symbol == '' else ' ' + cursor_symbol
        prompt_re = re.compile('^/[^ ]* #' + re.escape(cursor_symbol_spaced) +
                               '[\t ]*$')
        self.logger.debug("RE for prompt matching: {}".format(prompt_re))

        # Capture the screen before typing the command.
        self.machine.capture_vterm()

        self.machine.type(self.command)

        # Wait until the command is fully displayed on the screen.
        # That is needed to properly detect the newly displayed lines.
        # FIXME: this will not work for long commands spanning multiple lines
        for xxx in retries(timeout=60,
                           interval=2,
                           name="vterm-type",
                           message="Failed to type command"):
            self.machine.vterm = []
            self.machine.capture_vterm()
            lines = self.machine.vterm

            if len(lines) > 0:
                line = lines[0].strip()

                if (cursor_symbol != '') and line.endswith(cursor_symbol):
                    line = line[0:-(len(cursor_symbol))]
                if line.endswith(self.command.strip()):
                    break

        self.machine.vterm = []
        self.machine.type('\n')

        # Read output of the command.
        # We wait until prompt reappears or we find some text that is not
        # supposed to be there. Meanwhile we check that the text that is
        # supposed to be there appears.
        asserted_text_found = not 'assert' in self.args
        for xxx in retries(timeout=60,
                           interval=2,
                           name="vterm-run",
                           message="Failed to run command"):
            self.logger.debug("self.vterm = {}".format(self.machine.vterm))
            self.machine.capture_vterm()
            lines = self.machine.vterm
            self.logger.debug("Read lines {}".format(lines))
            self.machine.vterm = []
            if not self.ignore_abort:
                if self._find_in_lines('Cannot spawn',
                                       lines) or self._find_in_lines(
                                           'Command failed', lines):
                    raise Exception('Failed to run command')
            if 'negassert' in self.args:
                if self._find_in_lines(self.args['negassert'], lines):
                    raise Exception('Found forbidden text {} ...'.format(
                        self.args['negassert']))
            if ('assert' in self.args) and (not asserted_text_found):
                asserted_text_found = self._find_in_lines(
                    self.args['assert'], lines)
            if self._grep_in_lines(prompt_re, lines):
                if not asserted_text_found:
                    raise Exception('Missing expected text {} ...'.format(
                        self.args['assert']))
                break
        self.logger.info("Command '{}' done.".format(self.command))