test-export.py (6165B)
1 #!/usr/bin/env python3 2 # 3 # Check if find_package(Libevent COMPONENTS xxx) can get the correct library. 4 # Note: this script has only been tested on python3. 5 # Usage: 6 # cd cmake-build-dir 7 # cmake <options> .. && cmake --build . 8 # python /path/to/test-export.py [static|shared] 9 10 import sys 11 import os 12 import shutil 13 import platform 14 import subprocess 15 import tempfile 16 17 results = ("success", "failure") 18 FNULL = open(os.devnull, 'wb') 19 script_dir = os.path.split(os.path.realpath(sys.argv[0]))[0] 20 # working_dir is cmake build dir 21 working_dir = os.getcwd() 22 if len(sys.argv) > 1 and sys.argv[1] == "static": 23 link_type = sys.argv[1] 24 else: 25 link_type = "shared" 26 27 28 def exec_cmd(cmd, silent): 29 if silent: 30 p = subprocess.Popen(cmd, stdout=FNULL, stderr=FNULL, shell=True) 31 else: 32 p = subprocess.Popen(cmd, shell=True) 33 p.communicate() 34 return p.poll() 35 36 37 def link_and_run(link, code): 38 """Check if the source code matches the library component. 39 40 Compile source code relative to one component and link to another component. 41 Then run the generated executor. 42 43 Args: 44 link: The name of component that the source code will link with. 45 code: The source code related component name. 46 47 Returns: 48 Returns 0 if links and runs successfully, otherwise 1. 49 """ 50 exec_cmd("cmake --build . --target clean", True) 51 arch = '' 52 if platform.system() == "Windows": 53 arch = '-A x64' 54 cmd = 'cmake .. %s -DEVENT__LINK_COMPONENT=%s -DEVENT__CODE_COMPONENT=%s' % ( 55 arch, link, code) 56 if link_type == "static": 57 cmd = "".join([cmd, " -DLIBEVENT_STATIC_LINK=1"]) 58 r = exec_cmd(cmd, True) 59 if r == 0: 60 r = exec_cmd('cmake --build .', True) 61 if r == 0: 62 r = exec_cmd('ctest', True) 63 if r != 0: 64 r = 1 65 return r 66 67 # expect 0:success 1:failure 68 def testcase(link, code, expect): 69 r = link_and_run(link, code) 70 if link == "": 71 link = "all" 72 if code == "": 73 code = "all" 74 if r != expect: 75 print('[test-export] fail: link %s and run %s expects %s but gets %s.' % 76 (link, code, results[expect], results[r])) 77 sys.exit(1) 78 else: 79 print('[test-export] success: link %s and run %s expects and gets %s.' % 80 (link, code, results[r])) 81 82 # Dependency relationships between libevent libraries: 83 # core: none 84 # extra: core 85 # pthreads: core,pthread 86 # openssl: core,openssl 87 def test_group(): 88 testcase("core", "core", 0) 89 testcase("extra", "extra", 0) 90 testcase("openssl", "openssl", 0) 91 testcase("", "", 0) 92 testcase("extra", "core", 0) 93 testcase("openssl", "core", 0) 94 testcase("core", "extra", 1) 95 testcase("core", "openssl", 1) 96 testcase("extra", "openssl", 1) 97 testcase("openssl", "extra", 1) 98 if platform.system() != "Windows": 99 testcase("pthreads", "pthreads", 0) 100 testcase("pthreads", "core", 0) 101 testcase("core", "pthreads", 1) 102 testcase("extra", "pthreads", 1) 103 testcase("pthreads", "extra", 1) 104 testcase("pthreads", "openssl", 1) 105 testcase("openssl", "pthreads", 1) 106 107 108 def config_restore(): 109 if os.path.isfile("tempconfig") and not os.path.isfile("LibeventConfig.cmake"): 110 os.rename("tempconfig", "LibeventConfig.cmake") 111 112 113 def config_backup(): 114 if os.path.isfile("tempconfig"): 115 os.remove("tempconfig") 116 if os.path.isfile("LibeventConfig.cmake"): 117 os.rename("LibeventConfig.cmake", "tempconfig") 118 119 120 shutil.rmtree(os.path.join(script_dir, "build"), ignore_errors=True) 121 122 123 def run_test_group(): 124 os.chdir(script_dir) 125 if not os.path.isdir("build"): 126 os.mkdir("build") 127 os.chdir("build") 128 test_group() 129 os.chdir(working_dir) 130 131 132 need_exportdll = False 133 if link_type == "shared" and platform.system() == "Windows": 134 need_exportdll = True 135 136 # On Windows, we need to add the directory containing the dll to the 137 # 'PATH' environment variable so that the program can call it. 138 def export_dll(dir): 139 if need_exportdll: 140 os.environ["PATH"] += os.pathsep + dir 141 142 143 def unexport_dll(dir): 144 if need_exportdll: 145 paths = os.environ["PATH"].split(os.pathsep) 146 paths = list(set(paths)) 147 if dir in paths: 148 paths.remove(dir) 149 os.environ["PATH"] = os.pathsep.join(paths) 150 151 152 print("[test-export] use %s library" % link_type) 153 154 # Test for build tree. 155 print("[test-export] test for build tree") 156 dllpath = os.path.join(working_dir, "bin", "Debug") 157 config_restore() 158 os.environ["CMAKE_PREFIX_PATH"] = working_dir 159 export_dll(dllpath) 160 run_test_group() 161 del os.environ["CMAKE_PREFIX_PATH"] 162 unexport_dll(dllpath) 163 164 # Install libevent libraries to system path. Remove LibeventConfig.cmake 165 # from build directory to avoid confusion when using find_package(). 166 print("[test-export] test for install tree(in system-wide path)") 167 if platform.system() == "Windows": 168 prefix = "C:\\Program Files\\libevent" 169 dllpath = os.path.join(prefix, "lib") 170 else: 171 prefix = "/usr/local" 172 exec_cmd('cmake -DCMAKE_INSTALL_PREFIX="%s" ..' % prefix, True) 173 exec_cmd('cmake --build . --target install', True) 174 config_backup() 175 os.environ["CMAKE_PREFIX_PATH"] = os.path.join(prefix, "lib/cmake/libevent") 176 export_dll(dllpath) 177 run_test_group() 178 unexport_dll(dllpath) 179 del os.environ["CMAKE_PREFIX_PATH"] 180 181 # Uninstall the libraries installed in the above steps. Install the libraries 182 # into a temporary directory. Same as above, remove LibeventConfig.cmake from 183 # build directory to avoid confusion when using find_package(). 184 print("[test-export] test for install tree(in non-system-wide path)") 185 exec_cmd("cmake --build . --target uninstall", True) 186 tempdir = tempfile.TemporaryDirectory() 187 cmd = 'cmake -DCMAKE_INSTALL_PREFIX="%s" ..' % tempdir.name 188 exec_cmd(cmd, True) 189 exec_cmd("cmake --build . --target install", True) 190 config_backup() 191 os.environ["CMAKE_PREFIX_PATH"] = os.path.join(tempdir.name, "lib/cmake/libevent") 192 dllpath = os.path.join(tempdir.name, "lib") 193 export_dll(dllpath) 194 run_test_group() 195 unexport_dll(dllpath) 196 del os.environ["CMAKE_PREFIX_PATH"] 197 config_restore() 198 199 print("[test-export] all testcases have run successfully")