--- /dev/null
+"""common Graphviz test functionality"""
+
+import os
+from pathlib import Path
+import platform
+import subprocess
+import tempfile
+from typing import List, Optional, Tuple
+
+def compile_c(src: Path, link: List[str] = [], dst: Optional[Path] = None) \
+ -> Path:
+ '''
+ compile a C program
+ '''
+
+ # if the user did not give us destination, use a temporary path
+ if dst is None:
+ _, dst = tempfile.mkstemp('.exe')
+
+ if platform.system() == 'Windows':
+ # determine which runtime library option we need
+ rtflag = '-MDd' if os.environ.get('configuration') == 'Debug' else '-MD'
+
+ # construct an invocation of MSVC
+ args = ['cl', src, '-Fe:', dst, '-nologo', rtflag]
+ if len(link) > 0:
+ args += ['-link'] + [f'{l}.lib' for l in link]
+
+ else:
+ # construct an invocation of the default C compiler
+ cc = os.environ.get('CC', 'cc')
+ args = [cc, '-std=c99', src, '-o', dst]
+ if len(link) > 0:
+ args += [f'-l{l}' for l in link]
+
+ # compile the program
+ try:
+ subprocess.check_call(args)
+ except subprocess.CalledProcessError:
+ dst.unlink(missing_ok=True)
+ raise
+
+ return dst
+
+def run_c(src: Path, args: [str] = [], input: str = '', link: List[str] = []) \
+ -> Tuple[int, str, str]:
+ '''
+ compile and run a C program
+ '''
+
+ # create some temporary space to work in
+ with tempfile.TemporaryDirectory() as tmp:
+
+ # output filename to write our compiled code to
+ exe = Path(tmp) / 'a.exe'
+
+ # compile the program
+ compile_c(src, link, exe)
+
+ # run it
+ p = subprocess.run([exe] + args, input=input, stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE, universal_newlines=True)
+
+ return p.returncode, p.stdout, p.stderr
import pytest
import shutil
import subprocess
-import tempfile
+import sys
-def c_compiler():
- '''find the system's C compiler'''
- if platform.system() == 'Windows':
- return "cl"
- else:
- return os.environ.get('CC', 'cc')
+sys.path.append(os.path.dirname(__file__))
+from gvtest import run_c
@pytest.mark.parametrize('src', ['demo.c', 'dot.c', 'example.c', 'neatopack.c',
'simple.c'])
# construct an absolute path to the example
filepath = Path(__file__).parent.resolve() / '..' / 'dot.demo' / src
- cc = c_compiler()
-
- libs = ('cgraph', 'gvc')
-
- # create some scratch space to work in
- with tempfile.TemporaryDirectory() as tmp:
-
- # compile our test code
- exe = Path(tmp) / 'a.exe'
- if platform.system() == 'Windows':
- debug = os.environ.get('configuration') == 'Debug'
- rt_lib_option = '-MDd' if debug else '-MD'
- subprocess.check_call([cc, filepath, '-Fe:', exe, '-nologo',
- rt_lib_option, '-link'] + [f'{l}.lib' for l in libs])
- else:
- subprocess.check_call([cc, '-std=c99', '-o', exe, filepath]
- + [f'-l{l}' for l in libs])
-
- # FIXME: Remove skip of execution of neatopack.c example when
- # https://gitlab.com/graphviz/graphviz/-/issues/1800 has been fixed
- if src == 'neatopack.c':
- pytest.skip('Executing neatopack gives segmentation fault (#1800)')
-
- # run the example
- args = ['-Kneato'] if src in ['demo.c', 'dot.c'] else [];
-
- p = subprocess.Popen(
- [exe] + args,
- stdin=subprocess.PIPE,
- universal_newlines=True,
- )
- p.communicate(input='graph {a -- b}')
- print(f'returncode: {p.returncode} = 0x{p.returncode:08x}')
- assert p.returncode == 0
+ libs = ['cgraph', 'gvc']
+
+ # FIXME: Remove skip of execution of neatopack.c example when
+ # https://gitlab.com/graphviz/graphviz/-/issues/1800 has been fixed
+ if src == 'neatopack.c':
+ pytest.skip('Executing neatopack gives segmentation fault (#1800)')
+
+ # run the example
+ args = ['-Kneato'] if src in ['demo.c', 'dot.c'] else [];
+
+ ret, _, _ = run_c(filepath, args, 'graph {a -- b}', libs)
+
+ print(f'returncode: {ret} = 0x{ret:08x}')
+ if ret != 0:
+ print(out)
+ print(err)
+ assert ret == 0
@pytest.mark.parametrize('src', ['addrings', 'attr', 'bbox', 'bipart',
'chkedges', 'clustg', 'collapse', 'cycle', 'deghist', 'delmulti', 'depath',
import subprocess
import os
import re
+import sys
import stat
import tempfile
from typing import List, Optional, Tuple
+sys.path.append(os.path.dirname(__file__))
+from gvtest import run_c
+
# The terminology used in rtest.py is a little inconsistent. At the
# end it reports the total number of tests, the number of "failures"
# (crashes) and the number of "changes" (which is the number of tests
# FIXME: re-enable when all tests pass on all platforms
# assert result.returncode == 0
-def compile_c(src: Path, link: List[str] = [], dst: Optional[Path] = None) \
- -> Path:
- '''
- compile a C program
- '''
-
- # if the user did not give us destination, use a temporary path
- if dst is None:
- _, dst = tempfile.mkstemp('.exe')
-
- if platform.system() == 'Windows':
- # determine which runtime library option we need
- rtflag = '-MDd' if os.environ.get('configuration') == 'Debug' else '-MD'
-
- # construct an invocation of MSVC
- args = ['cl', src, '-Fe:', dst, '-nologo', rtflag]
- if len(link) > 0:
- args += ['-link'] + [f'{l}.lib' for l in link]
-
- else:
- # construct an invocation of the default C compiler
- cc = os.environ.get('CC', 'cc')
- args = [cc, '-std=c99', src, '-o', dst]
- if len(link) > 0:
- args += [f'-l{l}' for l in link]
-
- # compile the program
- try:
- subprocess.check_call(args)
- except subprocess.CalledProcessError:
- dst.unlink(missing_ok=True)
- raise
-
- return dst
-
-def run_c(src: Path, args: [str] = [], input: str = '', link: List[str] = []) \
- -> Tuple[int, str, str]:
- '''
- compile and run a C program
- '''
-
- # create some temporary space to work in
- with tempfile.TemporaryDirectory() as tmp:
-
- # output filename to write our compiled code to
- exe = Path(tmp) / 'a.exe'
-
- # compile the program
- compile_c(src, link, exe)
-
- # run it
- p = subprocess.run([exe] + args, input=input, stdout=subprocess.PIPE,
- stderr=subprocess.PIPE, universal_newlines=True)
-
- return p.returncode, p.stdout, p.stderr
-
def test_131():
'''
PIC back end should produce valid output