implemented the Main Controller's 'reconf' command (artf468488)
authorBotond Baranyi <botond.baranyi@ericsson.com>
Wed, 29 Jun 2016 12:18:33 +0000 (14:18 +0200)
committerBotond Baranyi <botond.baranyi@ericsson.com>
Wed, 29 Jun 2016 12:30:24 +0000 (14:30 +0200)
Change-Id: Ie84819f7e01d73b0735aaab24207117e4adef28b
Signed-off-by: Botond Baranyi <botond.baranyi@ericsson.com>
core/Communication.cc
core/Communication.hh
core/Message_types.hh
core/Runtime.hh
mctr2/cli/Cli.cc
mctr2/cli/Cli.h
mctr2/mctr/MainController.cc
mctr2/mctr/MainController.h
usrguide/userguide.doc

index 44352b934da5fda883bff31a369032e3957f7b3d..6c4df1c2ba19ec6d22f9959a437007c1467d95cf 100644 (file)
@@ -572,7 +572,7 @@ void TTCN_Communication::process_all_messages_hc()
       process_error();
       break;
     case MSG_CONFIGURE:
-      process_configure(msg_end);
+      process_configure(msg_end, false);
       break;
     case MSG_CREATE_MTC:
       process_create_mtc();
@@ -704,6 +704,9 @@ void TTCN_Communication::process_all_messages_tc()
         case MSG_EXIT_MTC:
           process_exit_mtc();
           break;
+        case MSG_CONFIGURE:
+          process_configure(msg_end, true);
+          break;
         default:
           process_unsupported_message(msg_type, msg_end);
         }
@@ -1263,20 +1266,28 @@ void TTCN_Communication::send_message(Text_Buf& text_buf)
   }
 }
 
