271 lines
9.2 KiB
Python
271 lines
9.2 KiB
Python
# unittests for premake-ninja
|
|
|
|
import os
|
|
import sys
|
|
import time
|
|
import shutil
|
|
import platform
|
|
import unittest
|
|
import subprocess
|
|
|
|
# we are changing working directory often in this tests, so let's save current one
|
|
current_cwd = os.getcwd()
|
|
|
|
# if set, will override compiler name when premake is executed
|
|
override_compiler = None
|
|
|
|
# finds the file in path
|
|
def which(cmd, mode = os.F_OK | os.X_OK, path = None):
|
|
if sys.version_info[0:2] >= (3, 3):
|
|
return shutil.which(cmd, mode, path)
|
|
else:
|
|
def _access_check(fn, mode):
|
|
return (os.path.exists(fn) and os.access(fn, mode)
|
|
and not os.path.isdir(fn))
|
|
|
|
if os.path.dirname(cmd):
|
|
if _access_check(cmd, mode):
|
|
return cmd
|
|
return None
|
|
|
|
if path is None:
|
|
path = os.environ.get("PATH", os.defpath)
|
|
if not path:
|
|
return None
|
|
path = path.split(os.pathsep)
|
|
|
|
if sys.platform == "win32":
|
|
if not os.curdir in path:
|
|
path.insert(0, os.curdir)
|
|
pathext = os.environ.get("PATHEXT", "").split(os.pathsep)
|
|
if any(cmd.lower().endswith(ext.lower()) for ext in pathext):
|
|
files = [cmd]
|
|
else:
|
|
files = [cmd + ext for ext in pathext]
|
|
else:
|
|
files = [cmd]
|
|
|
|
seen = set()
|
|
for dir in path:
|
|
normdir = os.path.normcase(dir)
|
|
if not normdir in seen:
|
|
seen.add(normdir)
|
|
for thefile in files:
|
|
name = os.path.join(dir, thefile)
|
|
if _access_check(name, mode):
|
|
return name
|
|
return None
|
|
|
|
# ----------------------------------------------------- helper class
|
|
class Helper(unittest.TestCase):
|
|
# removes build directory in test folder
|
|
def clear(self, build_dir):
|
|
if os.path.exists(build_dir):
|
|
shutil.rmtree(build_dir)
|
|
|
|
# enters test, and clears it
|
|
def enter_test(self, test, build_dir = "build"):
|
|
self.build_dir = build_dir
|
|
os.chdir(current_cwd) # if previous test failed then we need to restore cwd
|
|
os.chdir(test)
|
|
self.clear(build_dir)
|
|
|
|
# clears test and exit from it
|
|
def exit_test(self, build_dir = "build"):
|
|
# for some reason call/check_call are not waiting for executable to completely finish
|
|
# so let's wait a bit so we can remove folder safely
|
|
time.sleep(0.3)
|
|
self.clear(build_dir)
|
|
os.chdir(current_cwd)
|
|
|
|
# call premake in the test
|
|
def premake(self):
|
|
if override_compiler:
|
|
args = ["premake5", "--scripts=../../..", "--cc=" + override_compiler, "ninja"]
|
|
if override_compiler == "emcc":
|
|
args += ["--os=emscripten"]
|
|
self.assertEqual(subprocess.call(args), 0, "looks like premake failed")
|
|
else:
|
|
self.assertEqual(subprocess.call(["premake5", "--scripts=../../..", "ninja"]), 0, "looks like premake failed")
|
|
|
|
# call ninja in the test
|
|
def ninja(self, target = None):
|
|
args = ["ninja", "-C", "build"]
|
|
if target is not None:
|
|
args.append(target)
|
|
self.assertEqual(subprocess.call(args), 0, "looks like ninja failed")
|
|
|
|
# get out name with ext and prefix
|
|
def out_name(self, path, ext = None, prefix = None):
|
|
if (ext == None) and (prefix == None):
|
|
return path
|
|
base_path = os.path.dirname(path)
|
|
base_name_and_ext = os.path.splitext(os.path.basename(path))
|
|
if prefix == None:
|
|
prefix = ""
|
|
if ext == None:
|
|
ext = base_name_and_ext[1]
|
|
return base_path + "/" + prefix + base_name_and_ext[0] + ext
|
|
|
|
# check if executable exist
|
|
def out_exist(self, path):
|
|
print(f"Looking for {path} in {os.listdir(os.path.dirname(path))}")
|
|
sys.stdout.flush()
|
|
self.assertTrue(
|
|
os.path.exists(path) or
|
|
os.path.exists(self.out_name(path, ".exe")) or
|
|
os.path.exists(self.out_name(path, ".app")) or
|
|
os.path.exists(self.out_name(path, ".lib")) or
|
|
os.path.exists(self.out_name(path, ".a", "lib")) or
|
|
os.path.exists(self.out_name(path, ".dll")) or
|
|
os.path.exists(self.out_name(path, ".so", "lib")) or
|
|
os.path.exists(self.out_name(path, ".dylib", "lib")) or
|
|
os.path.exists(self.out_name(path, ".wasm"))
|
|
)
|
|
print(f"Found {path}")
|
|
sys.stdout.flush()
|
|
# check if executable doesn't exist
|
|
def out_not_exist(self, path):
|
|
self.assertFalse(
|
|
os.path.exists(path) or
|
|
os.path.exists(self.out_name(path, ".exe")) or
|
|
os.path.exists(self.out_name(path, ".app")) or
|
|
os.path.exists(self.out_name(path, ".lib")) or
|
|
os.path.exists(self.out_name(path, ".a", "lib")) or
|
|
os.path.exists(self.out_name(path, ".dll")) or
|
|
os.path.exists(self.out_name(path, ".so", "lib")) or
|
|
os.path.exists(self.out_name(path, ".dylib", "lib")) or
|
|
os.path.exists(self.out_name(path, ".wasm"))
|
|
)
|
|
|
|
# check if executable exist
|
|
def exe(self, path):
|
|
if os.path.exists(path):
|
|
current_cwd = os.getcwd()
|
|
os.chdir(self.build_dir)
|
|
executable = os.path.relpath(path, self.build_dir)
|
|
subprocess.check_call([executable], env={'LD_LIBRARY_PATH': os.path.dirname(executable), 'DYLD_LIBRARY_PATH': os.path.dirname(executable)})
|
|
os.chdir(current_cwd)
|
|
elif os.path.exists(path + ".exe"):
|
|
subprocess.check_call([path + ".exe"])
|
|
elif os.path.exists(path + ".app"):
|
|
subprocess.check_call([path + ".app"])
|
|
elif os.path.exists(self.out_name(path, ".lib")) or os.path.exists(self.out_name(path, ".a", "lib")) or os.path.exists(self.out_name(path, ".dll")) or os.path.exists(self.out_name(path, ".so", "lib")) or os.path.exists(self.out_name(path, ".dylib", "lib")):
|
|
pass
|
|
else:
|
|
self.assertTrue(False, "executable '" + path + "' doesn't exist")
|
|
|
|
# check basic flow, run debug and release executables
|
|
def check_basics(self, out_debug, out_release, build_dir = "build"):
|
|
# build dir should not exist before premake is called
|
|
self.assertFalse(os.path.exists(build_dir))
|
|
|
|
# call premake
|
|
# build dir should exist afterwards, but executables shouldn't
|
|
self.premake()
|
|
self.assertTrue(os.path.exists(build_dir))
|
|
self.out_not_exist(out_debug)
|
|
self.out_not_exist(out_release)
|
|
|
|
# call ninja, by default ninja should build debug target
|
|
# so debug executable should exist, and release shouldn't
|
|
self.ninja()
|
|
self.out_exist(out_debug)
|
|
self.out_not_exist(out_release)
|
|
|
|
# let's build debug target explicitly, and still release executable shouldn't exist
|
|
self.ninja("debug")
|
|
self.out_exist(out_debug)
|
|
self.out_not_exist(out_release)
|
|
|
|
# let's build release target explicitly, all basic executables should exist now
|
|
self.ninja("release")
|
|
self.out_exist(out_debug)
|
|
self.out_exist(out_release)
|
|
|
|
# run executables to check if they are valid
|
|
if override_compiler != "emcc":
|
|
self.exe(out_debug)
|
|
self.exe(out_release)
|
|
|
|
# ----------------------------------------------------- console app tests
|
|
class TestConsoleApp(Helper):
|
|
# test simple app
|
|
def test_simple(self):
|
|
self.enter_test("console_app/simple")
|
|
self.check_basics("build/bin_debug/ninjatestprj", "build/bin_release/ninjatestprj")
|
|
self.exit_test()
|
|
|
|
# test include path app
|
|
def test_include_path(self):
|
|
self.enter_test("console_app/includepath")
|
|
self.check_basics("build/bin_debug/ninjatestprj", "build/bin_release/ninjatestprj")
|
|
self.exit_test()
|
|
|
|
# ----------------------------------------------------- static lib tests
|
|
class TestStaticLib(Helper):
|
|
# test simple app
|
|
def test_simple(self):
|
|
self.enter_test("static_lib/simple")
|
|
self.check_basics("build/bin_debug/ninjatestprj", "build/bin_release/ninjatestprj")
|
|
self.exit_test()
|
|
|
|
# test static lib with app
|
|
def test_withapp(self):
|
|
self.enter_test("static_lib/withapp")
|
|
self.check_basics("build/bin_debug/ninjatestprj_app", "build/bin_release/ninjatestprj_app")
|
|
self.out_exist("build/bin_debug/ninjatestprj_lib test1")
|
|
self.out_exist("build/bin_release/ninjatestprj_lib test1")
|
|
self.out_exist("build/bin_debug/ninjatestprj_lib_test2")
|
|
self.out_exist("build/bin_release/ninjatestprj_lib_test2")
|
|
self.exit_test()
|
|
|
|
# ----------------------------------------------------- shared lib tests
|
|
class TestSharedLib(Helper):
|
|
# test simple app
|
|
def test_simple(self):
|
|
# Skip shared library tests on Emscripten since this is an advanced feature not supported by Premake yet.
|
|
if override_compiler == "emcc":
|
|
return
|
|
self.enter_test("shared_lib/simple")
|
|
self.check_basics("build/bin_debug/ninjatestprj", "build/bin_release/ninjatestprj")
|
|
self.exit_test()
|
|
|
|
# test shared lib with app
|
|
def test_withapp(self):
|
|
# Skip shared library tests on Emscripten since this is an advanced feature not supported by Premake yet.
|
|
if override_compiler == "emcc":
|
|
return
|
|
self.enter_test("shared_lib/withapp")
|
|
self.check_basics("build/bin_debug/ninjatestprj_app", "build/bin_release/ninjatestprj_app")
|
|
self.out_exist("build/bin_debug/ninjatestprj_lib_test1")
|
|
self.out_exist("build/bin_release/ninjatestprj_lib_test1")
|
|
self.out_exist("build/bin_debug/ninjatestprj_lib_test2")
|
|
self.out_exist("build/bin_release/ninjatestprj_lib_test2")
|
|
self.exit_test()
|
|
|
|
# ----------------------------------------------------- windowed app tests
|
|
class TestWindowedApp(Helper):
|
|
# test simple app
|
|
def test_simple(self):
|
|
self.enter_test("windowed_app/simple")
|
|
self.check_basics("build/bin_debug/ninjatestprj", "build/bin_release/ninjatestprj")
|
|
self.exit_test()
|
|
|
|
# ----------------------------------------------------- entry point
|
|
if __name__ == "__main__":
|
|
print("-------------------------- test default setup")
|
|
r = unittest.main(exit = False)
|
|
if not r.result.wasSuccessful():
|
|
sys.exit(1)
|
|
|
|
if platform.system() == "Windows" and which("gcc"):
|
|
print("-------------------------- found gcc on windows")
|
|
override_compiler = "gcc"
|
|
unittest.main()
|
|
|
|
if which("emcc"):
|
|
print("-------------------------- found emcc")
|
|
override_compiler = "emcc"
|
|
unittest.main()
|