Merge lp:~terceiro/lava-dispatcher/filter-ansi-color-codes into lp:lava-dispatcher

Proposed by Antonio Terceiro
Status: Rejected
Rejected by: Neil Williams
Proposed branch: lp:~terceiro/lava-dispatcher/filter-ansi-color-codes
Merge into: lp:lava-dispatcher
Prerequisite: lp:~terceiro/lava-dispatcher/fix-unit-tests
Diff against target: 242 lines (+104/-8)
11 files modified
lava_dispatcher/client/targetdevice.py (+1/-1)
lava_dispatcher/device/fastmodel.py (+4/-2)
lava_dispatcher/device/ipmi_pxe.py (+1/-1)
lava_dispatcher/device/master.py (+1/-1)
lava_dispatcher/device/qemu.py (+1/-1)
lava_dispatcher/device/sdmux.py (+1/-1)
lava_dispatcher/device/target.py (+1/-1)
lava_dispatcher/tests/__init__.py (+1/-0)
lava_dispatcher/tests/simulate_uefi_on_fastmodel.py (+10/-0)
lava_dispatcher/tests/test_utils.py (+61/-0)
lava_dispatcher/utils.py (+22/-0)
To merge this branch: bzr merge lp:~terceiro/lava-dispatcher/filter-ansi-color-codes
Reviewer Review Type Date Requested Status
Antonio Terceiro Needs Resubmitting
Review via email: mp+178188@code.launchpad.net

This proposal supersedes a proposal from 2013-08-02.

Description of the change

Filter out ANSI color codes when matching for patterns. This shoulf fix #1197582

To post a comment you must log in.
Revision history for this message
Antonio Terceiro (terceiro) wrote :

This does not fix the problem yet - no need for reviewing now. I will resubmit when it's done.

review: Needs Resubmitting
646. By Antonio Terceiro

Need to filter out non-color codes as well, such as cursor positioning, screen
clearing etc.

647. By Antonio Terceiro

Deal with slow/broken serial connection when filtering out ANSI escape sequences

648. By Antonio Terceiro

Merge branch for supporting specifying a bootloader on deployment of prebuilt images as well

649. By Antonio Terceiro

filter other escape sequences

650. By Antonio Terceiro

update from parent branch

651. By Antonio Terceiro

update from trunk

Unmerged revisions

651. By Antonio Terceiro

update from trunk

650. By Antonio Terceiro

update from parent branch

649. By Antonio Terceiro

filter other escape sequences

648. By Antonio Terceiro

Merge branch for supporting specifying a bootloader on deployment of prebuilt images as well

647. By Antonio Terceiro

Deal with slow/broken serial connection when filtering out ANSI escape sequences

646. By Antonio Terceiro

Need to filter out non-color codes as well, such as cursor positioning, screen
clearing etc.

645. By Antonio Terceiro

