Re: [Piglit] [Patch v3 1/4] framework/dmesg: Adds a new module for dmesg

2014-02-03 Thread Ilia Mirkin
On Mon, Feb 3, 2014 at 7:39 PM, Dylan Baker  wrote:
> On Monday, February 03, 2014 06:53:53 PM Ilia Mirkin wrote:
>> On Mon, Feb 3, 2014 at 6:40 PM, Dylan Baker  wrote:
>> > This modules implements two classes and a helper function. The two
>> > classes are both dmesg wrapper classes, one, PosixDmesg is used on posix
>> > systems when requested to actually do checks on dmesg. The second class,
>> > DummyDmesg, is used to reduce code complexity by providing dummy
>> > versions of the methods in PosixDmesg. This means that we don't need
>> > separate code paths for Posix systems wanting to check dmesg, Posix
>> > systems not wanting to check dmesg, and non-posix systems which lack
>> > dmesg.
>> >
>> > Beyond reducing complexity this module also gives better isolation,
>> > dmesg is only used in Test.execute(), no where else. Additional classes
>> > don't need to worry about dmesg that way, it's just available.
>> >
>> > v2: - Remove unnecessary assert from PosixDmesg.update_result()
>> >
>> > - simplify replace helper in PoixDmesg.update_result()
>> > - replace try/except with if check
>> > - Change PosixDmesg.update_dmesg() to work even if dmesg 'wraps'
>> >
>> > v3: - Try/Except assignment of PosixDmesg._last_message in update_dmesg()
>> >
>> > - Set the dmesg levels the same as the previous implementation
>> > - Change PosixDmesg into LinuxDmesg and enforce that dmesg has
>> >
>> >   timestamps
>> >
>> > Signed-off-by: Dylan Baker 
>> > ---
>> >
>> >  framework/dmesg.py | 167
>> >  + 1 file changed,
>> >  167 insertions(+)
>> >  create mode 100644 framework/dmesg.py
>> >
>> > diff --git a/framework/dmesg.py b/framework/dmesg.py
>> > new file mode 100644
>> > index 000..d270aaa
>> > --- /dev/null
>> > +++ b/framework/dmesg.py
>> > @@ -0,0 +1,167 @@
>> > +# Copyright (c) 2013-2014 Intel Corporation
>> > +#
>> > +# Permission is hereby granted, free of charge, to any person obtaining a
>> > +# copy of this software and associated documentation files (the
>> > "Software"), +# to deal in the Software without restriction, including
>> > without limitation +# the rights to use, copy, modify, merge, publish,
>> > distribute, sublicense, +# and/or sell copies of the Software, and to
>> > permit persons to whom the +# Software is furnished to do so, subject to
>> > the following conditions: +#
>> > +# The above copyright notice and this permission notice (including the
>> > next +# paragraph) shall be included in all copies or substantial
>> > portions of the +# Software.
>> > +#
>> > +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
>> > OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
>> > MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
>> >  IN NO EVENT SHALL +# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
>> > CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
>> > TORT OR OTHERWISE, ARISING +# FROM, OUT OF OR IN CONNECTION WITH THE
>> > SOFTWARE OR THE USE OR OTHER DEALINGS +# IN THE SOFTWARE.
>> > +
>> > +""" Module implementing classes for reading posix dmesg
>> > +
>> > +Currently this module only has the default DummyDmesg, and a LinuxDmesg.
>> > +The method used on Linux requires that timetamps are enabled, and no
>> > other
>> > +posix system has timestamps.
>> > +
>> > +On OSX and *BSD one would likely want to implement a system that reads
>> > the
>> > +sysloger, since timestamps can be added by the sysloger, and are not
>> > inserted +by dmesg.
>> > +
>> > +"""
>> > +
>> > +import re
>> > +import sys
>> > +import subprocess
>> > +
>> > +__all__ = ['LinuxDmesg', 'DummyDmesg', 'get_dmesg']
>> > +
>> > +
>> > +class LinuxDmesg(object):
>> > +""" Read dmesg on posix systems
>> > +
>> > +This reads the dmesg ring buffer, stores the contents of the buffer,
>> > and +then compares it whenever called, returning the difference
>> > between the +calls. It requires timestamps to be enabled.
>> > +
>> > +"""
>> > +DMESG_COMMAND = ['dmesg', '--level',
>> > 'emerg,alert,crit,err,warn,notice'] +
>> > +def __init__(self):
>> > +""" Create a dmesg instance """
>> > +self._last_message = None
>> > +self._new_messages = []
>> > +
>> > +# Populate self.dmesg initially, otherwise the first test will
>> > always +# be full of dmesg crud.
>> > +self.update_dmesg()
>> > +
>> > +# Do an initial check to ensure that dmesg has timestamps, we
>> > need
>> > +# timestamps to work correctly. A proper linux dmesg timestamp
>> > looks +# like this: [0.0]
>>
>> > +if not re.match('\[\s*\d+\.\d+\]', self._last_message):
>> So if I do dmesg -c; ./piglit-run bla this will fail, right? (I'm
>> surprised that the string works without the r prefix for raw string,
>> but I double-checked and it does...)
>
> I'll add the r
> And I don't know how I managed to 

Re: [Piglit] [Patch v3 3/4] Use the new dmesg class

2014-02-03 Thread Ilia Mirkin
On Mon, Feb 3, 2014 at 6:40 PM, Dylan Baker  wrote:
> This actually makes use of the new dmesg class rather than the dmesg
> functions. It touches a lot of files, but almost all of these changes
> are code removal rather than code addition.
>
> Signed-off-by: Dylan Baker 

Reviewed-by: Ilia Mirkin 

One little comment/question below:

