Add Misc_Helpers.ttcn to centralize TTCN3 shutdown handling
This function can now be called from anywhere to try and safely shutdown
a testcase. It is not optimal as we can't call "all component.stop" from
outside the mtc, but without any proper and orderly shutdown handling of
all our emulation components I believe this is the best we can do.
To use it:
import from Misc_Helpers all;
in your module and then call
Misc_Helpers.f_shutdown(__BFILE__, __LINE__);
You can also pass the function a verdict and a message and it will take care
of calling setverdict, but beware of the following:
While setverdict would accept any number of arguments as log message
and convert them to a log string f_shutdown expects one charstring.
It's possible to use the log2str function to use the log arguments in
setverdict for f_shutdown, for example
setverdict(fail, "Template didn't match: ", tmpl_foo);
would become
Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, log2str("Template didn't match: ", tmpl_foo));
Change-Id: I84d1aa6732f6b748d2bfdeac8f6309023717f267
diff --git a/library/Misc_Helpers.ttcn b/library/Misc_Helpers.ttcn
new file mode 100644
index 0000000..1ca6491
--- /dev/null
+++ b/library/Misc_Helpers.ttcn
@@ -0,0 +1,28 @@
+module Misc_Helpers {
+
+/* Try to properly shutdown a testcase.
+ * The reliable method to stop a testcase without running into dynamic
+ * testcase errors due to unconnected ports receiving messages is to call
+ * all component.stop before terminating. However, this can only be called
+ * from the mtc! So in case we want to terminate from a component that is not
+ * the mtc we try to do the next best thing which is calling mtc.stop and
+ * hoping for the best.
+ */
+function f_shutdown(charstring file, integer line, verdicttype verdict := none,
+ charstring text := "") {
+ if (verdict != none) {
+ text := file & ":" & int2str(line) & " : " & text
+ setverdict(verdict, text);
+ }
+
+ log("Stopping testcase execution from ", file, ":", line)
+ if (self == mtc) {
+ /* Properly stop all ports before disconnecting them. This avoids
+ * running into the dynamic testcase error due to messages arriving on
+ * unconnected ports. */
+ all component.stop;
+ }
+ mtc.stop
+}
+
+}