tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

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")