[Piglit] [PATCH 2/2] framework: record pid of test process in results
Mark Janes
mark.a.janes at intel.com
Thu Jan 7 09:53:12 PST 2016
Thank you for this feature. It has already assisted me in identifying a
gpu hang, even though I can't run with dmesg.
The only nit I have is about your choice to add an extra newline between
the pid field and start time. The formatting makes the output look
sloppy to me.
I've pointed out the places below where this occurs. Whether or not you
choose to change this,
Reviewed-by: Mark Janes <mark.a.janes at intel.com>
baker.dylan.c at gmail.com writes:
> From: Dylan Baker <baker.dylan.c at gmail.com>
>
> This information can be used on linux in conjunction with scripts to
> associate information in dmesg with information in piglit results.
>
> Adds the pid information to both the json and junit backends, and adds
> tests for both.
>
> This information is not published into any of the summary modes on
> purpose. It's usefulness is limited to the system on which the test was
> ran, and only while a log of dmesg exists.
>
> Signed-off-by: Dylan Baker <dylanx.c.baker at intel.com>
> ---
> framework/backends/junit.py | 24 ++++++++++++++----------
> framework/results.py | 6 ++++--
> framework/test/base.py | 3 +++
> framework/tests/junit_backends_tests.py | 19 ++++++++++++++++---
> framework/tests/results_tests.py | 10 ++++++++++
> 5 files changed, 47 insertions(+), 15 deletions(-)
>
> diff --git a/framework/backends/junit.py b/framework/backends/junit.py
> index 15c6c0b..c67fbdc 100644
> --- a/framework/backends/junit.py
> +++ b/framework/backends/junit.py
> @@ -212,8 +212,8 @@ class JUnitBackend(FileBackend):
> # Add stderr
> err = etree.SubElement(element, 'system-err')
> err.text = data.err
> - err.text += '\n\nstart time: {}\nend time: {}\n'.format(
> - data.time.start, data.time.end)
> + err.text += '\n\npid: {}\n\nstart time: {}\nend time: {}\n'.format(
^^^^
> + data.pid, data.time.start, data.time.end)
> calculate_result()
> else:
> etree.SubElement(element, 'failure', message='Incomplete run.')
> @@ -267,14 +267,18 @@ def _load(results_file):
> result.command = out[0]
> result.out = '\n'.join(out[1:])
>
> - # Try to get the values in stderr for time
> - if 'time start' in result.err:
> - for line in result.err.split('\n'):
> - if line.startswith('time start:'):
> - result.time.start = float(line[len('time start: '):])
> - elif line.startswith('time end:'):
> - result.time.end = float(line[len('time end: '):])
> - break
> + # Try to get the values in stderr for time and pid
> + for line in result.err.split('\n'):
> + if line.startswith('time start:'):
> + result.time.start = float(line[len('time start: '):])
> + continue
> + elif line.startswith('time end:'):
> + result.time.end = float(line[len('time end: '):])
> + continue
> + elif line.startswith('pid:'):
> + result.pid = int(line[len('pid: '):])
> + continue
> +
>
> run_result.tests[name] = result
>
> diff --git a/framework/results.py b/framework/results.py
> index eeffcb7..86560ad 100644
> --- a/framework/results.py
> +++ b/framework/results.py
> @@ -145,7 +145,7 @@ class TestResult(object):
> """An object represting the result of a single test."""
> __slots__ = ['returncode', '_err', '_out', 'time', 'command', 'traceback',
> 'environment', 'subtests', 'dmesg', '__result', 'images',
> - 'exception']
> + 'exception', 'pid']
> err = StringDescriptor('_err')
> out = StringDescriptor('_out')
>
> @@ -159,6 +159,7 @@ class TestResult(object):
> self.images = None
> self.traceback = None
> self.exception = None
> + self.pid = None
> if result:
> self.result = result
> else:
> @@ -197,6 +198,7 @@ class TestResult(object):
> 'time': self.time,
> 'exception': self.exception,
> 'dmesg': self.dmesg,
> + 'pid': self.pid,
> }
> return obj
>
> @@ -216,7 +218,7 @@ class TestResult(object):
> inst = cls()
>
> for each in ['returncode', 'command', 'exception', 'environment',
> - 'time', 'result', 'dmesg']:
> + 'time', 'result', 'dmesg', 'pid']:
> if each in dict_:
> setattr(inst, each, dict_[each])
>
> diff --git a/framework/test/base.py b/framework/test/base.py
> index 4232e6c..417fd4e 100644
> --- a/framework/test/base.py
> +++ b/framework/test/base.py
> @@ -302,6 +302,7 @@ class Test(object):
> env=fullenv,
> universal_newlines=True,
> preexec_fn=preexec_fn)
> +
> # create a ProcessTimeout object to watch out for test hang if the
> # process is still going after the timeout, then it will be killed
> # forcing the communicate function (which is a blocking call) to
> @@ -310,6 +311,8 @@ class Test(object):
> self.__proc_timeout = ProcessTimeout(self.timeout, proc)
> self.__proc_timeout.start()
>
> + self.result.pid = proc.pid
> +
> out, err = proc.communicate()
> returncode = proc.returncode
> except OSError as e:
> diff --git a/framework/tests/junit_backends_tests.py b/framework/tests/junit_backends_tests.py
> index 7d5a3fc..8801a27 100644
> --- a/framework/tests/junit_backends_tests.py
> +++ b/framework/tests/junit_backends_tests.py
> @@ -49,6 +49,8 @@ _XML = """\
> <system-out>this/is/a/command\nThis is stdout</system-out>
> <system-err>this is stderr
>
> +pid: 1934
> +
^^^^
> time start: 1.0
> time end: 4.5
> </system-err>
> @@ -98,6 +100,7 @@ class TestJUnitSingleTest(TestJunitNoTests):
> result.out = 'this is stdout'
> result.err = 'this is stderr'
> result.command = 'foo'
> + result.pid = 1034
>
> test = backends.junit.JUnitBackend(cls.tdir)
> test.initialize(BACKEND_INITIAL_META)
> @@ -129,6 +132,7 @@ class TestJUnitMultiTest(TestJUnitSingleTest):
> result.out = 'this is stdout'
> result.err = 'this is stderr'
> result.command = 'foo'
> + result.pid = 1034
>
> cls.test_file = os.path.join(cls.tdir, 'results.xml')
> test = backends.junit.JUnitBackend(cls.tdir)
> @@ -203,7 +207,7 @@ class TestJUnitLoad(utils.StaticDirectory):
> def setup_class(cls):
> super(TestJUnitLoad, cls).setup_class()
> cls.xml_file = os.path.join(cls.tdir, 'results.xml')
> -
> +
> with open(cls.xml_file, 'w') as f:
> f.write(_XML)
>
> @@ -263,13 +267,22 @@ class TestJUnitLoad(utils.StaticDirectory):
> def test_err(self):
> """backends.junit._load: stderr is loaded correctly."""
> test = self.xml().tests[self.testname].err
> - nt.eq_(
> - test, 'this is stderr\n\ntime start: 1.0\ntime end: 4.5\n ')
> + expected = ('this is stderr\n\n'
> + 'pid: 1934\n\n'
^^^^
> + 'time start: 1.0\n'
> + 'time end: 4.5\n'
> + ' ')
> + nt.eq_(test, expected)
>
> def test_totals(self):
> """backends.junit._load: Totals are calculated."""
> nt.ok_(bool(self.xml()))
>
> + def test_pid(self):
> + """backends.junit._load: pid is loaded correctly."""
> + test = self.xml().tests[self.testname].pid
> + nt.eq_(test, 1934)
> +
>
> @utils.no_error
> def test_load_file(self):
> diff --git a/framework/tests/results_tests.py b/framework/tests/results_tests.py
> index 745632b..17a7682 100644
> --- a/framework/tests/results_tests.py
> +++ b/framework/tests/results_tests.py
> @@ -205,6 +205,7 @@ class TestTestResult_to_json(object):
> test.result = 'crash'
> test.exception = 'an exception'
> test.dmesg = 'this is dmesg'
> + test.pid = 1934
>
> cls.test = test
> cls.json = test.to_json()
> @@ -254,6 +255,10 @@ class TestTestResult_to_json(object):
> """results.TestResult.to_json: Adds the dmesg attribute"""
> nt.eq_(self.test.dmesg, self.json['dmesg'])
>
> + def test_pid(self):
> + """results.TestResult.to_json: Adds the pid attribute"""
> + nt.eq_(self.test.pid, self.json['pid'])
> +
>
> class TestTestResult_from_dict(object):
> """Tests for the from_dict method."""
> @@ -275,6 +280,7 @@ class TestTestResult_from_dict(object):
> 'result': 'crash',
> 'exception': 'an exception',
> 'dmesg': 'this is dmesg',
> + 'pid': 1934,
> }
>
> cls.test = results.TestResult.from_dict(cls.dict)
> @@ -327,6 +333,10 @@ class TestTestResult_from_dict(object):
> """results.TestResult.from_dict: sets dmesg properly"""
> nt.eq_(self.test.dmesg, self.dict['dmesg'])
>
> + def test_pid(self):
> + """results.TestResult.from_dict: sets pid properly"""
> + nt.eq_(self.test.pid, self.dict['pid'])
> +
>
> def test_TestResult_update():
> """results.TestResult.update: result is updated"""
> --
> 2.6.4
More information about the Piglit
mailing list