Tests: iron out some kinks 21/214721/2
authorMichal Bloch <m.bloch@samsung.com>
Tue, 24 Sep 2019 12:31:54 +0000 (14:31 +0200)
committerMichal Bloch <m.bloch@samsung.com>
Wed, 25 Sep 2019 14:12:55 +0000 (16:12 +0200)
Change-Id: Ie3f815ffd313a810b5a6f49b96c3de51bae3f4b0
Signed-off-by: Michal Bloch <m.bloch@samsung.com>
tests/test-stability-cpu.cpp
tests/test-stability-fd.cpp
tests/test-stability-io.cpp
tests/test-stability-mem.cpp
tests/test-stability.cpp
tests/test-stability.hpp

index 15095a9..6fc421a 100644 (file)
 
 cpu_handler handler_avg ("avg"), handler_peak ("peak");
 
+static void try_kill (pid_t child)
+{
+       if (kill (child, SIGKILL) == -1)
+               throw_errno ("kill(" + std::to_string(child) + ", SIGKILL) failed");
+}
+
 int main (int argc, char ** argv)
 {
        const std::vector <std::pair <bool (*) (), std::string>> test_cases
@@ -73,13 +79,13 @@ int main (int argc, char ** argv)
                                handler_avg .child_pid = child;
 
                                if (! run_throttled (child, 60, & handler_peak, TEST_TIME_PEAK)) {
-                                       kill (child, SIGKILL);
+                                       try_kill (child);
                                        return false;
                                }
 
                                std::this_thread::sleep_for (CATCH_STRAGGLER_SIGNALS_TIME);
                                bool ret = ! run_throttled (child, 60, & handler_avg , TEST_TIME_AVG - TEST_TIME_PEAK);
-                               kill (child, SIGKILL);
+                               try_kill (child);
                                return ret;
                        }
                } , "running at ~60% CPU (using SIGSTOP/SIGCONT on child), expecting average signal (but not peak)"
index 47ffa0c..40b526b 100644 (file)
@@ -22,7 +22,8 @@ static void * open_fds (size_t count)
 
        for (const auto fd : fds)
                if (fd != -1)
-                       close (fd);
+                       if (close (fd) == -1)
+                               throw_errno ("close() failed");
 
        return nullptr;
 }
index 498da68..7d3ef4a 100644 (file)
@@ -15,14 +15,14 @@ static void * do_io (size_t delay)
         * the sum of both matters and it's good not to have to keep
         * extra files on the disk to read from.  */
 
-       static constexpr const char *  IN_FILE_PATH = "/dev/zero";
-       static constexpr const char * OUT_FILE_PATH = "/opt/usr/stability-test.out";
+       static const std::string  IN_FILE_PATH = "/dev/zero";
+       static const std::string OUT_FILE_PATH = "/opt/usr/stability-test.out";
 
        std::ifstream in  ( IN_FILE_PATH, std::ifstream::binary);
        std::ofstream out (OUT_FILE_PATH, std::ofstream::binary);
        if (!  in.good ()
        ||  ! out.good ())
-               throw std::runtime_error (std::string("Couldn't open ") + IN_FILE_PATH + " and " + OUT_FILE_PATH);
+               throw std::runtime_error ("Couldn't open " + IN_FILE_PATH + " and " + OUT_FILE_PATH);
 
        /* Buffering is undesirable here; it affects the underlying I/O
         * in an unpredictable way, ruining measurements. */
@@ -42,17 +42,18 @@ static void * do_io (size_t delay)
         in.close ();
        out.close ();
 
-       std::remove (OUT_FILE_PATH);
+       if (remove (OUT_FILE_PATH.c_str()) == -1)
+               throw_errno ("remove(" + OUT_FILE_PATH + ") failed");
 
        return nullptr;
 }
 
 static void * io_heavy (void * arg)
-{ do_io (10); }
+{ return do_io (10); }
 static void * io_light (void * arg)
-{ do_io (1000); }
+{ return do_io (1000); }
 static void * io_medium (void * arg)
-{ do_io (40); }
+{ return do_io (40); }
 
 struct io_handler : public dbus_signal_handler {
        const std::string limitType;
index 930c9b6..e2ae8de 100644 (file)
@@ -81,7 +81,12 @@ bool run_mem_test (thread_func_t * func, size_t test_time, dbus_signal_handler *
 
 int main (int argc, char ** argv)
 {
-       get_total_ram ();
+       try {
+               get_total_ram ();
+       } catch (const std::exception & ex) {
+               std::cout << ex.what () << std::endl;
+               return EXIT_FAILURE;
+       }
 
        const std::vector <std::pair <bool (*) (), std::string>> test_cases
                { { []() {
index bb3365a..c640c42 100644 (file)
 // C++
 #include <chrono>
 #include <exception>
-#include <iostream>
 #include <fstream>
+#include <iostream>
 #include <map>
 #include <memory>
 #include <numeric>
-#include <system_error>
 #include <thread>
 #include <vector>
 
@@ -40,9 +39,6 @@
 #include <pthread.h>
 #include <unistd.h>
 
-static inline void throw_errno (const std::string & what)
-{ throw std::system_error (errno, std::generic_category (), what); }
-
 /* Globals because passing them around would be a massive hassle. */
 bool timed_out = false;
 bool global_stop = false;
@@ -134,10 +130,31 @@ static void set_affinity (pthread_t pt, size_t affinity)
        pthread_setaffinity_np (pt, sizeof cpu_set, & cpu_set);
 }
 
+typedef std::pair <thread_func_t *, void *> thread_fwd_t;
+static void * safe_thread (void * params_ptr) try
+{
+       /* Threads can throw exceptions; this wrapper
+        * makes sure that nothing slips through, which
+        * would otherwise crash the entire program. */
+
+       std::unique_ptr <thread_fwd_t> params (reinterpret_cast <thread_fwd_t *> (params_ptr));
+       return params->first (params->second);
+}
+catch (const std::exception & ex)
+{
+       std::cout << "Thread caught exception: " << ex.what () << std::endl;
+       return nullptr;
+}
+catch (...)
+{
+       std::cout << "Thread caught unknown exception" << std::endl;
+       return nullptr;
+}
+
 static inline pthread_t spawn_thread (thread_func_t * func, int param)
 {
        pthread_t pt;
-       if (pthread_create(& pt, nullptr, func, reinterpret_cast <void *> (param)))
+       if (pthread_create(& pt, nullptr, safe_thread, new thread_fwd_t (func, reinterpret_cast <void *> (param))))
                throw_errno ("pthread_create");
        return pt;
 }
@@ -212,7 +229,8 @@ static void * throttle (void * arg)
 
        /* Finish with a SIGSTOP so that heavy throttlees do not
         * keep running at full speed and trigger something. */
-       kill (throttlee, SIGSTOP);
+       if (kill (throttlee, SIGSTOP) == -1)
+               throw_errno ("kill(" + std::to_string (throttlee) + ", SIGSTOP) failed");
 
        return nullptr;
 }
index 14f4fcd..1bd2a04 100644 (file)
@@ -6,6 +6,7 @@
 // C++
 #include <chrono>
 #include <string>
+#include <system_error>
 #include <vector>
 
 // POSIX
@@ -37,6 +38,9 @@ struct dbus_signal_handler {
        virtual bool match (const gchar * objpath, const gchar * iface, GVariant * parameters) const = 0;
 };
 
+static inline void throw_errno (const std::string & what)
+{ throw std::system_error (errno, std::generic_category (), what); }
+
 extern bool timed_out;
 extern bool global_stop;
 extern GMainLoop * loop;