Skip to content

Commit a08018c

Browse files
updated test and fixed part of #21
I completely rewrote the tests in a pythonic way. Now running these tests is as easy as python -m unittest discover in test/ I'm planning to add more tests and especially unittest for command line parsing which has several issues (-mllvm flags) for instance. The only test I did not move is : `mystery: otool -X -s __LLVM __llvm_bc main > main.otool xxd -r main.otool xxd -r main.otool main.xxd` as I could not understand what it does and could not find otool on my ubuntu system. (any help there ?) The fix for as is because it is not in the top-level directory.
1 parent a82b88d commit a08018c

File tree

11 files changed

+232
-53
lines changed

11 files changed

+232
-53
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
11
*.pyc
2+
.idea

driver/as

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,17 @@
1111
# compiler). We'll link this together at a later stage.
1212

1313
from __future__ import absolute_import
14+
import sys
15+
import os
1416

15-
from .utils import *
17+
sys.path.append(os.path.dirname(os.path.dirname(os.path.realpath(__file__))))
18+
19+
from driver.utils import *
1620
from subprocess import *
17-
from .popenwrapper import Popen
21+
from driver.popenwrapper import Popen
1822

23+
import logging
24+
logging.basicConfig()
1925

2026
class BCFilter(ArgumentListFilter):
2127
def __init__(self, arglist):

test/Makefile

Lines changed: 0 additions & 51 deletions
This file was deleted.

test/test_base_driver.py

Lines changed: 171 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,171 @@
1+
#!/usr/bin/env python
2+
# -*- Coding: UTF-8 -*-
3+
4+
__author__ = 'Benjamin Schubert, ben.c.schubert@gmail.com'
5+
6+
from abc import abstractproperty
7+
import os
8+
import shutil
9+
import subprocess
10+
import unittest
11+
12+
13+
test_output_directory = "/tmp/test-wllvm"
14+
test_files_directory = os.path.join(os.path.dirname(os.path.realpath(__file__)), "test_files")
15+
root_directory = os.path.join(os.path.dirname(os.path.dirname(__file__)))
16+
17+
18+
class BaseDriverTest(unittest.TestCase):
19+
"""
20+
This is a BaseDriverTest class. Can be used to generically test that every driver works correctly with different
21+
code examples without any problem. This class is meant to be overridden
22+
"""
23+
@classmethod
24+
def setUpClass(cls):
25+
"""
26+
This is a base class that should not be run in tests, skip it
27+
:return:
28+
"""
29+
if cls is BaseDriverTest:
30+
raise unittest.SkipTest("Skip BaseDriverTest, it's a base class")
31+
32+
@abstractproperty
33+
def env(self):
34+
"""
35+
Defines all necessary environment variables to allow the driver to be tested, assembly seen in "Usage" in the README
36+
"""
37+
return None
38+
39+
def setUp(self):
40+
"""
41+
Creates the test directory in /tmp
42+
:return:
43+
"""
44+
if not os.path.exists(test_output_directory):
45+
os.makedirs(test_output_directory)
46+
47+
def tearDown(self):
48+
"""
49+
remove all temporary test files
50+
:return:
51+
"""
52+
shutil.rmtree(test_output_directory)
53+
54+
def launch_proc(self, cmd):
55+
"""
56+
Launches cmd with environment and in test_output_directory
57+
:param cmd: command to launch
58+
:return: the subprocess instance
59+
"""
60+
return subprocess.Popen(cmd, shell=True, env=self.env, cwd=test_output_directory)
61+
62+
def create_objects(self):
63+
"""
64+
Creates some objects used by tests
65+
:return:
66+
"""
67+
for f in ["foo.c", "bar.c", "baz.c", "main.c"]:
68+
self.assertEqual(self.launch_proc("${{CC}} {dir}/{f} -c".format(dir=test_files_directory, f=f)).wait(), 0)
69+
70+
def create_archive(self):
71+
"""
72+
creates the libfoo.a archive
73+
:return:
74+
"""
75+
proc1 = self.launch_proc("ar cr libfoo.a foo.o bar.o baz.o")
76+
self.assertEqual(proc1.wait(), 0)
77+
78+
def test_can_compile_simple_file(self):
79+
"""
80+
Checks that it is possible to compile a single simple file
81+
:return:
82+
"""
83+
proc = self.launch_proc("${{CXX}} -o hello {}/hello.cc".format(test_files_directory))
84+
self.assertEqual(proc.wait(), 0)
85+
86+
def test_can_compile_multiple_file_in_one_object(self):
87+
"""
88+
Checks that is is possible to compile multiple files into one executable
89+
:return:
90+
"""
91+
proc = self.launch_proc(
92+
"${{CC}} {dir}/foo.c {dir}/bar.c {dir}/baz.c {dir}/main.c -o main".format(dir=test_files_directory)
93+
)
94+
self.assertEqual(proc.wait(), 0)
95+
96+
def test_can_compile_and_link_multiple_object(self):
97+
"""
98+
Checks that is is possible to compile first then link the compiled objects together
99+
:return:
100+
"""
101+
proc1 = self.launch_proc(
102+
"${{CC}} {dir}/foo.c {dir}/bar.c {dir}/baz.c {dir}/main.c -c".format(dir=test_files_directory)
103+
)
104+
self.assertEqual(proc1.wait(), 0)
105+
106+
proc2 = self.launch_proc("${CC} foo.o bar.o baz.o main.o -o main")
107+
self.assertEqual(proc2.wait(), 0)
108+
109+
def test_can_compile_and_link_object_and_source_object(self):
110+
"""
111+
Checks that is is possible to compile some objects first, then link them while compiling others
112+
:return:
113+
"""
114+
proc1 = self.launch_proc("${{CC}} {dir}/foo.c {dir}/bar.c -c".format(dir=test_files_directory))
115+
self.assertEqual(proc1.wait(), 0)
116+
117+
proc2 = self.launch_proc("${{CC}} foo.o bar.o {dir}/baz.c {dir}/main.c -o main".format(dir=test_files_directory))
118+
self.assertEqual(proc2.wait(), 0)
119+
120+
def test_can_link_multiple_objects_together(self):
121+
"""
122+
Checks that it is possible to link multiple objects together
123+
:return:
124+
"""
125+
self.create_objects()
126+
proc = self.launch_proc("${CC} foo.o bar.o baz.o main.o -o main")
127+
self.assertEqual(proc.wait(), 0)
128+
129+
def test_can_create_archive_from_object_created(self):
130+
"""
131+
Checks that it is possible to create a valid archive from the created objects
132+
:return:
133+
"""
134+
self.create_objects()
135+
self.create_archive()
136+
137+
proc2 = self.launch_proc("ranlib libfoo.a")
138+
self.assertEqual(proc2.wait(), 0)
139+
140+
def test_can_create_dynamic_library_from_objects(self):
141+
"""
142+
Checks that is is possible to create a dynamic library from the objects
143+
:return:
144+
"""
145+
self.create_objects()
146+
proc = self.launch_proc("${CC} -dynamiclib foo.o bar.o baz.o main.o -o libfoo.dylib")
147+
self.assertEqual(proc.wait(), 0)
148+
149+
def test_can_deadstrip_dynamic_library(self):
150+
"""
151+
Checks that is is possible to create a deadstripped dynamic library from the objects
152+
:return:
153+
"""
154+
self.create_objects()
155+
proc = self.launch_proc("${CC} -dynamiclib -Wl,-dead_strip foo.o bar.o baz.o main.o -o libfoo.dylib")
156+
self.assertEqual(proc.wait(), 0)
157+
158+
def test_can_link_with_archive(self):
159+
"""
160+
Checks that is is possible to link with a created archive
161+
:return:
162+
"""
163+
self.create_objects()
164+
self.create_archive()
165+
166+
proc = self.launch_proc("${CC} main.o libfoo.a -o main.arch")
167+
self.assertEqual(proc.wait(), 0)
168+
169+
170+
if __name__ == '__main__':
171+
unittest.main()