-void TTCN_Communication::process_configure(int msg_end)
+void TTCN_Communication::process_configure(int msg_end, bool to_mtc)
 {
   switch (TTCN_Runtime::get_state()) {
   case TTCN_Runtime::HC_IDLE:
   case TTCN_Runtime::HC_ACTIVE:
   case TTCN_Runtime::HC_OVERLOADED:
-    break;
+    if (!to_mtc) {
+      break;
+    }
+    // no break
+  case TTCN_Runtime::MTC_IDLE:
+    if (to_mtc) {
+      break;
+    }
+    // no break
   default:
     incoming_buf.cut_message();
     send_error("Message CONFIGURE arrived in invalid state.");
     return;
   }
 
-  TTCN_Runtime::set_state(TTCN_Runtime::HC_CONFIGURING);
+  TTCN_Runtime::set_state(to_mtc ? TTCN_Runtime::MTC_CONFIGURING : TTCN_Runtime::HC_CONFIGURING);
   TTCN_Logger::log_configdata(TitanLoggerApiSimple::ExecutorConfigdata_reason::received__from__mc);
 
   // take the config string directly from the buffer for efficiency reasons
@@ -1311,12 +1322,12 @@ void TTCN_Communication::process_configure(int msg_end)
 
   if (success) {
     send_configure_ack();
-    TTCN_Runtime::set_state(TTCN_Runtime::HC_ACTIVE);
+    TTCN_Runtime::set_state(to_mtc ? TTCN_Runtime::MTC_IDLE : TTCN_Runtime::HC_ACTIVE);
     TTCN_Logger::log_configdata(
       TitanLoggerApiSimple::ExecutorConfigdata_reason::processing__succeeded);
   } else {
     send_configure_nak();
-    TTCN_Runtime::set_state(TTCN_Runtime::HC_IDLE);
+    TTCN_Runtime::set_state(to_mtc ? TTCN_Runtime::MTC_IDLE : TTCN_Runtime::HC_IDLE);
   }
 
   incoming_buf.cut_message();
index 3cf058ebff0e035ffca12d0c5b92b0c201246cbc..1cf41e27ce2fd6fdec26a8472ef1ad547c10fd74 100644 (file)
@@ -182,7 +182,7 @@ private:
   /** @name Handlers of various messages
   *   @{
   */
-  static void process_configure(int msg_end);
+  static void process_configure(int msg_end, bool to_mtc);
   static void process_create_mtc();
   static void process_create_ptc();
   static void process_kill_process();
index b8873d663237de51200cd3b6c376881c3978a3dd..cb718983b735a310e81e8d1161d8618d9be85502 100644 (file)
@@ -34,7 +34,6 @@
 
 /* Messages from MC to HC (down) */
 
-#define MSG_CONFIGURE          1
 #define MSG_CREATE_MTC         2
 #define MSG_CREATE_PTC         3
 #define MSG_KILL_PROCESS       4
@@ -42,8 +41,6 @@
 
 /* Messages from HC to MC (up) */
 
-#define MSG_CONFIGURE_ACK      2
-#define MSG_CONFIGURE_NAK      3
 #define MSG_CREATE_NAK         4
 #define MSG_HC_READY           5
 
 
 #define MSG_DEBUG_RETURN_VALUE 100
 
+/* Messages from MC to HC or MTC (down) */
+
+#define MSG_CONFIGURE          200
+
+/* Messages from HC or MTC to MC (up) */
+
+#define MSG_CONFIGURE_ACK      200
+#define MSG_CONFIGURE_NAK      201
+
 #endif
index 282a531a52852d0ed3e6c2311919270030313293..10e67fcc6afe074c027bbace8f2d30998b44a31c 100644 (file)
@@ -50,11 +50,11 @@ public:
     MTC_TERMINATING_TESTCASE, MTC_TERMINATING_EXECUTION, MTC_PAUSED, // 14-16
     MTC_CREATE, MTC_START, MTC_STOP, MTC_KILL, MTC_RUNNING, MTC_ALIVE, // 17-22
     MTC_DONE, MTC_KILLED, MTC_CONNECT, MTC_DISCONNECT, MTC_MAP, MTC_UNMAP, // 23-28
-    MTC_EXIT, // 29
+    MTC_CONFIGURING, MTC_EXIT, // 30
 
-    PTC_INITIAL, PTC_IDLE, PTC_FUNCTION, PTC_CREATE, PTC_START, PTC_STOP, // 30-35
-    PTC_KILL, PTC_RUNNING, PTC_ALIVE, PTC_DONE, PTC_KILLED, PTC_CONNECT, // 36-41
-    PTC_DISCONNECT, PTC_MAP, PTC_UNMAP, PTC_STOPPED, PTC_EXIT // 42-46
+    PTC_INITIAL, PTC_IDLE, PTC_FUNCTION, PTC_CREATE, PTC_START, PTC_STOP, // 31-36
+    PTC_KILL, PTC_RUNNING, PTC_ALIVE, PTC_DONE, PTC_KILLED, PTC_CONNECT, // 37-42
+    PTC_DISCONNECT, PTC_MAP, PTC_UNMAP, PTC_STOPPED, PTC_EXIT // 43-47
   };
 private:
   static executor_state_enum executor_state;
index b4818ac18d9af54fdf0f553b2ca27dd030a9eeb4..6a4886ab98e9fc36d5011a83edfd96005cda3e83 100644 (file)
@@ -195,12 +195,14 @@ Cli::Cli()
     perror("Cli::Cli: pthread_cond_init failed.");
     exit(EXIT_FAILURE);
   }
+  cfg_file_name = NULL;
 }
 
 Cli::~Cli()
 {
   pthread_mutex_destroy(&mutex);
   pthread_cond_destroy(&cond);
+  Free(cfg_file_name);
 }
 
 //----------------------------------------------------------------------------
