Coverage for bim2sim/plugins/PluginTEASER/test/regression/test_teaser.py: 0%

100 statements  

« prev     ^ index     » next       coverage.py v7.6.12, created at 2025-03-12 17:09 +0000

1import logging 

2import re 

3import shutil 

4import unittest 

5from pathlib import Path 

6 

7import buildingspy.development.regressiontest as u 

8 

9import bim2sim 

10from bim2sim.kernel.decision.decisionhandler import DebugDecisionHandler 

11from bim2sim.utilities.test import RegressionTestBase 

12from bim2sim.utilities.types import IFCDomain, ZoningCriteria 

13 

14logger = logging.getLogger(__name__) 

15 

16 

17class RegressionTestTEASER(RegressionTestBase): 

18 def setUp(self): 

19 self.results_src_dir = None 

20 self.results_dst_dir = None 

21 self.tester = None 

22 super().setUp() 

23 

24 def tearDown(self): 

25 # clean up buildingspy logs 

26 # TODO if statement is only needed, because CI discovers more tests 

27 # than existing and then fails when trying to access not existing 

28 # project 

29 if self.project: 

30 reg_dir = self.project.paths.b2sroot / 'bim2sim' / 'plugins' \ 

31 / 'PluginTEASER' / 'test' / 'regression' 

32 shutil.rmtree(reg_dir / 'funnel_comp', ignore_errors=True) 

33 log_files = [ 

34 'comparison-dymola.log', 

35 'failed-simulator-dymola.log', 

36 'simulator-dymola.log', 

37 'unitTests-dymola.log' 

38 ] 

39 for log_file in log_files: 

40 source = reg_dir / log_file 

41 if not self.is_ci: 

42 destination = self.project.paths.log / log_file 

43 if source.exists(): 

44 shutil.move(str(source), str(destination)) 

45 

46 super().tearDown() 

47 

48 def create_regression_setup( 

49 self, 

50 tolerance: float = 1E-3, 

51 batch_mode: bool = False): 

52 """ 

53 Create a regression test setup based on BuildingsPy regression tests. 

54 

55 This method uses the BuildingsPy library to create a regression test for 

56 the currents project TEASER modelica simulation model export. 

57 

58 Args: 

59 tolerance: the tolerance in which the regression results will be 

60 accepted as valid 

61 batch_mode: in batch mode no input is required and no new results 

62 can be created 

63 

64 """ 

65 regex = re.compile("[^a-zA-z0-9]") 

66 model_export_name = regex.sub("", self.project.name) 

67 self.ref_results_src_path = Path(bim2sim.__file__).parent.parent \ 

68 / "test/resources/arch/regression_results" \ 

69 / self.project.name / 'TEASER' 

70 self.ref_results_dst_path = \ 

71 self.project.paths.export / 'TEASER' / 'Model' / \ 

72 model_export_name / 'Resources' / 'ReferenceResults' / \ 

73 'Dymola' 

74 self.tester = u.Tester(tool='dymola', tol=tolerance, 

75 cleanup=True) 

76 self.tester.pedanticModelica(False) 

77 self.tester.showGUI(False) 

78 self.tester.batchMode(batch_mode) 

79 self.tester.setLibraryRoot( 

80 self.project.paths.export / 'TEASER' / 'Model' / model_export_name) 

81 path_aixlib = ( 

82 Path(bim2sim.__file__).parent / 'plugins' / 

83 f'PluginTEASER' / 'test' / 'regression' / 'library' / 

84 'library_AixLib' / 'AixLib' / 'package.mo') 

85 self.tester.setAdditionalLibResource(str(path_aixlib)) 

86 if list(self.ref_results_src_path.rglob("*.txt")): 

87 shutil.copytree(self.ref_results_src_path, 

88 self.ref_results_dst_path) 

89 else: 

90 shutil.rmtree(self.ref_results_src_path.parent, ignore_errors=True) 

91 

92 def run_regression_test(self): 

93 if not list(self.ref_results_src_path.rglob("*.txt")): 

94 logger.error( 

95 f"No Regression Results found in {self.ref_results_src_path} " 

96 f"to perform regression test via simulation.") 

97 reg_test_res = self.tester.run() 

98 return reg_test_res 

99 

100 def create_regression_results(self): 