> ---
>  framework/core.py| 30 -
>  framework/exectest.py| 50 
> ++--
>  framework/gleantest.py   |  6 +++---
>  framework/shader_test.py |  2 +-
>  piglit-run.py|  5 +++--
>  tests/es3conform.py  |  6 +++---
>  tests/igt.py |  8 
>  tests/oglconform.py  |  6 +++---
>  8 files changed, 48 insertions(+), 65 deletions(-)
>
> diff --git a/framework/core.py b/framework/core.py
> index da2a716..01aa1b5 100644
> --- a/framework/core.py
> +++ b/framework/core.py
> @@ -424,7 +424,7 @@ class Test(object):
>  def run(self):
>  raise NotImplementedError
>
> -def execute(self, env, path, json_writer):
> +def execute(self, env, path, json_writer, dmesg):
>  '''
>  Run the test.
>
> @@ -440,8 +440,10 @@ class Test(object):
>  try:
>  status("running")
>  time_start = time.time()
> +dmesg.update_dmesg()
>  self._test_hook_execute_run()
>  result = self.run(env)
> +result = dmesg.update_result(result)
>  time_end = time.time()
>  if 'time' not in result:
>  result['time'] = time_end - time_start

Did the old code include dmesg runtime in the test time? I'm a bit
lazy and haven't checked, and these diffs don't provide enough context
-- diff --show-function doesn't work so well for python :)

> @@ -111,19 +83,14 @@ class ExecTest(Test):
> '--tool=memcheck']
>
>  i = 0
> -dmesg_diff = ''
>  while True:
>  if self.skip_test:
>  out = "PIGLIT: {'result': 'skip'}\n"
>  err = ""
>  returncode = None
>  else:
> -if env.dmesg:
> -old_dmesg = read_dmesg()
> -(out, err, returncode) = \
> -self.get_command_result(command, fullenv)
> -if env.dmesg:
> -dmesg_diff = get_dmesg_diff(old_dmesg, read_dmesg())
> +out, err, returncode = self.get_command_result(command,
> +   fullenv)
>
>  # https://bugzilla.gnome.org/show_bug.cgi?id=680214 is
>  # affecting many developers.  If we catch it
___
Piglit mailing list
Piglit@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/piglit


Re: [Piglit] [Patch v3 1/4] framework/dmesg: Adds a new module for dmesg

2014-02-03 Thread Dylan Baker
On Monday, February 03, 2014 06:53:53 PM Ilia Mirkin wrote:
> On Mon, Feb 3, 2014 at 6:40 PM, Dylan Baker  wrote:
> > This modules implements two classes and a helper function. The two
> > classes are both dmesg wrapper classes, one, PosixDmesg is used on posix
> > systems when requested to actually do checks on dmesg. The second class,
> > DummyDmesg, is used to reduce code complexity by providing dummy
> > versions of the methods in PosixDmesg. This means that we don't need
> > separate code paths for Posix systems wanting to check dmesg, Posix
> > systems not wanting to check dmesg, and non-posix systems which lack
> > dmesg.
> > 
> > Beyond reducing complexity this module also gives better isolation,
> > dmesg is only used in Test.execute(), no where else. Additional classes
> > don't need to worry about dmesg that way, it's just available.
> > 
> > v2: - Remove unnecessary assert from PosixDmesg.update_result()
> > 
> > - simplify replace helper in PoixDmesg.update_result()
> > - replace try/except with if check
> > - Change PosixDmesg.update_dmesg() to work even if dmesg 'wraps'
> > 
> > v3: - Try/Except assignment of PosixDmesg._last_message in update_dmesg()
> > 
> > - Set the dmesg levels the same as the previous implementation
> > - Change PosixDmesg into LinuxDmesg and enforce that dmesg has
> > 
> >   timestamps
> > 
> > Signed-off-by: Dylan Baker 
> > ---
> > 
> >  framework/dmesg.py | 167
> >  + 1 file changed,
> >  167 insertions(+)
> >  create mode 100644 framework/dmesg.py
> > 
> > diff --git a/framework/dmesg.py b/framework/dmesg.py
> > new file mode 100644
> > index 000..d270aaa
> > --- /dev/null
> > +++ b/framework/dmesg.py
> > @@ -0,0 +1,167 @@
> > +# Copyright (c) 2013-2014 Intel Corporation
> > +#
> > +# Permission is hereby granted, free of charge, to any person obtaining a
> > +# copy of this software and associated documentation files (the
> > "Software"), +# to deal in the Software without restriction, including
> > without limitation +# the rights to use, copy, modify, merge, publish,
> > distribute, sublicense, +# and/or sell copies of the Software, and to
> > permit persons to whom the +# Software is furnished to do so, subject to
> > the following conditions: +#
> > +# The above copyright notice and this permission notice (including the
> > next +# paragraph) shall be included in all copies or substantial
> > portions of the +# Software.
> > +#
> > +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
> > OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
> > MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
> >  IN NO EVENT SHALL +# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
> > CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
> > TORT OR OTHERWISE, ARISING +# FROM, OUT OF OR IN CONNECTION WITH THE
> > SOFTWARE OR THE USE OR OTHER DEALINGS +# IN THE SOFTWARE.
> > +
> > +""" Module implementing classes for reading posix dmesg
> > +
> > +Currently this module only has the default DummyDmesg, and a LinuxDmesg.
> > +The method used on Linux requires that timetamps are enabled, and no
> > other
> > +posix system has timestamps.
> > +
> > +On OSX and *BSD one would likely want to implement a system that reads
> > the
> > +sysloger, since timestamps can be added by the sysloger, and are not
> > inserted +by dmesg.
> > +
> > +"""
> > +
> > +import re
> > +import sys
> > +import subprocess
> > +
> > +__all__ = ['LinuxDmesg', 'DummyDmesg', 'get_dmesg']
> > +
> > +
> > +class LinuxDmesg(object):
> > +""" Read dmesg on posix systems
> > +
> > +This reads the dmesg ring buffer, stores the contents of the buffer,
> > and +then compares it whenever called, returning the difference
> > between the +calls. It requires timestamps to be enabled.
> > +
> > +"""
> > +DMESG_COMMAND = ['dmesg', '--level',
> > 'emerg,alert,crit,err,warn,notice'] +
> > +def __init__(self):
> > +""" Create a dmesg instance """
> > +self._last_message = None
> > +self._new_messages = []
> > +
> > +# Populate self.dmesg initially, otherwise the first test will
> > always +# be full of dmesg crud.
> > +self.update_dmesg()
> > +
> > +# Do an initial check to ensure that dmesg has timestamps, we
> > need
> > +# timestamps to work correctly. A proper linux dmesg timestamp
> > looks +# like this: [0.0]
> 
> > +if not re.match('\[\s*\d+\.\d+\]', self._last_message):
> So if I do dmesg -c; ./piglit-run bla this will fail, right? (I'm
> surprised that the string works without the r prefix for raw string,
> but I double-checked and it does...)

I'll add the r
And I don't know how I managed to drop the check to ensure that dmesg wasn't 
Falsy, I wrote that code originally.

> 
> > +raise EnvironmentError("Your kernel does not seem to s

Re: [Piglit] [Patch v3 4/4] piglit-run.py: Restrict dmesg to serial runs

2014-02-03 Thread Ilia Mirkin
On Mon, Feb 3, 2014 at 6:40 PM, Dylan Baker  wrote:
> Dmesg reporting has always been inaccurate with concurrent runs, and the
> solution to concurrent runs would be to have each run take out a lock,
> removing the chance that another test generated an error in dmesg while
> it was running. But this effectively makes them a serial run, and at the
> cost of greater code complexity. With that in mind it makes more sense
> to just force --dmesg to imply -1.
>
> Signed-off-by: Dylan Baker 

Reviewed-by: Ilia Mirkin 

> ---
>  piglit-run.py | 7 ++-
>  1 file changed, 6 insertions(+), 1 deletion(-)
>
> diff --git a/piglit-run.py b/piglit-run.py
> index faf3adb..d837ccf 100755
> --- a/piglit-run.py
> +++ b/piglit-run.py
> @@ -81,7 +81,7 @@ def main():
>  parser.add_argument("--dmesg",
>  action="store_true",
>  help="Capture a difference in dmesg before and "
> - "after each test")
> + "after each test. Implies -1/--no-concurrency")
>  parser.add_argument("test_profile",
>  metavar="",
>  nargs='+',
> @@ -96,6 +96,11 @@ def main():
>  if args.platform:
>  os.environ['PIGLIT_PLATFORM'] = args.platform
>
> +# If dmesg is requested we must have serial run, this is becasue dmesg
> +# isn't reliable with threaded run
> +if args.dmesg:
> +args.concurrency = "none"
> +
>  # Read the config file
>  if args.config_file:
>  core.PIGLIT_CONFIG.readfp(args.config_file)
> --
> 1.8.5.3
>
> ___
> Piglit mailing list
> Piglit@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/piglit
___
Piglit mailing list
Piglit@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/piglit


Re: [Piglit] [Patch v3 1/4] framework/dmesg: Adds a new module for dmesg

2014-02-03 Thread Ilia Mirkin
On Mon, Feb 3, 2014 at 6:40 PM, Dylan Baker  wrote:
> This modules implements two classes and a helper function. The two
> classes are both dmesg wrapper classes, one, PosixDmesg is used on posix
> systems when requested to actually do checks on dmesg. The second class,
> DummyDmesg, is used to reduce code complexity by providing dummy
> versions of the methods in PosixDmesg. This means that we don't need
> separate code paths for Posix systems wanting to check dmesg, Posix
> systems not wanting to check dmesg, and non-posix systems which lack
> dmesg.
>
> Beyond reducing complexity this module also gives better isolation,
> dmesg is only used in Test.execute(), no where else. Additional classes
> don't need to worry about dmesg that way, it's just available.
>
> v2: - Remove unnecessary assert from PosixDmesg.update_result()
> - simplify replace helper in PoixDmesg.update_result()
> - replace try/except with if check
> - Change PosixDmesg.update_dmesg() to work even if dmesg 'wraps'
> v3: - Try/Except assignment of PosixDmesg._last_message in update_dmesg()
> - Set the dmesg levels the same as the previous implementation
> - Change PosixDmesg into LinuxDmesg and enforce that dmesg has
>   timestamps
>
> Signed-off-by: Dylan Baker 
> ---
>  framework/dmesg.py | 167 
> +
>  1 file changed, 167 insertions(+)
>  create mode 100644 framework/dmesg.py
>
> diff --git a/framework/dmesg.py b/framework/dmesg.py
> new file mode 100644
> index 000..d270aaa
> --- /dev/null
> +++ b/framework/dmesg.py
> @@ -0,0 +1,167 @@
> +# Copyright (c) 2013-2014 Intel Corporation
> +#
> +# Permission is hereby granted, free of charge, to any person obtaining a
> +# copy of this software and associated documentation files (the "Software"),
> +# to deal in the Software without restriction, including without limitation
> +# the rights to use, copy, modify, merge, publish, distribute, sublicense,
> +# and/or sell copies of the Software, and to permit persons to whom the
> +# Software is furnished to do so, subject to the following conditions:
> +#
> +# The above copyright notice and this permission notice (including the next
> +# paragraph) shall be included in all copies or substantial portions of the
> +# Software.
> +#
> +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
> +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
> +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
> +# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
> +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
> +# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
> DEALINGS
> +# IN THE SOFTWARE.
> +
> +""" Module implementing classes for reading posix dmesg
> +
> +Currently this module only has the default DummyDmesg, and a LinuxDmesg.
> +The method used on Linux requires that timetamps are enabled, and no other
> +posix system has timestamps.
> +
> +On OSX and *BSD one would likely want to implement a system that reads the
> +sysloger, since timestamps can be added by the sysloger, and are not inserted
> +by dmesg.
> +
> +"""
> +
> +import re
> +import sys
> +import subprocess
> +
> +__all__ = ['LinuxDmesg', 'DummyDmesg', 'get_dmesg']
> +
> +
> +class LinuxDmesg(object):
> +""" Read dmesg on posix systems
> +
> +This reads the dmesg ring buffer, stores the contents of the buffer, and
> +then compares it whenever called, returning the difference between the
> +calls. It requires timestamps to be enabled.
> +
> +"""
> +DMESG_COMMAND = ['dmesg', '--level', 'emerg,alert,crit,err,warn,notice']
> +
> +def __init__(self):
> +""" Create a dmesg instance """
> +self._last_message = None
> +self._new_messages = []
> +
> +# Populate self.dmesg initially, otherwise the first test will always
> +# be full of dmesg crud.
> +self.update_dmesg()
> +
> +# Do an initial check to ensure that dmesg has timestamps, we need
> +# timestamps to work correctly. A proper linux dmesg timestamp looks
> +# like this: [0.0]
> +if not re.match('\[\s*\d+\.\d+\]', self._last_message):

So if I do dmesg -c; ./piglit-run bla this will fail, right? (I'm
surprised that the string works without the r prefix for raw string,
but I double-checked and it does...)

> +raise EnvironmentError("Your kernel does not seem to support "
> +   "timestamps, which are required by the "
> +   "--dmesg option")
> +
> +def update_result(self, result):
> +""" Takes a TestResult object and updates it with dmesg statuses
> +
> +If dmesg is enabled, and if dmesg has been updated, then replace pass
> +with dmesg-warn and warn and fail with dmesg-fail. If dmesg has not
> +been 

[Piglit] [Patch v3 4/4] piglit-run.py: Restrict dmesg to serial runs

2014-02-03 Thread Dylan Baker
Dmesg reporting has always been inaccurate with concurrent runs, and the
solution to concurrent runs would be to have each run take out a lock,
removing the chance that another test generated an error in dmesg while
it was running. But this effectively makes them a serial run, and at the
cost of greater code complexity. With that in mind it makes more sense
to just force --dmesg to imply -1.

Signed-off-by: Dylan Baker 
---
 piglit-run.py | 7 ++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/piglit-run.py b/piglit-run.py
index faf3adb..d837ccf 100755
--- a/piglit-run.py
+++ b/piglit-run.py
@@ -81,7 +81,7 @@ def main():
 parser.add_argument("--dmesg",
 action="store_true",
 help="Capture a difference in dmesg before and "
- "after each test")
+ "after each test. Implies -1/--no-concurrency")
 parser.add_argument("test_profile",
 metavar="",
 nargs='+',
@@ -96,6 +96,11 @@ def main():
 if args.platform:
 os.environ['PIGLIT_PLATFORM'] = args.platform
 
+# If dmesg is requested we must have serial run, this is becasue dmesg
+# isn't reliable with threaded run
+if args.dmesg:
+args.concurrency = "none"
+
 # Read the config file
 if args.config_file:
 core.PIGLIT_CONFIG.readfp(args.config_file)
-- 
1.8.5.3

___
Piglit mailing list
Piglit@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/piglit


[Piglit] [Patch v3 3/4] Use the new dmesg class

2014-02-03 Thread Dylan Baker
This actually makes use of the new dmesg class rather than the dmesg
functions. It touches a lot of files, but almost all of these changes
are code removal rather than code addition.

Signed-off-by: Dylan Baker 
---
 framework/core.py| 30 -
 framework/exectest.py| 50 ++--
 framework/gleantest.py   |  6 +++---
 framework/shader_test.py |  2 +-
 piglit-run.py|  5 +++--
 tests/es3conform.py  |  6 +++---
 tests/igt.py |  8 
 tests/oglconform.py  |  6 +++---
 8 files changed, 48 insertions(+), 65 deletions(-)

diff --git a/framework/core.py b/framework/core.py
index da2a716..01aa1b5 100644
--- a/framework/core.py
+++ b/framework/core.py
@@ -42,6 +42,7 @@ except ImportError:
 import json
 
 import framework.status as status
+from .dmesg import get_dmesg
 from .threads import synchronized_self
 from .log import log
 
@@ -354,14 +355,13 @@ class TestrunResult:
 
 class Environment:
 def __init__(self, concurrent=True, execute=True, include_filter=[],
- exclude_filter=[], valgrind=False, dmesg=False):
+ exclude_filter=[], valgrind=False):
 self.concurrent = concurrent
 self.execute = execute
 self.filter = []
 self.exclude_filter = []
 self.exclude_tests = set()
 self.valgrind = valgrind
-self.dmesg = dmesg
 
 """
 The filter lists that are read in should be a list of string objects,
@@ -424,7 +424,7 @@ class Test(object):
 def run(self):
 raise NotImplementedError
 
-def execute(self, env, path, json_writer):
+def execute(self, env, path, json_writer, dmesg):
 '''
 Run the test.
 