@@ -217,8 +219,9 @@ int Cli::enterLoop(int argc, char *argv[])
   printWelcome();
 
   if (argc == 2) {
-    printf("Using configuration file: %s\n", argv[1]);
-    if (process_config_read_file(argv[1], &mycfg)) {
+    cfg_file_name = mcopystr(argv[1]);
+    printf("Using configuration file: %s\n", cfg_file_name);
+    if (process_config_read_file(cfg_file_name, &mycfg)) {
       puts("Error was found in the configuration file. Exiting.");
       cleanUp();
       return EXIT_FAILURE;
@@ -728,12 +731,37 @@ void Cli::infoCallback(const char *arguments)
 
 void Cli::reconfCallback(const char *arguments)
 {
-  if(*arguments == 0) { // reconf called without its optional argument
-    puts("Reconfiguration of MC and HCs using original configuration "
-      "data\n -- not supported, yet.");
-  } else { // reconf called with config_file argument
-    puts("Reconfiguration of MC and HCs using configuration file"
-      "specified in\ncommand line argument -- not supported, yet.");
+  if (!MainController::start_reconfiguring()) {
+    return;
+  }
+  if (*arguments != 0) {
+    Free(cfg_file_name);
+    cfg_file_name = mcopystr(arguments);
+  }
+  
+  printf("Using configuration file: %s\n", cfg_file_name);
+  if (process_config_read_file(cfg_file_name, &mycfg)) {
+    puts("Error was found in the configuration file. Exiting.");
+    cleanUp();
+    puts("exit");
+    exitCallback("");
+  }
+  else {
+    MainController::set_kill_timer(mycfg.kill_timer);
+
+    for (int i = 0; i < mycfg.group_list_len; ++i) {
+      MainController::add_host(mycfg.group_list[i].group_name,
+        mycfg.group_list[i].host_name);
+    }
+
+    for (int i = 0; i < mycfg.component_list_len; ++i) {
+      MainController::assign_component(mycfg.component_list[i].host_or_group,
+        mycfg.component_list[i].component);
+    }
+    
+    if (MainController::get_state() == mctr::MC_RECONFIGURING) {
+      MainController::configure(mycfg.config_read_buffer);
+    }
   }
 }
 
@@ -800,6 +828,7 @@ void Cli::exitCallback(const char *arguments)
   if (*arguments == 0) {
     switch (MainController::get_state()) {
     case mctr::MC_READY:
+    case mctr::MC_RECONFIGURING:
       MainController::exit_mtc();
       waitMCState(WAIT_MTC_TERMINATED);
     case mctr::MC_LISTENING:
index 190de8f7edbb9c54631f900051d7d221f93a8ef8..5485f0e185066ff05e4dd4dab45bb750e02fad02 100644 (file)
@@ -191,6 +191,7 @@ private:
    */
   int executeListIndex;
 
+  char* cfg_file_name;
   config_data mycfg;
 };
 
index 0af6531642aa4e99855486271f15aededa7eff1f..8ff32588cf3d8560184ed12ee3d3058acff52c2c 100644 (file)
@@ -688,20 +688,37 @@ void MainController::configure_host(host_struct *host, boolean should_notify)
         host->hostname);
     }
     send_configure(host, config_str);
-    send_debug_setup(host);
+    if (mc_state != MC_RECONFIGURING) {
+      send_debug_setup(host);
+    }
+  }
+}
+
+void MainController::configure_mtc()
+{
+  if (config_str == NULL) {
+    fatal_error("MainController::configure_mtc: no config file");
+  }
+  if (mtc->tc_state != TC_IDLE) {
+    error("MainController::configure_mtc(): MTC is in wrong state.");
+  }
+  else {
+    mtc->tc_state = MTC_CONFIGURING;
+    send_configure_mtc(config_str);
   }
 }
 
 void MainController::check_all_hc_configured()
 {
+  bool reconf = mc_state == MC_RECONFIGURING;
   if (is_hc_in_state(HC_CONFIGURING) ||
     is_hc_in_state(HC_CONFIGURING_OVERLOADED)) return;
   if (is_hc_in_state(HC_IDLE)) {
     error("There were errors during configuring HCs.");
-    mc_state = MC_HC_CONNECTED;
+    mc_state = reconf ? MC_READY : MC_HC_CONNECTED;
   } else if (is_hc_in_state(HC_ACTIVE) || is_hc_in_state(HC_OVERLOADED)) {
     notify("Configuration file was processed on all HCs.");
-    mc_state = MC_ACTIVE;
+    mc_state = reconf ? MC_READY : MC_ACTIVE;
   } else {
     error("There is no HC connection after processing the configuration "
       "file.");
@@ -2782,6 +2799,7 @@ void MainController::handle_hc_data(host_struct *hc, boolean recv_from_socket)
       if (all_hc_in_state(HC_DOWN)) mc_state = MC_LISTENING;
       break;
     case MC_CONFIGURING:
+    case MC_RECONFIGURING:
       check_all_hc_configured();
       break;
     case MC_ACTIVE:
@@ -2901,6 +2919,12 @@ void MainController::handle_tc_data(component_struct *tc,
             case MSG_MTC_READY:
               process_mtc_ready();
               break;
+            case MSG_CONFIGURE_ACK:
+              process_configure_ack_mtc();
+              break;
+            case MSG_CONFIGURE_NAK:
+              process_configure_nak_mtc();
+              break;
             default:
               error("Invalid message type (%d) was received "
                 "from the MTC at %s [%s].", message_type,
@@ -3538,6 +3562,15 @@ void MainController::send_exit_mtc()
   send_message(mtc->tc_fd, text_buf);
 }
 
+void MainController::send_configure_mtc(const char* config_file)
+{
+  Text_Buf text_buf;
+  text_buf.push_int(MSG_CONFIGURE);
+  text_buf.push_string(config_file);
+  send_message(mtc->tc_fd, text_buf);
+}
+
+
 void MainController::send_cancel_done_ptc(component_struct *tc,
   component component_reference)
 {
@@ -3840,7 +3873,8 @@ void MainController::process_configure_ack(host_struct *hc)
       "received.");
     return;
   }
-  if (mc_state == MC_CONFIGURING) check_all_hc_configured();
+  if (mc_state == MC_CONFIGURING || mc_state == MC_RECONFIGURING)
+    check_all_hc_configured();
   else notify("Host %s was configured successfully.", hc->hostname);
   status_change();
 }
@@ -3857,7 +3891,8 @@ void MainController::process_configure_nak(host_struct *hc)
       "received.");
     return;
   }
