From edd1f8c48bf8a78609c450ef3e71e90c89b3299b Mon Sep 17 00:00:00 2001
From: Botond Baranyi <botond.baranyi@ericsson.com>
Date: Mon, 12 Mar 2018 11:50:53 +0100
Subject: [PATCH] Fixed verdict redirects on 'alive' components (bug 532316)

Change-Id: I2df66a19e4f07eda45059ebaa2b3593edd01cc4e
Signed-off-by: Botond Baranyi <botond.baranyi@ericsson.com>
---
 core/Communication.cc              |  9 ++++++--
 core/Communication.hh              |  6 ++---
 core/Runtime.cc                    |  8 ++++---
 mctr2/mctr/MainController.cc       |  3 +++
 regression_test/done/DoneTest.ttcn | 37 ++++++++++++++++++++++++++++++
 5 files changed, 55 insertions(+), 8 deletions(-)

diff --git a/core/Communication.cc b/core/Communication.cc
index f96b36ee2..5f6442223 100644
--- a/core/Communication.cc
+++ b/core/Communication.cc
@@ -1115,16 +1115,21 @@ void TTCN_Communication::send_ptc_created(component component_reference)
 }
 
 void TTCN_Communication::prepare_stopped(Text_Buf& text_buf,
-  const char *return_type)
+  verdicttype final_verdict, const char *return_type, const char* reason)
 {
   text_buf.push_int(MSG_STOPPED);
+  text_buf.push_int(final_verdict);
+  text_buf.push_string(reason);
   text_buf.push_string(return_type);
 }
 
-void TTCN_Communication::send_stopped()
+void TTCN_Communication::send_stopped(verdicttype final_verdict,
+  const char* reason)
 {
   Text_Buf text_buf;
   text_buf.push_int(MSG_STOPPED);
+  text_buf.push_int(final_verdict);
+  text_buf.push_string(reason);
   // add an empty return type
   text_buf.push_string(NULL);
   send_message(text_buf);
diff --git a/core/Communication.hh b/core/Communication.hh
index 752617509..1a1e47055 100644
--- a/core/Communication.hh
+++ b/core/Communication.hh
@@ -138,9 +138,9 @@ public:
   static void send_mtc_ready();
 
   static void send_ptc_created(component component_reference);
-  static void prepare_stopped(Text_Buf& text_buf,
-    const char *return_type);
-  static void send_stopped();
+  static void prepare_stopped(Text_Buf& text_buf, verdicttype final_verdict,
+    const char *return_type, const char* reason = "");
+  static void send_stopped(verdicttype final_verdict, const char* reason = "");
   static void prepare_stopped_killed(Text_Buf& text_buf,
     verdicttype final_verdict, const char *return_type,
     const char* reason = "");
diff --git a/core/Runtime.cc b/core/Runtime.cc
index fd750ca2c..d059d9696 100644
--- a/core/Runtime.cc
+++ b/core/Runtime.cc
@@ -783,7 +783,7 @@ void TTCN_Runtime::start_function(const char *module_name,
         "Function %s was stopped. PTC remains alive and is waiting for next start.",
         function_name);
       // send a STOPPED message without return value
-      TTCN_Communication::send_stopped();
+      TTCN_Communication::send_stopped(local_verdict, verdict_reason);
       // return and do nothing else
       return;
     case PTC_EXIT:
@@ -825,8 +825,10 @@ void TTCN_Runtime::prepare_function_finished(const char *return_type,
     TTCN_error("Internal error: PTC behaviour function finished in invalid "
                "state.");
   if (is_alive) {
-    // Prepare a STOPPED message with the possible return value.
-    TTCN_Communication::prepare_stopped(text_buf, return_type);
+    // Prepare a STOPPED message with the current verdict and
+    // possible return value.
+    TTCN_Communication::prepare_stopped(text_buf, local_verdict, return_type,
+      verdict_reason);
   } else {
     // First the ports and timers must be stopped and deactivated.  The
     // user_unmap and user_stop functions of Test Ports may detect errors
diff --git a/mctr2/mctr/MainController.cc b/mctr2/mctr/MainController.cc
index 55c9d6e10..ba5602ccf 100644
--- a/mctr2/mctr/MainController.cc
+++ b/mctr2/mctr/MainController.cc
@@ -5863,6 +5863,9 @@ void MainController::process_stopped(component_struct *tc, int message_end)
     return;
   }
   Text_Buf& text_buf = *tc->text_buf;
+  tc->local_verdict = (verdicttype)text_buf.pull_int().get_val();
+  delete [] tc->verdict_reason;
+  tc->verdict_reason = text_buf.pull_string();
   delete [] tc->return_type;
   tc->return_type = text_buf.pull_string();
   tc->return_value_len = message_end - text_buf.get_pos();
diff --git a/regression_test/done/DoneTest.ttcn b/regression_test/done/DoneTest.ttcn
index c05886688..9719300ed 100644
--- a/regression_test/done/DoneTest.ttcn
+++ b/regression_test/done/DoneTest.ttcn
@@ -35,6 +35,27 @@ function f_behavior_pass() runs on CT {
   setverdict(pass);
 }
 
+// Testing 'done' statement on an 'alive' component
+function f_behavior_test_alive() runs on CT {
+  var CT ct := CT.create alive;
+  var verdicttype vt1;
+  ct.start(f_behavior_pass());
+  ct.done -> value vt1;
+  if (vt1 != pass) {
+    setverdict(fail, "Test #1 failed. Verdict: ", vt1);
+  }
+  else {
+    // do the test again, without setting the verdict to 'pass';
+    // the verdict on the component should still be the one set by the previous behavior function
+    var verdicttype vt2;
+    ct.start(f_behavior_none());
+    ct.done -> value vt2;
+    if (vt2 != pass) {
+      setverdict(fail, "Test #2 failed. Verdict: ", vt2);
+    }
+  }
+}
+
 /*************** Test cases ***************/
 
 // Testing 'done' statement on single component with no value redirect
@@ -125,6 +146,20 @@ testcase tc_any_from_done_verdict_redirect() runs on CT {
   setverdict(pass);
 }
 
+// Testing 'done' statement on an 'alive' component
+testcase tc_done_verdict_redirect_alive_mtc() runs on CT {
+  // calling the function normally runs the test on the MTC
+  f_behavior_test_alive();
+}
+
+// Testing 'done' statement on an 'alive' component
+testcase tc_done_verdict_redirect_alive_ptc() runs on CT {
+  // create a component variable to run the test on a PTC
+  var CT ct := CT.create;
+  ct.start(f_behavior_test_alive());
+  ct.done;
+}
+
 /************** Control part **************/
 control {
   execute(tc_done_single());
@@ -133,6 +168,8 @@ control {
   execute(tc_done_retval_redirect());
   execute(tc_done_verdict_redirect());
   execute(tc_any_from_done_verdict_redirect());
+  execute(tc_done_verdict_redirect_alive_mtc());
+  execute(tc_done_verdict_redirect_alive_ptc());
 }
 
 }
-- 
GitLab