@ -27,6 +27,7 @@ import unittest
import platform
import platform
import pickle
import pickle
import functools
import functools
import io
from itertools import chain
from itertools import chain
from unittest import mock
from unittest import mock
from configparser import ConfigParser
from configparser import ConfigParser
@ -54,6 +55,8 @@ from mesonbuild.dependencies import PkgConfigDependency, ExternalProgram
from mesonbuild . build import Target
from mesonbuild . build import Target
import mesonbuild . modules . pkgconfig
import mesonbuild . modules . pkgconfig
from mesonbuild . mtest import TAPParser , TestResult
from run_tests import (
from run_tests import (
Backend , FakeBuild , FakeCompilerOptions ,
Backend , FakeBuild , FakeCompilerOptions ,
ensure_backend_detects_changes , exe_suffix , get_backend_commands ,
ensure_backend_detects_changes , exe_suffix , get_backend_commands ,
@ -5728,6 +5731,272 @@ class CrossFileTests(BasePlatformTests):
' -Ddef_sysconfdir=sysconfbar ' ] )
' -Ddef_sysconfdir=sysconfbar ' ] )
class TAPParserTests ( unittest . TestCase ) :
def assert_test ( self , events , * * kwargs ) :
if ' explanation ' not in kwargs :
kwargs [ ' explanation ' ] = None
self . assertEqual ( next ( events ) , TAPParser . Test ( * * kwargs ) )
def assert_plan ( self , events , * * kwargs ) :
if ' skipped ' not in kwargs :
kwargs [ ' skipped ' ] = False
if ' explanation ' not in kwargs :
kwargs [ ' explanation ' ] = None
self . assertEqual ( next ( events ) , TAPParser . Plan ( * * kwargs ) )
def assert_version ( self , events , * * kwargs ) :
self . assertEqual ( next ( events ) , TAPParser . Version ( * * kwargs ) )
def assert_error ( self , events ) :
self . assertEqual ( type ( next ( events ) ) , TAPParser . Error )
def assert_bailout ( self , events , * * kwargs ) :
self . assertEqual ( next ( events ) , TAPParser . Bailout ( * * kwargs ) )
def assert_last ( self , events ) :
with self . assertRaises ( StopIteration ) :
next ( events )
def parse_tap ( self , s ) :
parser = TAPParser ( io . StringIO ( s ) )
return iter ( parser . parse ( ) )
def parse_tap_v13 ( self , s ) :
events = self . parse_tap ( ' TAP version 13 \n ' + s )
self . assert_version ( events , version = 13 )
return events
def test_empty ( self ) :
events = self . parse_tap ( ' ' )
self . assert_last ( events )
def test_empty_plan ( self ) :
events = self . parse_tap ( ' 1..0 ' )
self . assert_plan ( events , count = 0 , late = False , skipped = True )
self . assert_last ( events )
def test_plan_directive ( self ) :
events = self . parse_tap ( ' 1..0 # skipped for some reason ' )
self . assert_plan ( events , count = 0 , late = False , skipped = True ,
explanation = ' for some reason ' )
self . assert_last ( events )
events = self . parse_tap ( ' 1..1 # skipped for some reason \n ok 1 ' )
self . assert_error ( events )
self . assert_plan ( events , count = 1 , late = False , skipped = True ,
explanation = ' for some reason ' )
self . assert_test ( events , number = 1 , name = ' ' , result = TestResult . OK )
self . assert_last ( events )
events = self . parse_tap ( ' 1..1 # todo not supported here \n ok 1 ' )
self . assert_error ( events )
self . assert_plan ( events , count = 1 , late = False , skipped = False ,
explanation = ' not supported here ' )
self . assert_test ( events , number = 1 , name = ' ' , result = TestResult . OK )
self . assert_last ( events )
def test_one_test_ok ( self ) :
events = self . parse_tap ( ' ok ' )
self . assert_test ( events , number = 1 , name = ' ' , result = TestResult . OK )
self . assert_last ( events )
def test_one_test_with_number ( self ) :
events = self . parse_tap ( ' ok 1 ' )
self . assert_test ( events , number = 1 , name = ' ' , result = TestResult . OK )
self . assert_last ( events )
def test_one_test_with_name ( self ) :
events = self . parse_tap ( ' ok 1 abc ' )
self . assert_test ( events , number = 1 , name = ' abc ' , result = TestResult . OK )
self . assert_last ( events )
def test_one_test_not_ok ( self ) :
events = self . parse_tap ( ' not ok ' )
self . assert_test ( events , number = 1 , name = ' ' , result = TestResult . FAIL )
self . assert_last ( events )
def test_one_test_todo ( self ) :
events = self . parse_tap ( ' not ok 1 abc # TODO ' )
self . assert_test ( events , number = 1 , name = ' abc ' , result = TestResult . EXPECTEDFAIL )
self . assert_last ( events )
events = self . parse_tap ( ' ok 1 abc # TODO ' )
self . assert_test ( events , number = 1 , name = ' abc ' , result = TestResult . UNEXPECTEDPASS )
self . assert_last ( events )
def test_one_test_skip ( self ) :
events = self . parse_tap ( ' ok 1 abc # SKIP ' )
self . assert_test ( events , number = 1 , name = ' abc ' , result = TestResult . SKIP )
self . assert_last ( events )
def test_one_test_skip_failure ( self ) :
events = self . parse_tap ( ' not ok 1 abc # SKIP ' )
self . assert_test ( events , number = 1 , name = ' abc ' , result = TestResult . FAIL )
self . assert_last ( events )
def test_many_early_plan ( self ) :
events = self . parse_tap ( ' 1..4 \n ok 1 \n not ok 2 \n ok 3 \n not ok 4 ' )
self . assert_plan ( events , count = 4 , late = False )
self . assert_test ( events , number = 1 , name = ' ' , result = TestResult . OK )
self . assert_test ( events , number = 2 , name = ' ' , result = TestResult . FAIL )
self . assert_test ( events , number = 3 , name = ' ' , result = TestResult . OK )
self . assert_test ( events , number = 4 , name = ' ' , result = TestResult . FAIL )
self . assert_last ( events )
def test_many_late_plan ( self ) :
events = self . parse_tap ( ' ok 1 \n not ok 2 \n ok 3 \n not ok 4 \n 1..4 ' )
self . assert_test ( events , number = 1 , name = ' ' , result = TestResult . OK )
self . assert_test ( events , number = 2 , name = ' ' , result = TestResult . FAIL )
self . assert_test ( events , number = 3 , name = ' ' , result = TestResult . OK )
self . assert_test ( events , number = 4 , name = ' ' , result = TestResult . FAIL )
self . assert_plan ( events , count = 4 , late = True )
self . assert_last ( events )
def test_directive_case ( self ) :
events = self . parse_tap ( ' ok 1 abc # skip ' )
self . assert_test ( events , number = 1 , name = ' abc ' , result = TestResult . SKIP )
self . assert_last ( events )
events = self . parse_tap ( ' ok 1 abc # ToDo ' )
self . assert_test ( events , number = 1 , name = ' abc ' , result = TestResult . UNEXPECTEDPASS )
self . assert_last ( events )
def test_directive_explanation ( self ) :
events = self . parse_tap ( ' ok 1 abc # skip why ' )
self . assert_test ( events , number = 1 , name = ' abc ' , result = TestResult . SKIP ,
explanation = ' why ' )
self . assert_last ( events )
events = self . parse_tap ( ' ok 1 abc # ToDo Because ' )
self . assert_test ( events , number = 1 , name = ' abc ' , result = TestResult . UNEXPECTEDPASS ,
explanation = ' Because ' )
self . assert_last ( events )
def test_one_test_early_plan ( self ) :
events = self . parse_tap ( ' 1..1 \n ok ' )
self . assert_plan ( events , count = 1 , late = False )
self . assert_test ( events , number = 1 , name = ' ' , result = TestResult . OK )
self . assert_last ( events )
def test_one_test_late_plan ( self ) :
events = self . parse_tap ( ' ok \n 1..1 ' )
self . assert_test ( events , number = 1 , name = ' ' , result = TestResult . OK )
self . assert_plan ( events , count = 1 , late = True )
self . assert_last ( events )
def test_out_of_order ( self ) :
events = self . parse_tap ( ' ok 2 ' )
self . assert_error ( events )
self . assert_test ( events , number = 2 , name = ' ' , result = TestResult . OK )
self . assert_last ( events )
def test_middle_plan ( self ) :
events = self . parse_tap ( ' ok 1 \n 1..2 \n ok 2 ' )
self . assert_test ( events , number = 1 , name = ' ' , result = TestResult . OK )
self . assert_plan ( events , count = 2 , late = True )
self . assert_error ( events )
self . assert_test ( events , number = 2 , name = ' ' , result = TestResult . OK )
self . assert_last ( events )
def test_too_many_plans ( self ) :
events = self . parse_tap ( ' 1..1 \n 1..2 \n ok 1 ' )
self . assert_plan ( events , count = 1 , late = False )
self . assert_error ( events )
self . assert_test ( events , number = 1 , name = ' ' , result = TestResult . OK )
self . assert_last ( events )
def test_too_many ( self ) :
events = self . parse_tap ( ' ok 1 \n not ok 2 \n 1..1 ' )
self . assert_test ( events , number = 1 , name = ' ' , result = TestResult . OK )
self . assert_test ( events , number = 2 , name = ' ' , result = TestResult . FAIL )
self . assert_plan ( events , count = 1 , late = True )
self . assert_error ( events )
self . assert_last ( events )
events = self . parse_tap ( ' 1..1 \n ok 1 \n not ok 2 ' )
self . assert_plan ( events , count = 1 , late = False )
self . assert_test ( events , number = 1 , name = ' ' , result = TestResult . OK )
self . assert_test ( events , number = 2 , name = ' ' , result = TestResult . FAIL )
self . assert_error ( events )
self . assert_last ( events )
def test_too_few ( self ) :
events = self . parse_tap ( ' ok 1 \n not ok 2 \n 1..3 ' )
self . assert_test ( events , number = 1 , name = ' ' , result = TestResult . OK )
self . assert_test ( events , number = 2 , name = ' ' , result = TestResult . FAIL )
self . assert_plan ( events , count = 3 , late = True )
self . assert_error ( events )
self . assert_last ( events )
events = self . parse_tap ( ' 1..3 \n ok 1 \n not ok 2 ' )
self . assert_plan ( events , count = 3 , late = False )
self . assert_test ( events , number = 1 , name = ' ' , result = TestResult . OK )
self . assert_test ( events , number = 2 , name = ' ' , result = TestResult . FAIL )
self . assert_error ( events )
self . assert_last ( events )
def test_too_few_bailout ( self ) :
events = self . parse_tap ( ' 1..3 \n ok 1 \n not ok 2 \n Bail out! no third test ' )
self . assert_plan ( events , count = 3 , late = False )
self . assert_test ( events , number = 1 , name = ' ' , result = TestResult . OK )
self . assert_test ( events , number = 2 , name = ' ' , result = TestResult . FAIL )
self . assert_bailout ( events , message = ' no third test ' )
self . assert_last ( events )
def test_diagnostics ( self ) :
events = self . parse_tap ( ' 1..1 \n # ignored \n ok 1 ' )
self . assert_plan ( events , count = 1 , late = False )
self . assert_test ( events , number = 1 , name = ' ' , result = TestResult . OK )
self . assert_last ( events )
events = self . parse_tap ( ' # ignored \n 1..1 \n ok 1 \n # ignored too ' )
self . assert_plan ( events , count = 1 , late = False )
self . assert_test ( events , number = 1 , name = ' ' , result = TestResult . OK )
self . assert_last ( events )
events = self . parse_tap ( ' # ignored \n ok 1 \n 1..1 \n # ignored too ' )
self . assert_test ( events , number = 1 , name = ' ' , result = TestResult . OK )
self . assert_plan ( events , count = 1 , late = True )
self . assert_last ( events )
def test_unexpected ( self ) :
events = self . parse_tap ( ' 1..1 \n invalid \n ok 1 ' )
self . assert_plan ( events , count = 1 , late = False )
self . assert_error ( events )
self . assert_test ( events , number = 1 , name = ' ' , result = TestResult . OK )
self . assert_last ( events )
def test_version ( self ) :
events = self . parse_tap ( ' TAP version 13 \n ' )
self . assert_version ( events , version = 13 )
self . assert_last ( events )
events = self . parse_tap ( ' TAP version 12 \n ' )
self . assert_error ( events )
self . assert_last ( events )
events = self . parse_tap ( ' 1..0 \n TAP version 13 \n ' )
self . assert_plan ( events , count = 0 , late = False , skipped = True )
self . assert_error ( events )
self . assert_last ( events )
def test_yaml ( self ) :
events = self . parse_tap_v13 ( ' ok \n --- \n foo: abc \n bar: def \n ... \n ok 2 ' )
self . assert_test ( events , number = 1 , name = ' ' , result = TestResult . OK )
self . assert_test ( events , number = 2 , name = ' ' , result = TestResult . OK )
self . assert_last ( events )
events = self . parse_tap_v13 ( ' ok \n --- \n foo: abc \n bar: def ' )
self . assert_test ( events , number = 1 , name = ' ' , result = TestResult . OK )
self . assert_error ( events )
self . assert_last ( events )
events = self . parse_tap_v13 ( ' ok 1 \n --- \n foo: abc \n bar: def \n not ok 2 ' )
self . assert_test ( events , number = 1 , name = ' ' , result = TestResult . OK )
self . assert_error ( events )
self . assert_test ( events , number = 2 , name = ' ' , result = TestResult . FAIL )
self . assert_last ( events )
def unset_envs ( ) :
def unset_envs ( ) :
# For unit tests we must fully control all command lines
# For unit tests we must fully control all command lines
# so that there are no unexpected changes coming from the
# so that there are no unexpected changes coming from the
@ -5741,6 +6010,8 @@ def main():
unset_envs ( )
unset_envs ( )
cases = [ ' InternalTests ' , ' DataTests ' , ' AllPlatformTests ' , ' FailureTests ' ,
cases = [ ' InternalTests ' , ' DataTests ' , ' AllPlatformTests ' , ' FailureTests ' ,
' PythonTests ' , ' NativeFileTests ' , ' RewriterTests ' , ' CrossFileTests ' ,
' PythonTests ' , ' NativeFileTests ' , ' RewriterTests ' , ' CrossFileTests ' ,
' TAPParserTests ' ,
' LinuxlikeTests ' , ' LinuxCrossArmTests ' , ' LinuxCrossMingwTests ' ,
' LinuxlikeTests ' , ' LinuxCrossArmTests ' , ' LinuxCrossMingwTests ' ,
' WindowsTests ' , ' DarwinTests ' ]
' WindowsTests ' , ' DarwinTests ' ]