-  if (mc_state == MC_CONFIGURING) check_all_hc_configured();
+  if (mc_state == MC_CONFIGURING || mc_state == MC_RECONFIGURING)
+    check_all_hc_configured();
   else notify("Processing of configuration file failed on host %s.",
     hc->hostname);
   status_change();
@@ -5766,6 +5801,26 @@ void MainController::process_mtc_ready()
   status_change();
 }
 
+void MainController::process_configure_ack_mtc()
+{
+  if (mtc->tc_state != MTC_CONFIGURING) {
+    send_error_str(mtc->tc_fd, "Unexpected message CONFIGURE_ACK was received.");
+    return;
+  }
+  mtc->tc_state = TC_IDLE;
+  notify("Configuration file was processed on the MTC.");
+}
+
+void MainController::process_configure_nak_mtc()
+{
+  if (mtc->tc_state != MTC_CONFIGURING) {
+    send_error_str(mtc->tc_fd, "Unexpected message CONFIGURE_NAK was received.");
+    return;
+  }
+  mtc->tc_state = TC_IDLE;
+  notify("Processing of configuration file failed on the MTC.");
+}
+
 void MainController::process_stopped(component_struct *tc, int message_end)
 {
   switch (tc->tc_state) {
@@ -6049,12 +6104,20 @@ void MainController::destroy_host_groups()
 void MainController::set_kill_timer(double timer_val)
 {
   lock();
-  if (mc_state != MC_INACTIVE)
+  switch (mc_state) {
+  case MC_INACTIVE:
+  case MC_LISTENING:
+  case MC_HC_CONNECTED:
+  case MC_RECONFIGURING:
+    if (timer_val < 0.0)
+      error("MainController::set_kill_timer: setting a negative kill timer "
+        "value.");
+    else kill_timer = timer_val;
+    break;
+  default:
     error("MainController::set_kill_timer: called in wrong state.");
-  else if (timer_val < 0.0)
-    error("MainController::set_kill_timer: setting a negative kill timer "
-      "value.");
-  else kill_timer = timer_val;
+    break;
+  }
   unlock();
 }
 
@@ -6309,6 +6372,8 @@ void MainController::configure(const char *config_file)
   case MC_LISTENING_CONFIGURED:
     mc_state = MC_LISTENING_CONFIGURED;
     break;
+  case MC_RECONFIGURING:
+    break;
   default:
     error("MainController::configure: called in wrong state.");
     unlock();
@@ -6316,14 +6381,35 @@ void MainController::configure(const char *config_file)
   }
   Free(config_str);
   config_str = mcopystr(config_file);
-  if(mc_state == MC_CONFIGURING) {
+  if (mc_state == MC_CONFIGURING || mc_state == MC_RECONFIGURING) {
     notify("Downloading configuration file to all HCs.");
     for (int i = 0; i < n_hosts; i++) configure_host(hosts[i], FALSE);
   }
+  if (mc_state == MC_RECONFIGURING) {
+    notify("Downloading configuration file to the MTC.");
+    configure_mtc();
+  }
   status_change();
   unlock();
 }
 
+bool MainController::start_reconfiguring()
+{
+  switch (mc_state) {
+  case MC_READY:
+    mc_state = MC_RECONFIGURING;
+    return true;
+  case MC_LISTENING:
+  case MC_HC_CONNECTED:
+    return true;
+  default:
+    lock();
+    error("MainController::start_reconfiguring: called in wrong state.");
+    unlock();
+    return false;
+  }
+}
+
 void MainController::create_mtc(int host_index)
 {
   lock();
@@ -6415,7 +6501,7 @@ void MainController::create_mtc(int host_index)
 void MainController::exit_mtc()
 {
   lock();
-  if (mc_state != MC_READY) {
+  if (mc_state != MC_READY && mc_state != MC_RECONFIGURING) {
     error("MainController::exit_mtc: called in wrong state.");
     unlock();
     return;
index 561c665a3314a94e42ef2f2c4cae8613091aae52..c670f01f6130b915c36914cf0a500433ec640eb0 100644 (file)
@@ -63,7 +63,7 @@ enum mc_state_enum {
   MC_INACTIVE, MC_LISTENING, MC_LISTENING_CONFIGURED, MC_HC_CONNECTED,
   MC_CONFIGURING, MC_ACTIVE, MC_SHUTDOWN, MC_CREATING_MTC, MC_READY,
   MC_TERMINATING_MTC, MC_EXECUTING_CONTROL, MC_EXECUTING_TESTCASE,
-  MC_TERMINATING_TESTCASE, MC_PAUSED
+  MC_TERMINATING_TESTCASE, MC_PAUSED, MC_RECONFIGURING
 };
 
 /** Data structure for unknown incoming connections (before receiving
@@ -164,7 +164,7 @@ enum tc_state_enum { TC_INITIAL, TC_IDLE, TC_CREATE, TC_START, TC_STOP, TC_KILL,
   MTC_CONTROLPART, MTC_TESTCASE, MTC_ALL_COMPONENT_STOP,
   MTC_ALL_COMPONENT_KILL, MTC_TERMINATING_TESTCASE, MTC_PAUSED,
   PTC_FUNCTION, PTC_STARTING, PTC_STOPPED, PTC_KILLING, PTC_STOPPING_KILLING,
-  PTC_STALE, TC_SYSTEM };
+  PTC_STALE, TC_SYSTEM, MTC_CONFIGURING };
 
 /** Data structure for each TC */
 struct component_struct {
@@ -345,6 +345,7 @@ class MainController {
   static boolean is_hc_in_state(hc_state_enum checked_state);
   static boolean all_hc_in_state(hc_state_enum checked_state);
   static void configure_host(host_struct *host, boolean should_notify);
+  static void configure_mtc();
   static void check_all_hc_configured();
   static void add_component_to_host(host_struct *host,
     component_struct *comp);
@@ -544,6 +545,7 @@ private:
   static void send_ptc_verdict(boolean continue_execution);
   static void send_continue();
   static void send_exit_mtc();
+  static void send_configure_mtc(const char *config_file);
 
   /** Messages to PTCs */
   static void send_cancel_done_ptc(component_struct *tc,
@@ -607,6 +609,8 @@ private:
   static void process_testcase_started();
   static void process_testcase_finished();
   static void process_mtc_ready();
+  static void process_configure_ack_mtc();
+  static void process_configure_nak_mtc();
 
   /* Incoming messages from PTCs */
   static void process_stopped(component_struct *tc, int message_end);
@@ -629,6 +633,7 @@ public:
   static void shutdown_session();
 
   static void configure(const char *config_file);
+  static bool start_reconfiguring();
 
   static void create_mtc(int host_index);
   static void exit_mtc();
index a440e5d62ec66b7e9d4ddd52d11b68c603476180..430e53215fdb5c788ae9dae09b4307ef7ff58387 100644 (file)
Binary files a/usrguide/userguide.doc and b/usrguide/userguide.doc differ
This page took 0.031872 seconds and 5 git commands to generate.