@@ -440,8 +440,10 @@ class Test(object):
 try:
 status("running")
 time_start = time.time()
+dmesg.update_dmesg()
 self._test_hook_execute_run()
 result = self.run(env)
+result = dmesg.update_result(result)
 time_end = time.time()
 if 'time' not in result:
 result['time'] = time_end - time_start
@@ -476,11 +478,29 @@ class Group(dict):
 pass
 
 
-class TestProfile:
+class TestProfile(object):
 def __init__(self):
 self.tests = Group()
 self.test_list = {}
 self.filters = []
+# Sets a default of a Dummy
+self.dmesg = False
+
+@property
+def dmesg(self):
+""" Return dmesg """
+return self.__dmesg
+
+@dmesg.setter
+def dmesg(self, not_dummy):
+""" Set dmesg
+
+Argumnts:
+not_dummy -- if Truthy dmesg will try to get a PosixDmesg, if Falsy it
+ will get a DummyDmesg
+
+"""
+self.__dmesg = get_dmesg(not_dummy)
 
 def flatten_group_hierarchy(self):
 '''
@@ -544,7 +564,7 @@ class TestProfile:
 
 """
 name, test = pair
-test.execute(env, name, json_writer)
+test.execute(env, name, json_writer, self.dmesg)
 
 # Multiprocessing.dummy is a wrapper around Threading that provides a
 # multiprocessing compatible API
diff --git a/framework/exectest.py b/framework/exectest.py
index 6af1496..4f88dbc 100644
--- a/framework/exectest.py
+++ b/framework/exectest.py
@@ -35,34 +35,6 @@ else:
 PIGLIT_PLATFORM = ''
 
 
-def read_dmesg():
-proc = subprocess.Popen(['dmesg', '-l', 
'emerg,alert,crit,err,warn,notice'], stdout=subprocess.PIPE)
-return proc.communicate()[0].rstrip('\n')
-
-def get_dmesg_diff(old, new):
-# Note that dmesg is a ring buffer, i.e. lines at the beginning may
-# be removed when new lines are added.
-
-# Get the last dmesg timestamp from the old dmesg as string.
-last = old.split('\n')[-1]
-ts = last[:last.find(']')+1]
-if ts == '':
-return ''
-
-# Find the last occurence of the timestamp.
-pos = new.find(ts)
-if pos == -1:
-return new # dmesg was completely overwritten by new messages
-
-while pos != -1:
-start = pos
-pos = new.find(ts, pos+len(ts))
-
-# Find the next line and return the rest of the string.
-nl = new.find('\n', start+len(ts))
-return new[nl+1:] if nl != -1 else ''
-
-
 # ExecTest: A shared base class for tests that simply runs an executable.
 class ExecTest(Test):
 def __init__(self, command):
@@ -85,7 +57,7 @@ class ExecTest(Test):
 return
 self._command = value
 
-def interpretResult(self, out, returncode, results, dmesg):
+def interpretResult(self, out, returncode, results):
 raise NotImplementedError
 return out
 
@@ -111,19 +83,14 @@ class ExecTest(Test):
'--tool=memcheck']
 
 i = 0
-dmesg_diff = ''
 while True:
 if self.skip_test:
 out = "P

[Piglit] [Patch v3 2/4] Adds unit tests for the dmesg module

2014-02-03 Thread Dylan Baker
This adds a few tests for the dmesg class.

It also adds a test hook into core.Test. This is a little ugly, but I
just couldn't come up with any other solution that didn't involve
making the dmesg code more invasive or harder to read.

v2: - Adds tests to simulate dmesg 'wrapping'
v3: - Replace assert with nose.test assert helpers. These have the
  advantage of providing the option to add a message explaining what
  when wrong.
- Adds test for LinuxDmesg's enforcement of timestamps

Signed-off-by: Dylan Baker 
---
 framework/core.py  |   5 +
 framework/tests/dmesg_tests.py | 309 +
 2 files changed, 314 insertions(+)
 create mode 100644 framework/tests/dmesg_tests.py

diff --git a/framework/core.py b/framework/core.py
index a193a2d..da2a716 100644
--- a/framework/core.py
+++ b/framework/core.py
@@ -417,6 +417,10 @@ class Test(object):
 self.runConcurrent = runConcurrent
 self.skip_test = False
 
+# This is a hook for doing some testing on execute right before
+# self.run is called.
+self._test_hook_execute_run = lambda: None
+
 def run(self):
 raise NotImplementedError
 
@@ -436,6 +440,7 @@ class Test(object):
 try:
 status("running")
 time_start = time.time()
+self._test_hook_execute_run()
 result = self.run(env)
 time_end = time.time()
 if 'time' not in result:
diff --git a/framework/tests/dmesg_tests.py b/framework/tests/dmesg_tests.py
new file mode 100644
index 000..6311509
--- /dev/null
+++ b/framework/tests/dmesg_tests.py
@@ -0,0 +1,309 @@
+# Copyright (c) 2014 Intel Corporation
+
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
+""" Provides tests for the dmesg class """
+
+import os
+import sys
+import subprocess
+from nose.plugins.skip import SkipTest
+import nose.tools as nt
+from framework.dmesg import DummyDmesg, LinuxDmesg, get_dmesg
+from framework.core import TestResult, PiglitJSONEncoder, Environment
+from framework.exectest import PlainExecTest
+from framework.gleantest import GleanTest
+from framework.shader_test import ShaderTest
+from framework.glsl_parser_test import GLSLParserTest
+
+
+def _get_dmesg():
+""" checks to ensure dmesg is not DummyDmesg, raises skip if it is
+
+If we are on a non-posix system we will get a dummy dmesg, go ahead and
+skip in that case
+"""
+test = get_dmesg()
+if isinstance(test, DummyDmesg):
+raise SkipTest("A DummyDmesg was returned, testing dmesg impossible.")
+return test
+
+
+def _write_dev_kmesg():
+""" Try to write to /dev/kmesg, skip if not possible
+
+Writing to the dmesg ringbuffer at /dev/kmesg ensures that we varies
+functionality in the LinuxDmesg class will go down the
+dmesg-has-new-entries path.
+
+If we anything goes wrong here just skip.
+"""
+err = subprocess.call(['sudo', 'sh', '-c', 'echo "piglit dmesg test" > 
/dev/kmsg'])
+if err != 0:
+raise SkipTest("Writing to the ringbuffer failed")
+
+
+def test_get_dmesg_dummy():
+""" Test that get_dmesg function returns a Dummy when asked """
+dummy = get_dmesg(not_dummy=False)
+nt.assert_is(type(dummy), DummyDmesg,
+ msg="Error: get_dmesg should have returned DummyDmesg, "
+ "but it actually returned {}".format(type(dummy)))
+
+
+def test_get_dmesg_linux():
+""" Test that get_dmesg() returns a LinuxDmesg instance when asked """
+if not sys.platform.startswith('linux'):
+raise SkipTest("Cannot test a LinuxDmesg on a non linux system")
+posix = _get_dmesg()
+nt.assert_is(type(posix), LinuxDmesg,
+ msg="Error: get_dmesg should have returned LinuxDmesg, "
+ "but it actually returned {}".format(type(posix)))
+
+
+@nt.raises(EnvironmentError)
+def test_linux_dmesg_with_timestamps():
+""" I

[Piglit] [Patch v3 1/4] framework/dmesg: Adds a new module for dmesg

2014-02-03 Thread Dylan Baker
This modules implements two classes and a helper function. The two
classes are both dmesg wrapper classes, one, PosixDmesg is used on posix
systems when requested to actually do checks on dmesg. The second class,
DummyDmesg, is used to reduce code complexity by providing dummy
versions of the methods in PosixDmesg. This means that we don't need
separate code paths for Posix systems wanting to check dmesg, Posix
systems not wanting to check dmesg, and non-posix systems which lack
dmesg.

Beyond reducing complexity this module also gives better isolation,
dmesg is only used in Test.execute(), no where else. Additional classes
don't need to worry about dmesg that way, it's just available.

v2: - Remove unnecessary assert from PosixDmesg.update_result()
- simplify replace helper in PoixDmesg.update_result()
- replace try/except with if check
- Change PosixDmesg.update_dmesg() to work even if dmesg 'wraps'
v3: - Try/Except assignment of PosixDmesg._last_message in update_dmesg()
- Set the dmesg levels the same as the previous implementation
- Change PosixDmesg into LinuxDmesg and enforce that dmesg has
  timestamps

Signed-off-by: Dylan Baker 
---
 framework/dmesg.py | 167 +
 1 file changed, 167 insertions(+)
 create mode 100644 framework/dmesg.py

diff --git a/framework/dmesg.py b/framework/dmesg.py
new file mode 100644
index 000..d270aaa
--- /dev/null
+++ b/framework/dmesg.py
@@ -0,0 +1,167 @@
+# Copyright (c) 2013-2014 Intel Corporation
+#
+# Permission is hereby granted, free of charge, to any person obtaining a
+# copy of this software and associated documentation files (the "Software"),
+# to deal in the Software without restriction, including without limitation
+# the rights to use, copy, modify, merge, publish, distribute, sublicense,
+# and/or sell copies of the Software, and to permit persons to whom the
+# Software is furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice (including the next
+# paragraph) shall be included in all copies or substantial portions of the
+# Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+# IN THE SOFTWARE.
+
+""" Module implementing classes for reading posix dmesg
+
+Currently this module only has the default DummyDmesg, and a LinuxDmesg.
+The method used on Linux requires that timetamps are enabled, and no other
+posix system has timestamps.
+
+On OSX and *BSD one would likely want to implement a system that reads the
+sysloger, since timestamps can be added by the sysloger, and are not inserted
+by dmesg.
+
+"""
+
+import re
+import sys
+import subprocess
+
+__all__ = ['LinuxDmesg', 'DummyDmesg', 'get_dmesg']
+
+
+class LinuxDmesg(object):
+""" Read dmesg on posix systems
+
+This reads the dmesg ring buffer, stores the contents of the buffer, and
+then compares it whenever called, returning the difference between the
+calls. It requires timestamps to be enabled.
+
+"""
+DMESG_COMMAND = ['dmesg', '--level', 'emerg,alert,crit,err,warn,notice']
+
+def __init__(self):
+""" Create a dmesg instance """
+self._last_message = None
+self._new_messages = []
+
+# Populate self.dmesg initially, otherwise the first test will always
+# be full of dmesg crud.
+self.update_dmesg()
+
+# Do an initial check to ensure that dmesg has timestamps, we need
+# timestamps to work correctly. A proper linux dmesg timestamp looks
+# like this: [0.0]
+if not re.match('\[\s*\d+\.\d+\]', self._last_message):
+raise EnvironmentError("Your kernel does not seem to support "
+   "timestamps, which are required by the "
+   "--dmesg option")
+
+def update_result(self, result):
+""" Takes a TestResult object and updates it with dmesg statuses
+
+If dmesg is enabled, and if dmesg has been updated, then replace pass
+with dmesg-warn and warn and fail with dmesg-fail. If dmesg has not
+been updated, it will return the original result passed in.
+
+Arguments:
+result -- A TestResult instance
+
+"""
+
+def replace(res):
+""" helper to replace statuses with the new dmesg status
+
+Replaces pass with dmesg-warn, and warn and fail with dmesg-fail,
+otherwise returns the input
+
+"""
+return {"pass": "dmesg-warn",
+"warn

Re: [Piglit] [PATCH] Add test to verify interpolation at sample position

2014-02-03 Thread Paul Berry
On 9 January 2014 15:43, Anuj Phogat  wrote:

> +void
> +piglit_init(int argc, char**argv)
> +{
> +   if (argc != 2)
> +   print_usage_and_exit(argv[0]);
> +
> +   /* 1st arg: num_samples */
> +   char *endptr = NULL;
> +   num_samples = strtol(argv[1], &endptr, 0);
> +   if (endptr != argv[1] + strlen(argv[1]))
> +   print_usage_and_exit(argv[0]);
> +
> +   piglit_require_extension("GL_ARB_texture_multisample");
> +   piglit_require_extension("GL_ARB_sample_shading");
> +   piglit_require_GLSL_version(130);
> +
> +   /* Skip the test if num_samples > GL_MAX_SAMPLES */
> +   GLint max_samples;
> +   glGetIntegerv(GL_MAX_SAMPLES, &max_samples);
> +   if (num_samples == 0 || num_samples > max_samples)
> +   piglit_report_result(PIGLIT_SKIP);
> +
> +   piglit_fbo_config msConfig(num_samples, piglit_width,
> piglit_height);
> +msConfig.attach_texture = true;
> +   multisampled_fbo.setup(msConfig);
> +
> +   /* Reduced tolerence for stricter color matching */
> +   piglit_set_tolerance_for_bits(16, 16, 16, 16);
> +   draw_prog_left = piglit_build_simple_program(
> +   "#version 130\n"
> +   "#extension GL_ARB_sample_shading: require\n"
> +   "in vec4 piglit_vertex;\n"
> +   "out vec2 test;\n"
> +   "void main() {\n"
> +   "   gl_Position = piglit_vertex;\n"
> +   "   test = piglit_vertex.xy;\n"
> +   "}\n",
> +
> +   "#version 130\n"
> +   "#extension GL_ARB_sample_shading: require\n"
> +   "in vec2 test;\n"
> +   "void main() {\n"
> +   "   gl_FragColor = vec4(abs(test), 0, 1);\n"
> +   "}\n");
> +
> +   draw_prog_right = piglit_build_simple_program(
> +   "#version 130\n"
> +   "uniform vec2 sample_pos;\n"
> +   "in vec4 piglit_vertex;\n"
> +   "out vec2 ref;\n"
> +   "void main() {\n"
> +   "   gl_Position = piglit_vertex;\n"
> +   "   ref = piglit_vertex.xy;\n"
> +   /* Add an offset to account for interplolation
> +* at sample position.
> +*/
> +   "   ref += (sample_pos - 0.5) / 64;\n"
>

As with the patch "Add test to verify 'centroid' qualifier is ignored in
case of persample shading", it would be nice to have a comment here
explaining the origin of the magic number 64 (it comes from the fact that
pattern_width == pattern_height == 128, so the scaling factor between
normalized device coordinates and pixels is 128/2 == 64).

With that fixed, and with the Fbo and FboConfig renames you mentioned in
your follow-up email, this patch is:

Reviewed-by: Paul Berry 

Sorry for the slow review!
___
Piglit mailing list
Piglit@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/piglit


Re: [Piglit] [PATCH] line-flat-clip-color: test flat-shaded line clipping color

2014-02-03 Thread Jose Fonseca


- Original Message -
> This exercises a bug found in Mesa with softpipe, llvmpipe and swrast
> ---
>  tests/all.py |1 +
>  tests/general/CMakeLists.gl.txt  |1 +
>  tests/general/line-flat-clip-color.c |  156
>  ++
>  3 files changed, 158 insertions(+)
>  create mode 100644 tests/general/line-flat-clip-color.c
> 
> diff --git a/tests/all.py b/tests/all.py
> index 5d6ef9a..d1bd617 100644
> --- a/tests/all.py
> +++ b/tests/all.py
> @@ -861,6 +861,7 @@ add_concurrent_test(gl11, 'glinfo')
>  add_plain_test(gl11, 'hiz')
>  add_plain_test(gl11, 'infinite-spot-light')
>  add_plain_test(gl11, 'line-aa-width')
> +add_concurrent_test(gl11, 'line-flat-clip-color')
>  add_plain_test(gl11, 'linestipple')
>  add_plain_test(gl11, 'longprim')
>  add_concurrent_test(gl11, 'masked-clear')
> diff --git a/tests/general/CMakeLists.gl.txt
> b/tests/general/CMakeLists.gl.txt
> index 1933b13..69ed167 100644
> --- a/tests/general/CMakeLists.gl.txt
> +++ b/tests/general/CMakeLists.gl.txt
> @@ -81,6 +81,7 @@ piglit_add_executable (line-aa-width line-aa-width.c)
>  IF (UNIX)
>   target_link_libraries (line-aa-width m)
>  ENDIF (UNIX)
> +piglit_add_executable (line-flat-clip-color line-flat-clip-color.c)
>  piglit_add_executable (longprim longprim.c)
>  piglit_add_executable (masked-clear masked-clear.c)
>  piglit_add_executable (pos-array pos-array.c)
> diff --git a/tests/general/line-flat-clip-color.c
> b/tests/general/line-flat-clip-color.c
> new file mode 100644
> index 000..4cf37b2
> --- /dev/null
> +++ b/tests/general/line-flat-clip-color.c
> @@ -0,0 +1,156 @@
> +/*
> + * Copyright © 2014 VMware, Inc.
> + *
> + * Permission is hereby granted, free of charge, to any person obtaining a
> + * copy of this software and associated documentation files (the
> "Software"),
> + * to deal in the Software without restriction, including without limitation
> + * the rights to use, copy, modify, merge, publish, distribute, sublicense,
> + * and/or sell copies of the Software, and to permit persons to whom the
> + * Software is furnished to do so, subject to the following conditions:
> + *
> + * The above copyright notice and this permission notice (including the next
> + * paragraph) shall be included in all copies or substantial portions of the
> + * Software.
> + *
> + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
> OR
> + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
> + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
> + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
> OTHER
> + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
> + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
> + * DEALINGS IN THE SOFTWARE.
> + */
> +
> +/*
> + * Test flat-shaded clipped line color.
> + * Exercises provoking vertex, line smooth, line width, etc.
> + *
> + * Author: Brian Paul
> + */
> +
> +
> +#include "piglit-util-gl-common.h"
> +
> +PIGLIT_GL_TEST_CONFIG_BEGIN
> + config.supports_gl_compat_version = 10;
> + config.window_visual = PIGLIT_GL_VISUAL_RGB | PIGLIT_GL_VISUAL_DOUBLE;
> +PIGLIT_GL_TEST_CONFIG_END
> +
> +
> +/* far left, far right verts */
> +static const float verts[2][2] = {
> + { -10.0, 0.0 }, { 10.0, 0.0 }
> +};
> +
> +static const float colors[2][3] = {
> + { 1.0, 0.0, 0.0 }, { 0.0, 1.0, 0.0 }
> +};
> +
> +static const GLuint forward_order[2] = { 0, 1 };
> +static const GLuint backward_order[2] = { 1, 0 };
> +
> +static bool have_pv = false;
> +
> +
> +static bool
> +test_one(int order, const float expected[3])
> +{
> + bool pass;
> + int dy, y = piglit_height / 2;
> +
> + glClear(GL_COLOR_BUFFER_BIT);
> +
> + /* draw horizontal line across middle of window */
> + if (order == 0)
> + glDrawElements(GL_LINES, 2, GL_UNSIGNED_INT, forward_order);
> + else
> + glDrawElements(GL_LINES, 2, GL_UNSIGNED_INT, backward_order);
> +
> + /* To be resilient in the face of different line rasterization,
> +  * try several Y values to find where the line was drawn.
> +  */
> + for (dy = -1; dy <= 1; dy++) {
> + GLfloat color[3];
> + glReadPixels(0, y + dy, 1, 1, GL_RGB, GL_FLOAT, color);
> + if (color[0] || color[1] || color[2]) {
> + /* found non-black pixel */
> + /* test all pixels across middle of window */
> + pass = piglit_probe_rect_rgb(0, y + dy, /* x, y */
> +  piglit_width, 1, /* w, h */
> +  expected);
> + break;
> + }
> + }
> +
> + piglit_present_results();
> +
> + return pass;
> +}
> +
> +
> +void
> +piglit_init(int argc, char **argv)
> +{
> + glMatrixMode(GL_PROJECTION);
> + glLoadIdentit

[Piglit] [PATCH] line-flat-clip-color: test flat-shaded line clipping color

2014-02-03 Thread Brian Paul
This exercises a bug found in Mesa with softpipe, llvmpipe and swrast
---
 tests/all.py |1 +
 tests/general/CMakeLists.gl.txt  |1 +
 tests/general/line-flat-clip-color.c |  156 ++
 3 files changed, 158 insertions(+)
 create mode 100644 tests/general/line-flat-clip-color.c

diff --git a/tests/all.py b/tests/all.py
index 5d6ef9a..d1bd617 100644
--- a/tests/all.py
+++ b/tests/all.py
@@ -861,6 +861,7 @@ add_concurrent_test(gl11, 'glinfo')
 add_plain_test(gl11, 'hiz')
 add_plain_test(gl11, 'infinite-spot-light')
 add_plain_test(gl11, 'line-aa-width')
+add_concurrent_test(gl11, 'line-flat-clip-color')
 add_plain_test(gl11, 'linestipple')
 add_plain_test(gl11, 'longprim')
 add_concurrent_test(gl11, 'masked-clear')
diff --git a/tests/general/CMakeLists.gl.txt b/tests/general/CMakeLists.gl.txt
index 1933b13..69ed167 100644
--- a/tests/general/CMakeLists.gl.txt
+++ b/tests/general/CMakeLists.gl.txt
@@ -81,6 +81,7 @@ piglit_add_executable (line-aa-width line-aa-width.c)
 IF (UNIX)
target_link_libraries (line-aa-width m)
 ENDIF (UNIX)
+piglit_add_executable (line-flat-clip-color line-flat-clip-color.c)
 piglit_add_executable (longprim longprim.c)
 piglit_add_executable (masked-clear masked-clear.c)
 piglit_add_executable (pos-array pos-array.c)
diff --git a/tests/general/line-flat-clip-color.c 
b/tests/general/line-flat-clip-color.c
new file mode 100644
index 000..4cf37b2
--- /dev/null
+++ b/tests/general/line-flat-clip-color.c
@@ -0,0 +1,156 @@
+/*
+ * Copyright © 2014 VMware, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+/*
+ * Test flat-shaded clipped line color.
+ * Exercises provoking vertex, line smooth, line width, etc.
+ *
+ * Author: Brian Paul
+ */
+
+
+#include "piglit-util-gl-common.h"
+
+PIGLIT_GL_TEST_CONFIG_BEGIN
+   config.supports_gl_compat_version = 10;
+   config.window_visual = PIGLIT_GL_VISUAL_RGB | PIGLIT_GL_VISUAL_DOUBLE;
+PIGLIT_GL_TEST_CONFIG_END
+
+
+/* far left, far right verts */
+static const float verts[2][2] = {
+   { -10.0, 0.0 }, { 10.0, 0.0 }
+};
+
+static const float colors[2][3] = {
+   { 1.0, 0.0, 0.0 }, { 0.0, 1.0, 0.0 }
+};
+
+static const GLuint forward_order[2] = { 0, 1 };
+static const GLuint backward_order[2] = { 1, 0 };
+
+static bool have_pv = false;
+
+
+static bool
+test_one(int order, const float expected[3])
+{
+   bool pass;
+   int dy, y = piglit_height / 2;
+
+   glClear(GL_COLOR_BUFFER_BIT);
+
+   /* draw horizontal line across middle of window */
+   if (order == 0)
+   glDrawElements(GL_LINES, 2, GL_UNSIGNED_INT, forward_order);
+   else
+   glDrawElements(GL_LINES, 2, GL_UNSIGNED_INT, backward_order);
+
+   /* To be resilient in the face of different line rasterization,
+* try several Y values to find where the line was drawn.
+*/
+   for (dy = -1; dy <= 1; dy++) {
+   GLfloat color[3];
+   glReadPixels(0, y + dy, 1, 1, GL_RGB, GL_FLOAT, color);
+   if (color[0] || color[1] || color[2]) {
+   /* found non-black pixel */
+   /* test all pixels across middle of window */
+   pass = piglit_probe_rect_rgb(0, y + dy, /* x, y */
+piglit_width, 1, /* w, h */
+expected);
+   break;
+   }
+   }
+
+   piglit_present_results();
+
+   return pass;
+}
+
+
+void
+piglit_init(int argc, char **argv)
+{
+   glMatrixMode(GL_PROJECTION);
+   glLoadIdentity();
+   glMatrixMode(GL_MODELVIEW);
+   glLoadIdentity();
+
+   glEnable(GL_VERTEX_ARRAY);
+   glEnable(GL_COLOR_ARRAY);
+   glVertexPointer(2, GL_FLOAT, 0, verts);
+   glColorPointer(3, GL_FLOAT, 0, colors);
+
+   g