mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-17 10:59:17 +00:00
274 lines
8.5 KiB
Python
274 lines
8.5 KiB
Python
from behave.__main__ import main as behave_main
|
|
import behave.formatter.pretty # Needed for pyinstaller to package it
|
|
import os
|
|
import sys
|
|
import shutil
|
|
import webbrowser
|
|
import fileinput
|
|
import tempfile
|
|
|
|
|
|
# get bimtester source code module path
|
|
bimtester_path = os.path.dirname(os.path.realpath(__file__))
|
|
# print(bimtester_path)
|
|
try:
|
|
# PyInstaller creates a temp folder and stores path in _MEIPASS
|
|
base_path = sys._MEIPASS
|
|
except Exception:
|
|
base_path = os.path.dirname(os.path.realpath(__file__))
|
|
|
|
|
|
def get_resource_path(relative_path):
|
|
return os.path.join(base_path, relative_path)
|
|
|
|
|
|
def run_tests(args):
|
|
if not get_features(args):
|
|
print("No features could be found to check.")
|
|
return False
|
|
behave_args = [get_resource_path("features")]
|
|
if args["advanced_arguments"]:
|
|
behave_args.extend(args["advanced_arguments"].split())
|
|
elif not args["console"]:
|
|
behave_args.extend(["--format", "json.pretty", "--outfile", "report/report.json"])
|
|
behave_main(behave_args)
|
|
print("# All tests are finished.")
|
|
return True
|
|
|
|
|
|
def get_features(args):
|
|
# current_path = os.path.abspath(".")
|
|
features_dir = get_resource_path("features")
|
|
for f in os.listdir(features_dir):
|
|
if f.endswith(".feature"):
|
|
os.remove(os.path.join(features_dir, f))
|
|
if args["feature"]:
|
|
shutil.copyfile(args["feature"], os.path.join(get_resource_path("features"), os.path.basename(args["feature"])))
|
|
return True
|
|
if os.path.exists("features"):
|
|
shutil.copytree("features", get_resource_path("features"))
|
|
return True
|
|
has_features = False
|
|
for f in os.listdir("."):
|
|
if not f.endswith(".feature"):
|
|
continue
|
|
if args["feature"] and args["feature"] != f:
|
|
continue
|
|
has_features = True
|
|
shutil.copyfile(f, os.path.join(get_resource_path("features"), os.path.basename(f)))
|
|
return has_features
|
|
|
|
|
|
"""
|
|
# clean logs to be able to run tests
|
|
# once again but on another building model and in another directory
|
|
# somehow does not work, thus test will be run in the same directory
|
|
# on each new run, directory will be deleted before each new run
|
|
# https://github.com/behave/behave/issues/871
|
|
# run bimtester
|
|
# copy manually this code, run bimtester again, does not work on two directories
|
|
from behave.runner_util import reset_runtime
|
|
reset_runtime()
|
|
|
|
"""
|
|
|
|
|
|
"""
|
|
from code_bimtester import run
|
|
myfeatures_path = "/home/hugo/.FreeCAD/Mod/bimtester/features_bimtester/fea_min/"
|
|
myifcfile_path = "/home/hugo/Documents/zeug_sort/z_some_ifc/"
|
|
ifcfilename = "example_model.ifc"
|
|
run.run_all(myfeatures_path, myifcfile_path, ifcfilename)
|
|
|
|
|
|
from code_bimtester import run
|
|
myfeatures_path = "/home/hugo/Documents/zeug_sort/ifcos_bimtester/myrun/"
|
|
run.run_all(myfeatures_path, myfeatures_path)
|
|
|
|
"""
|
|
|
|
|
|
# TODO: if the ifc file name or path contains special character
|
|
# like German Umlaute behave gives an error
|
|
|
|
|
|
def run_intmp_tests(args={}):
|
|
|
|
from behave import __version__ as behave_version
|
|
# https://github.com/behave/behave/issues/871
|
|
if behave_version == "1.2.5":
|
|
print(
|
|
"At least behave version 1.2.6 is needed, but version {} found."
|
|
.format(behave_version)
|
|
)
|
|
return False
|
|
|
|
# mandatory parameter: ifcdir, featuredir
|
|
# optional parameter: ifcfilename
|
|
# copy features and steps to tmp, replace ifcdir in features files
|
|
# run
|
|
|
|
# get ifcpath, this is the path the ifc file is in
|
|
if "ifcpath" in args and args["ifcpath"] != "":
|
|
# TODO check if path exists
|
|
ifc_path = args["ifcpath"]
|
|
else:
|
|
print("No ifc path was given.")
|
|
return False
|
|
|
|
# get the features_path, the feature files where the tests are in
|
|
if "features" in args and args["features"] != "":
|
|
# TODO check if path exists, and if features dir is inside
|
|
features_path = os.path.join(args["features"], "features")
|
|
else:
|
|
print("No features path was given.")
|
|
return False
|
|
|
|
if "ifcfilename" in args and args["ifcfilename"] != "":
|
|
# TODO check if file
|
|
ifc_filename = args["ifcfilename"]
|
|
else:
|
|
ifc_filename = None
|
|
|
|
# set up paths
|
|
# a unique temp path should not be used
|
|
# behave raises an ambiguous step exception
|
|
# run_path = tempfile.mkdtemp()
|
|
# thus use the same path on every run
|
|
# but delete it if exists
|
|
run_path = os.path.join(tempfile.gettempdir(), "bimtesterfc")
|
|
if os.path.isdir(run_path):
|
|
from shutil import rmtree
|
|
rmtree(run_path) # fails on read only files
|
|
if os.path.isdir(run_path):
|
|
print("Delete former beimtester run dir {} failed".format(run_path))
|
|
return False
|
|
os.mkdir(run_path)
|
|
report_path = os.path.join(run_path, "report")
|
|
copy_features_path = os.path.join(run_path, "features")
|
|
copy_steps_path = os.path.join(copy_features_path, "steps")
|
|
|
|
# copy features files
|
|
# print(features_path)
|
|
# print(copy_features_path)
|
|
if os.path.exists(features_path):
|
|
shutil.copytree(features_path, copy_features_path)
|
|
|
|
# replace ifcpath in feature files
|
|
# IMHO better than copy the ifc file which could be 500 MB
|
|
feature_files = os.listdir(copy_features_path)
|
|
# print(feature_files)
|
|
for feature_file in feature_files:
|
|
feature_file = os.path.join(copy_features_path, feature_file)
|
|
# print(feature_file)
|
|
# search the line
|
|
ff = open(feature_file, "r")
|
|
lines = ff.readlines()
|
|
ff.close()
|
|
theline = ""
|
|
for line in lines:
|
|
if "* The IFC file" in line and "must be provided" in line:
|
|
theline = line
|
|
if ifc_filename is None:
|
|
ifc_filename = os.path.basename(theline.split('"')[1])
|
|
newifcline = (
|
|
' * The IFC file "{}" must be provided\n'
|
|
.format(os.path.join(ifc_path, ifc_filename))
|
|
)
|
|
# print(newifcline)
|
|
break
|
|
else:
|
|
print("The line which sets the ifc file to test was not found.")
|
|
newifcline = ""
|
|
# replace the line
|
|
if newifcline != "":
|
|
# https://stackoverflow.com/a/290494
|
|
for line in fileinput.input(feature_file, inplace=True):
|
|
# the print replaces the line in the file
|
|
print(line.replace(theline, newifcline), end="")
|
|
|
|
# copy step files and environment file
|
|
steps_path = os.path.join(
|
|
bimtester_path,
|
|
"features",
|
|
"steps"
|
|
)
|
|
# print(steps_path)
|
|
# print(copy_steps_path)
|
|
if os.path.exists(steps_path):
|
|
shutil.copytree(steps_path, copy_steps_path)
|
|
|
|
environment_file = os.path.join(
|
|
bimtester_path,
|
|
"features",
|
|
"environment.py"
|
|
)
|
|
if os.path.isfile(environment_file):
|
|
shutil.copyfile(
|
|
environment_file,
|
|
os.path.join(copy_features_path, "environment.py")
|
|
)
|
|
|
|
# get advanced args
|
|
# print to console from inside step files, add "--no-capture" flag
|
|
# https://github.com/behave/behave/issues/346
|
|
behave_args = [copy_features_path]
|
|
if "advanced_arguments" in args:
|
|
behave_args.extend(args["advanced_arguments"].split())
|
|
elif "console" not in args:
|
|
behave_args.extend([
|
|
"--no-capture",
|
|
"--format",
|
|
"json.pretty",
|
|
"--outfile",
|
|
os.path.join(report_path, "report.json")
|
|
])
|
|
print(behave_args)
|
|
|
|
# run tests
|
|
from behave.__main__ import main as behave_main
|
|
behave_main(behave_args)
|
|
print("All tests are finished.")
|
|
|
|
# delete steps
|
|
# shutil.rmtree(steps_path)
|
|
|
|
return run_path
|
|
|
|
|
|
def run_all(the_features_path, the_ifcfile_path, the_ifcfile_name=None):
|
|
|
|
# feature files
|
|
feature_files = os.listdir(
|
|
os.path.join(the_features_path, "features")
|
|
)
|
|
# print(feature_files)
|
|
|
|
# run bimtester
|
|
if the_ifcfile_name is None:
|
|
runpath = run_intmp_tests({
|
|
"features": the_features_path,
|
|
"ifcpath": the_ifcfile_path
|
|
})
|
|
else:
|
|
runpath = run_intmp_tests({
|
|
"features": the_features_path,
|
|
"ifcpath": the_ifcfile_path,
|
|
"ifcfilename": the_ifcfile_name
|
|
})
|
|
|
|
# create html report
|
|
from .reports import generate_report
|
|
generate_report(runpath)
|
|
# print(runpath)
|
|
|
|
# open the webbrowser
|
|
for ff in feature_files:
|
|
webbrowser.open(os.path.join(
|
|
runpath,
|
|
"report",
|
|
ff + ".html"
|
|
))
|
|
|
|
return True
|