Filter out ANSI color escape sequences when reading input from child processes

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'lava_dispatcher/client/targetdevice.py'
--- lava_dispatcher/client/targetdevice.py 2013-07-24 16:56:18 +0000
+++ lava_dispatcher/client/targetdevice.py 2013-08-08 15:29:54 +0000
@@ -62,7 +62,7 @@
62 if image is None:62 if image is None:
63 self.target_device.deploy_linaro(hwpack, rootfs, bootloader)63 self.target_device.deploy_linaro(hwpack, rootfs, bootloader)
64 else:64 else:
65 self.target_device.deploy_linaro_prebuilt(image)65 self.target_device.deploy_linaro_prebuilt(image, bootloader)
6666
67 def _boot_linaro_image(self):67 def _boot_linaro_image(self):
68 if self.proc:68 if self.proc:
6969
=== modified file 'lava_dispatcher/device/fastmodel.py'
--- lava_dispatcher/device/fastmodel.py 2013-07-24 14:04:25 +0000
+++ lava_dispatcher/device/fastmodel.py 2013-08-08 15:29:54 +0000
@@ -171,10 +171,11 @@
171 rootfs = download_image(rootfs, self.context, decompress=False)171 rootfs = download_image(rootfs, self.context, decompress=False)
172 odir = os.path.dirname(rootfs)172 odir = os.path.dirname(rootfs)
173173
174 self._bootloader = bootloader
175174
176 generate_fastmodel_image(self.context, hwpack, rootfs, odir, bootloader)175 generate_fastmodel_image(self.context, hwpack, rootfs, odir, bootloader)
176
177 self._sd_image = '%s/sd.img' % odir177 self._sd_image = '%s/sd.img' % odir
178 self._bootloader = bootloader
178179
179 self._copy_needed_files_from_directory(odir)180 self._copy_needed_files_from_directory(odir)
180 self._copy_needed_files_from_partition(self.config.boot_part, 'rtsm')181 self._copy_needed_files_from_partition(self.config.boot_part, 'rtsm')
@@ -182,8 +183,9 @@
182183
183 self._customize_linux(self._sd_image)184 self._customize_linux(self._sd_image)
184185
185 def deploy_linaro_prebuilt(self, image):186 def deploy_linaro_prebuilt(self, image, bootloader='u_boot'):
186 self._sd_image = download_image(image, self.context)187 self._sd_image = download_image(image, self.context)
188 self._bootloader = bootloader
187189
188 self._copy_needed_files_from_partition(self.config.boot_part, 'rtsm')190 self._copy_needed_files_from_partition(self.config.boot_part, 'rtsm')
189 self._copy_needed_files_from_partition(self.config.root_part, 'boot')191 self._copy_needed_files_from_partition(self.config.root_part, 'boot')
190192
=== modified file 'lava_dispatcher/device/ipmi_pxe.py'
--- lava_dispatcher/device/ipmi_pxe.py 2013-07-16 16:06:42 +0000
+++ lava_dispatcher/device/ipmi_pxe.py 2013-08-08 15:29:54 +0000
@@ -79,7 +79,7 @@
79 self._customize_linux(image_file)79 self._customize_linux(image_file)
80 self._deploy_image(image_file, '/dev/sda')80 self._deploy_image(image_file, '/dev/sda')
8181
82 def deploy_linaro_prebuilt(self, image):82 def deploy_linaro_prebuilt(self, image, bootloader):
83 image_file = download_image(image, self.context, self.scratch_dir)83 image_file = download_image(image, self.context, self.scratch_dir)
84 self._customize_linux(image_file)84 self._customize_linux(image_file)
85 self._deploy_image(image_file, '/dev/sda')85 self._deploy_image(image_file, '/dev/sda')
8686
=== modified file 'lava_dispatcher/device/master.py'
--- lava_dispatcher/device/master.py 2013-07-17 09:16:46 +0000
+++ lava_dispatcher/device/master.py 2013-08-08 15:29:54 +0000
@@ -149,7 +149,7 @@
149 _deploy_linaro_android_system(master, system_url)149 _deploy_linaro_android_system(master, system_url)
150 _deploy_linaro_android_data(master, data_url)150 _deploy_linaro_android_data(master, data_url)
151151
152 def deploy_linaro_prebuilt(self, image):152 def deploy_linaro_prebuilt(self, image, bootloader):
153 self.boot_master_image()153 self.boot_master_image()
154154
155 if self.context.job_data.get('health_check', False):155 if self.context.job_data.get('health_check', False):
156156
=== modified file 'lava_dispatcher/device/qemu.py'
--- lava_dispatcher/device/qemu.py 2013-07-24 14:04:25 +0000
+++ lava_dispatcher/device/qemu.py 2013-08-08 15:29:54 +0000
@@ -51,7 +51,7 @@
51 self._sd_image = generate_image(self, hwpack, rootfs, odir, bootloader)51 self._sd_image = generate_image(self, hwpack, rootfs, odir, bootloader)
52 self._customize_linux(self._sd_image)52 self._customize_linux(self._sd_image)
5353
54 def deploy_linaro_prebuilt(self, image):54 def deploy_linaro_prebuilt(self, image, bootloader='u_boot'):
55 self._sd_image = download_image(image, self.context)55 self._sd_image = download_image(image, self.context)
56 self._customize_linux(self._sd_image)56 self._customize_linux(self._sd_image)
5757
5858
=== modified file 'lava_dispatcher/device/sdmux.py'
--- lava_dispatcher/device/sdmux.py 2013-07-16 16:04:07 +0000
+++ lava_dispatcher/device/sdmux.py 2013-08-08 15:29:54 +0000
@@ -93,7 +93,7 @@
93 self._customize_linux(img)93 self._customize_linux(img)
94 self._write_image(img)94 self._write_image(img)
9595
96 def deploy_linaro_prebuilt(self, image):96 def deploy_linaro_prebuilt(self, image, bootloader=None):
97 img = download_image(image, self.context)97 img = download_image(image, self.context)
98 self._customize_linux(img)98 self._customize_linux(img)
99 self._write_image(img)99 self._write_image(img)
100100
=== modified file 'lava_dispatcher/device/target.py'
--- lava_dispatcher/device/target.py 2013-07-17 09:16:46 +0000
+++ lava_dispatcher/device/target.py 2013-08-08 15:29:54 +0000
@@ -91,7 +91,7 @@
91 def deploy_android(self, boot, system, userdata):91 def deploy_android(self, boot, system, userdata):
92 raise NotImplementedError('deploy_android_image')92 raise NotImplementedError('deploy_android_image')
9393
94 def deploy_linaro_prebuilt(self, image):94 def deploy_linaro_prebuilt(self, image, bootloader):
95 raise NotImplementedError('deploy_linaro_prebuilt')95 raise NotImplementedError('deploy_linaro_prebuilt')
9696
97 def power_off(self, proc):97 def power_off(self, proc):
9898
=== modified file 'lava_dispatcher/tests/__init__.py'
--- lava_dispatcher/tests/__init__.py 2013-07-16 16:09:31 +0000
+++ lava_dispatcher/tests/__init__.py 2013-08-08 15:29:54 +0000
@@ -3,6 +3,7 @@
33
4def test_suite():4def test_suite():
5 module_names = [5 module_names = [
6 'lava_dispatcher.tests.test_utils',
6 'lava_dispatcher.tests.test_config',7 'lava_dispatcher.tests.test_config',
7 'lava_dispatcher.tests.test_device_version',8 'lava_dispatcher.tests.test_device_version',
8 ]9 ]
910
=== added file 'lava_dispatcher/tests/simulate_uefi_on_fastmodel.py'
--- lava_dispatcher/tests/simulate_uefi_on_fastmodel.py 1970-01-01 00:00:00 +0000
+++ lava_dispatcher/tests/simulate_uefi_on_fastmodel.py 2013-08-08 15:29:54 +0000
@@ -0,0 +1,10 @@
1import sys
2import time
3
4chars = 0
5for char in "\033[23;01H2.0 \033[1m\033[33m\033[40mShell> \033[0m\033[37m\033[40m":
6 sys.stdout.write(char)
7 sys.stdout.flush()
8 chars += 1
9 if chars % 10 == 0:
10 time.sleep(0.1)
011
=== added file 'lava_dispatcher/tests/test_utils.py'
--- lava_dispatcher/tests/test_utils.py 1970-01-01 00:00:00 +0000
+++ lava_dispatcher/tests/test_utils.py 2013-08-08 15:29:54 +0000
@@ -0,0 +1,61 @@
1# Copyright (C) 2013 Linaro Limited
2#
3# Author: Antonio Terceiro <antonio.terceiro@linaro.org>
4#
5# This file is part of LAVA Dispatcher.
6#
7# LAVA Dispatcher is free software; you can redistribute it and/or modify
8# it under the terms of the GNU General Public License as published by
9# the Free Software Foundation; either version 2 of the License, or
10# (at your option) any later version.
11#
12# LAVA Dispatcher is distributed in the hope that it will be useful,
13# but WITHOUT ANY WARRANTY; without even the implied warranty of
14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15# GNU General Public License for more details.
16#
17# You should have received a copy of the GNU General Public License
18# along with this program; if not, see <http://www.gnu.org/licenses>.
19
20from unittest import TestCase
21import pexpect
22
23import os
24
25from lava_dispatcher.utils import logging_spawn, remove_ansi_escape_codes
26
27class TestLoggingSpawn(TestCase):
28
29 def test_filter_out_ansi_color_codes(self):
30 proc = logging_spawn('printf "I AM \033[1mOK\033[m\n"') # OK in bold
31 proc.expect(["I AM OK", pexpect.EOF])
32 self.assertIsNot(proc.match, pexpect.EOF)
33
34 def test_filter_out_multiple_ansi_color_escape_sequences(self):
35 # "I AM" in bold light green, "OK" in bold
36 proc = logging_spawn('printf "\033[1;32;40mI AM\033[m \033[1mOK\033[m\n"')
37 proc.expect(["I AM OK", pexpect.EOF])
38 self.assertIsNot(proc.match, pexpect.EOF)
39
40 def test_filter_out_cursor_positioning_codes(self):
41 proc = logging_spawn('printf "I AM \033[23;01H\033[1mOK\033[m\n"')
42 proc.expect(["I AM OK", pexpect.EOF])
43 self.assertIsNot(proc.match, pexpect.EOF)
44
45 def test_filter_out_uefi_ansi_crap(self):
46 program = os.path.join(os.path.dirname(__file__),
47 'simulate_uefi_on_fastmodel.py')
48 proc = logging_spawn('python %s' % program)
49 proc.expect(['2.0 Shell>', pexpect.EOF])
50 self.assertIsNot(proc.match, pexpect.EOF)
51
52 def test_filter_out_other_types_of_escape_sequences(self):
53 proc = logging_spawn('printf "\x1b[=3hTHIS \x1b[=3hIS \x1b[=3hOK"')
54 proc.expect(['THIS IS OK'])
55 self.assertIsNot(proc.match, pexpect.EOF)
56
57 def test_filter_out_incomplete_sequences_followed_by_others(self):
58 data = "\x1b[01;01\x1b[=3hHELLO"
59 self.assertEqual(remove_ansi_escape_codes(data), "HELLO")
60
61
062
=== modified file 'lava_dispatcher/utils.py'
--- lava_dispatcher/utils.py 2013-07-24 16:56:18 +0000
+++ lava_dispatcher/utils.py 2013-08-08 15:29:54 +0000
@@ -29,6 +29,7 @@
29import time29import time
30import urlparse30import urlparse
31import subprocess31import subprocess
32import re
3233
33from shlex import shlex34from shlex import shlex
3435
@@ -213,6 +214,24 @@
213 ['.+', pexpect.EOF, pexpect.TIMEOUT],214 ['.+', pexpect.EOF, pexpect.TIMEOUT],
214 timeout=1, lava_no_logging=1)215 timeout=1, lava_no_logging=1)
215216
217 def read_nonblocking(self, size, timeout):
218 read = super(logging_spawn, self).read_nonblocking
219
220 raw = read(size, timeout)
221 filtered = remove_ansi_escape_codes(raw)
222
223 while '\x1b' in filtered:
224 # This happens when the serial connection is too slow -- or just
225 # broken -- and the escape sequences are split across different
226 # reads. We have to accumulate more reads until we find the entire
227 # sequence to be able to filter it out.
228 raw = raw + read(size, timeout)
229 logging.debug("Input with potentially incomplete ANSI "
230 "escape sequence: %r" % raw)
231 filtered = remove_ansi_escape_codes(raw)
232
233 return filtered
234
216235
217def connect_to_serial(context):236def connect_to_serial(context):
218 """237 """
@@ -276,3 +295,6 @@
276 logging.debug("Finalizing child proccess with PID %d" % proc.pid)295 logging.debug("Finalizing child proccess with PID %d" % proc.pid)
277 proc.kill(9)296 proc.kill(9)
278 proc.close()297 proc.close()
298
299def remove_ansi_escape_codes(string):
300 return re.sub('(\x1b\[[0-9;=]*)+[a-zA-Z]', '', string)

Subscribers

People subscribed via source and target branches