test/test_clang_driver.py

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
#!/usr/bin/env python
2+
# -*- Coding: UTF-8 -*-
3+
import os
4+
from test_base_driver import root_directory, BaseDriverTest
5+
6+
__author__ = 'Benjamin Schubert, ben.c.schubert@gmail.com'
7+
8+
9+
10+
class ClangDriverTest(BaseDriverTest):
11+
"""
12+
Clang driver tester
13+
"""
14+
@property
15+
def env(self):
16+
"""
17+
The different environment variables used by subprocess to compile with clang and wllvm
18+
:return:
19+
"""
20+
env = os.environ.copy()
21+
env["CC"] = "wllvm"
22+
env["CXX"] = "wllvm++"
23+
env["LLVM_COMPILER"] = "clang"
24+
env["PATH"] = "{}:{}".format(root_directory, os.environ["PATH"])
25+
return env

test/test_dragonegg_driver.py

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
#!/usr/bin/env python
2+
# -*- Coding: UTF-8 -*-
3+
import os
4+
from test_base_driver import root_directory, BaseDriverTest
5+
6+
__author__ = 'Benjamin Schubert, ben.c.schubert@gmail.com'
7+
8+
9+
class DragonEggDriverTest(BaseDriverTest):
10+
"""
11+
Dragonegg driver tester
12+
"""
13+
@property
14+
def env(self):
15+
"""
16+
The different environment variables used by subprocess to compile with dragonegg and wllvm
17+
:return:
18+
"""
19+
env = os.environ.copy()
20+
env["CC"] = "wllvm"
21+
env["CXX"] = "wllvm++"
22+
env["LLVM_COMPILER"] = "dragonegg"
23+
env["PATH"] = "{}:{}".format(root_directory, os.environ["PATH"])
24+
# FIXME find dragonegg path generically
25+
env["LLVM_DRAGONEGG_PLUGIN"] = "/usr/lib/gcc/x86_64-linux-gnu/4.7/plugin/dragonegg.so"
26+
env["LLVM_GCC_PREFIX"] = "llvm-"
27+
return env
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.

0 commit comments

Comments
 (0)