[Apptest] Add test checking how to handle SIGKILL events
authorDongju Chae <dongju.chae@samsung.com>
Fri, 9 Jul 2021 01:41:30 +0000 (10:41 +0900)
committer채동주/On-Device Lab(SR)/Staff Engineer/삼성전자 <dongju.chae@samsung.com>
Fri, 9 Jul 2021 05:25:29 +0000 (14:25 +0900)
This patch adds extra apptest to check how to handle SIGKILL events.

Signed-off-by: Dongju Chae <dongju.chae@samsung.com>
tests/apptests/meson.build
tests/apptests/tvn_triv2_sigkill.cc [new file with mode: 0644]

index 36b4fda..bfa55ac 100644 (file)
@@ -136,3 +136,13 @@ executable ('apptest_tvn_triv2_interleave',
   install_rpath : ne_libdir,
   install_dir : join_paths(ne_bindir, 'apptests')
 )
+
+executable ('apptest_tvn_triv2_sigkill',
+  'tvn_triv2_sigkill.cc',
+  include_directories : ne_apptest_inc,
+  dependencies : ne_test_utils_dep,
+  link_with : ne_library_shared,
+  install : true,
+  install_rpath : ne_libdir,
+  install_dir : join_paths(ne_bindir, 'apptests')
+)
diff --git a/tests/apptests/tvn_triv2_sigkill.cc b/tests/apptests/tvn_triv2_sigkill.cc
new file mode 100644 (file)
index 0000000..84fb11d
--- /dev/null
@@ -0,0 +1,148 @@
+/**
+ * Proprietary
+ * Copyright (C) 2021 Samsung Electronics
+ * Copyright (C) 2021 Dongju Chae <dongju.chae@samsung.com>
+ */
+/**
+ * @file tvn_triv2_sigkill.cc
+ * @date 09 Jul 2020
+ * @brief AppTest to test how to handle a SIGKILL event
+ * @author Dongju Chae <dongju.chae@samsung.com>
+ * @bug No known bugs except for NYI items
+ */
+
+#include <iostream>
+
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <unistd.h>
+#include <errno.h>
+
+#include <ne_test_utils.h>
+
+using namespace std;
+
+#define NPU_TOPS (2)
+#define NPU_TIMEOUT_MS (1000)
+#define NPU_MAX_RETRY (3)
+
+static pid_t ppid, cpid;
+
+static int
+work_child (int argc, char **argv) {
+  const char *help = "model_dir";
+  UtilTRIV2 tester;
+  int index, status;
+
+  status = tester.parseArgs (argc, argv, help, &index);
+  if (status == test_ret_skipped || index < 0)
+    return test_ret_skipped;
+
+  if (argc < index + 1) {
+    cerr << "Need additional arguments..\n";
+    return status;
+  }
+
+  status = tester.init (NPU_TOPS);
+  if (status != test_ret_success) {
+    cerr << "Failed to initialize\n";
+    return status;
+  }
+
+  const char *model_dir = argv[index];
+  uint32_t model_id;
+  int req_id;
+
+  status =
+      tester.loadModel (model_dir, &model_id, NPU_PRIORITY_MID, NPU_TIMEOUT_MS);
+  if (status != test_ret_success) {
+    cerr << "Unable to load model\n";
+    return status;
+  }
+
+  req_id = tester.createRequest (model_id);
+  if (req_id < 0)
+    return req_id;
+
+  status = tester.submitRequest (req_id);
+  if (status < 0) {
+    tester.unloadModel (model_id);
+    return status;
+  }
+
+  /* now, waiting to be killed */
+  kill (ppid, SIGINT);
+  sleep (10);
+
+  /* not reachable */
+  return test_ret_failure;
+}
+
+static void
+sig_handler (int signo) {
+  /* kill child process when it gets ready */
+  if (signo == SIGINT)
+    kill (cpid, SIGKILL);
+}
+
+static void
+work_parent () {
+  /* register signal handler */
+  signal (SIGINT, sig_handler);
+}
+
+/** @brief apptest main  */
+int
+main (int argc, char **argv) {
+  pid_t pid;
+  int cur_retry, max_retry;
+  int status = test_ret_success;
+
+  max_retry = NPU_MAX_RETRY;
+  cur_retry = 0;
+
+retry:
+  if (max_retry <= cur_retry)
+    goto out;
+
+  ppid = getpid ();
+  pid = fork ();
+  if (pid == -1) {
+    status = -errno;
+    goto out;
+  }
+
+  if (pid == 0) {
+    /* child process */
+    exit (work_child (argc, argv));
+  } else {
+    /* parent process */
+    cpid = pid;
+    work_parent ();
+    wait (&status);
+    if (WIFEXITED (status)) {
+      /* normal exit */
+      status = WEXITSTATUS (status);
+    } else if (WIFSIGNALED (status)) {
+      /* signal exit */
+      status = WTERMSIG (status);
+      if (status == SIGKILL) {
+        status = test_ret_success;
+        cur_retry++;
+        goto retry;
+      }
+    }
+  }
+
+out:
+  if (status == test_ret_success) {
+    cerr << "[APPTEST] " << argv[0] << ": PASSED\n";
+    return 0;
+  } else if (status == test_ret_skipped) {
+    cerr << "[APPTEST] " << argv[0] << ": SKIPPED\n";
+    return 0;
+  } else {
+    cerr << "[APPTEST] " << argv[0] << ": FAILED (" << status << ")\n";
+    return status;
+  }
+}