summaryrefslogtreecommitdiff
path: root/test-export/test-export.py
blob: 84824350042a5a32fc8158e78d72c072769d78b7 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
#!/usr/bin/env python3
#
# Check if find_package(Libevent COMPONENTS xxx) can get the correct library.
# Note: this script has only been tested on python3.
# Usage:
#   cd cmake-build-dir
#   cmake <options> .. && cmake --build .
#   python /path/to/test-export.py [static|shared]

import sys
import os
import shutil
import platform
import subprocess
import tempfile

results = ("success", "failure")
FNULL = open(os.devnull, 'wb')
script_dir = os.path.split(os.path.realpath(sys.argv[0]))[0]
# working_dir is cmake build dir
working_dir = os.getcwd()
if len(sys.argv) > 1 and sys.argv[1] == "static":
    link_type = sys.argv[1]
else:
    link_type = "shared"


def exec_cmd(cmd, silent):
    p = subprocess.Popen(cmd, shell=True)
    p.communicate()
    return p.poll()


def link_and_run(link, code):
    """Check if the source code matches the library component.

    Compile source code relative to one component and link to another component.
    Then run the generated executor.

    Args:
        link: The name of component that the source code will link with.
        code: The source code related component name.

    Returns:
        Returns 0 if links and runs successfully, otherwise 1.
    """
    exec_cmd("cmake --build . -v --target clean", True)
    arch = ''
    if platform.system() == "Windows":
        arch = '-A x64'
    cmd = 'cmake .. %s -DEVENT__LINK_COMPONENT=%s -DEVENT__CODE_COMPONENT=%s' % (
        arch, link, code)
    if link_type == "static":
        cmd = "".join([cmd, " -DLIBEVENT_STATIC_LINK=1"])
    r = exec_cmd(cmd, True)
    if r == 0:
        r = exec_cmd('cmake --build . -v', True)
        if r == 0:
            r = exec_cmd('ctest', True)
    if r != 0:
        r = 1
    return r

# expect  0:success 1:failure
def testcase(link, code, expect):
    r = link_and_run(link, code)
    if link == "":
        link = "all"
    if code == "":
        code = "all"
    if r != expect:
        print('[test-export] fail: link %s and run %s expects %s but gets %s.' %
              (link, code, results[expect], results[r]))
        sys.exit(1)
    else:
        print('[test-export] success: link %s and run %s expects and gets %s.' %
              (link, code, results[r]))

# Dependency relationships between libevent libraries:
#   core:        none
#   extra:       core
#   pthreads:    core,pthread
#   openssl:     core,openssl
def test_group():
    testcase("core", "core", 0)
    testcase("extra", "extra", 0)
    testcase("openssl", "openssl", 0)
    testcase("mbedtls", "mbedtls", 0)
    testcase("", "", 0)
    testcase("extra", "core", 0)
    testcase("openssl", "core", 0)
    testcase("mbedtls", "core", 0)
    testcase("core", "extra", 1)
    testcase("core", "openssl", 1)
    testcase("extra", "openssl", 1)
    testcase("openssl", "extra", 1)
    testcase("core", "mbedtls", 1)
    testcase("extra", "mbedtls", 1)
    testcase("mbedtls", "extra", 1)
    if platform.system() != "Windows":
        testcase("pthreads", "pthreads", 0)
        testcase("pthreads", "core", 0)
        testcase("core", "pthreads", 1)
        testcase("extra", "pthreads", 1)
        testcase("pthreads", "extra", 1)
        testcase("pthreads", "openssl", 1)
        testcase("openssl", "pthreads", 1)
        testcase("pthreads", "mbedtls", 1)
        testcase("mbedtls", "pthreads", 1)


shutil.rmtree(os.path.join(script_dir, "build"), ignore_errors=True)


def run_test_group():
    os.chdir(script_dir)
    if not os.path.isdir("build"):
        os.mkdir("build")
    os.chdir("build")
    test_group()
    os.chdir(working_dir)


need_exportdll = False
if link_type == "shared" and platform.system() == "Windows":
    need_exportdll = True

# On Windows, we need to add the directory containing the dll to the
# 'PATH' environment variable so that the program can call it.
def export_dll(dir):
    if need_exportdll:
        os.environ["PATH"] += os.pathsep + dir


def unexport_dll(dir):
    if need_exportdll:
        paths = os.environ["PATH"].split(os.pathsep)
        paths = list(set(paths))
        if dir in paths:
            paths.remove(dir)
        os.environ["PATH"] = os.pathsep.join(paths)


print("[test-export] use %s library" % link_type)

# Test for build tree.
print("[test-export] test for build tree")
dllpath = os.path.join(working_dir, "bin", "Debug")
os.environ["CMAKE_PREFIX_PATH"] = working_dir
export_dll(dllpath)
run_test_group()
del os.environ["CMAKE_PREFIX_PATH"]
unexport_dll(dllpath)

# Install libevent libraries to system path. Remove LibeventConfig.cmake
# from build directory to avoid confusion when using find_package().
print("[test-export] test for install tree(in system-wide path)")
if platform.system() == "Windows":
    prefix = "C:\\Program Files\\libevent"
    dllpath = os.path.join(prefix, "lib")
else:
    prefix = "/usr/local"
exec_cmd('cmake -DCMAKE_SKIP_INSTALL_RPATH=OFF -DCMAKE_INSTALL_PREFIX="%s" ..' % prefix, True)
exec_cmd('cmake --build . -v --target install', True)
os.environ["CMAKE_PREFIX_PATH"] = os.path.join(prefix, "lib/cmake/libevent")
export_dll(dllpath)
run_test_group()
unexport_dll(dllpath)
del os.environ["CMAKE_PREFIX_PATH"]

# Uninstall the libraries installed in the above steps. Install the libraries
# into a temporary directory. Same as above, remove LibeventConfig.cmake from
# build directory to avoid confusion when using find_package().
print("[test-export] test for install tree(in non-system-wide path)")
exec_cmd("cmake --build . -v --target uninstall", True)
tempdir = tempfile.TemporaryDirectory()
cmd = 'cmake -DCMAKE_SKIP_INSTALL_RPATH=OFF -DCMAKE_INSTALL_PREFIX="%s" ..' % tempdir.name
exec_cmd(cmd, True)
exec_cmd("cmake --build . -v --target install", True)
os.environ["CMAKE_PREFIX_PATH"] = os.path.join(tempdir.name, "lib/cmake/libevent")
dllpath = os.path.join(tempdir.name, "lib")
export_dll(dllpath)
run_test_group()
unexport_dll(dllpath)
del os.environ["CMAKE_PREFIX_PATH"]

print("[test-export] all testcases have run successfully")