101 """Creates regression results based on simulation model. 

102 

103 If simulation is successful and regression results differ from 

104 new simulation results, the user is asked if the results should be 

105 overwritten. 

106 If simulation is successful and simulation results are same with 

107 regression results nothing happens. 

108 If simulation is not successful nothing happens. 

109 """ 

110 self.tester.run() 

111 sim_sucessful = self.tester._comp_info[0]['simulation']['success'] 

112 comp_sucessful = self.tester._comp_info[0]['comparison']['test_passed'] 

113 

114 # sim and comparison 

115 if sim_sucessful and all(comp_sucessful): 

116 logger.info("No differences between simulation and regression " 

117 "results. No fresh results created.") 

118 # sim successful but comparison not (new results were created based if 

119 # user decided to simulate 

120 elif sim_sucessful and not all(comp_sucessful): 

121 # copy updated ref results to assets 

122 shutil.rmtree(self.ref_results_src_path, 

123 ignore_errors=True) 

124 shutil.copytree(self.ref_results_dst_path, 

125 self.ref_results_src_path) 

126 logger.info("Regression results were updated with new results.") 

127 elif not sim_sucessful: 

128 logger.error(f"The simulation was not successful, " 

129 f"no new regression results were created.") 

130 

131 

132class TestRegressionTEASER(RegressionTestTEASER, unittest.TestCase): 

133 def test_run_kitfzkhaus(self): 

134 """Run TEASER regression test with AC20-FZK-Haus.ifc and one zone model 

135 export""" 

136 ifc_names = {IFCDomain.arch: 'AC20-FZK-Haus.ifc'} 

137 project = self.create_project(ifc_names, 'TEASER') 

138 project.sim_settings.zoning_criteria = ( 

139 ZoningCriteria.combined_single_zone) 

140 project.sim_settings.ahu_tz_overwrite = False 

141 answers = () 

142 handler = DebugDecisionHandler(answers) 

143 for decision, answer in handler.decision_answer_mapping(project.run()): 

144 decision.value = answer 

145 orientation_dict = {} 

146 elements = project.playground.state['elements'] 

147 for ele in elements.values(): 

148 if hasattr(ele, 'teaser_orientation'): 

149 if ele.teaser_orientation: 

150 orientation_dict[ele] = ele.teaser_orientation 

151 self.assertEqual(0, handler.return_value, 

152 "Project export did not finish successfully.") 

153 self.create_regression_setup(tolerance=1E-3, batch_mode=True) 

154 reg_test_res = self.run_regression_test() 

155 if reg_test_res == 3: 

156 logger.error("Can't run dymola Simulation as no Dymola executable " 

157 "found") 

158 self.assertEqual(0, reg_test_res, 

159 "Regression test with simulation did not finish" 

160 " successfully or created deviations.") 

161 

162 def test_run_digitalhub(self): 

163 """Run TEASER regression test with FM_ARC_DigitalHub_with_SB_neu and 

164 one zone model export""" 

165 ifc_names = {IFCDomain.arch: 'FM_ARC_DigitalHub_with_SB_neu.ifc'} 

166 project = self.create_project(ifc_names, 'TEASER') 

167 project.sim_settings.ahu_tz_overwrite = False 

168 project.sim_settings.zoning_criteria = ( 

169 ZoningCriteria.combined_single_zone) 

170 project.sim_settings.prj_use_conditions = Path( 

171 bim2sim.__file__).parent.parent / \ 

172 "test/resources/arch/custom_usages/" \ 

173 "UseConditionsFM_ARC_DigitalHub.json" 

174 project.sim_settings.prj_custom_usages = Path( 

175 bim2sim.__file__).parent.parent / \ 

176 "test/resources/arch/custom_usages/" \ 

177 "customUsagesFM_ARC_DigitalHub_with_SB_neu.json" 

178 answers = ('Other', *(None,)*12, 2015) 

179 handler = DebugDecisionHandler(answers) 

180 for decision, answer in handler.decision_answer_mapping(project.run()): 

181 decision.value = answer 

182 self.assertEqual(0, handler.return_value, 

183 "Project export did not finish successfully.") 

184 self.create_regression_setup(tolerance=1E-3, batch_mode=True) 

185 reg_test_res = self.run_regression_test() 

186 if reg_test_res == 3: 

187 logger.error("Can't run dymola Simulation as no Dymola executable " 

188 "found") 

189 self.assertEqual(0, reg_test_res, 

190 "Regression test with simulation did not finish" 

191 " successfully or created deviations.")