Update libtest.
authorBrian Aker <brian@tangent.org>
Wed, 2 May 2012 18:38:32 +0000 (11:38 -0700)
committerBrian Aker <brian@tangent.org>
Wed, 2 May 2012 18:38:32 +0000 (11:38 -0700)
23 files changed:
libtest/collection.cc [new file with mode: 0644]
libtest/collection.h
libtest/common.h
libtest/fatal.cc
libtest/fatal.hpp
libtest/framework.cc
libtest/framework.h
libtest/include.am
libtest/main.cc
libtest/port.cc
libtest/server.cc
libtest/server_container.cc
libtest/server_container.h
libtest/stats.h [deleted file]
libtest/stream.cc [new file with mode: 0644]
libtest/stream.h
libtest/test.hpp
libtest/timer.cc [new file with mode: 0644]
libtest/timer.hpp [new file with mode: 0644]
tests/cycle.cc
tests/failure.cc
tests/include.am
tests/runner.h

diff --git a/libtest/collection.cc b/libtest/collection.cc
new file mode 100644 (file)
index 0000000..c6fec1e
--- /dev/null
@@ -0,0 +1,179 @@
+/*  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
+ *
+ *  Data Differential YATL (i.e. libtest)  library
+ *
+ *  Copyright (C) 2012 Data Differential, http://datadifferential.com/
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are
+ *  met:
+ *
+ *      * Redistributions of source code must retain the above copyright
+ *  notice, this list of conditions and the following disclaimer.
+ *
+ *      * Redistributions in binary form must reproduce the above
+ *  copyright notice, this list of conditions and the following disclaimer
+ *  in the documentation and/or other materials provided with the
+ *  distribution.
+ *
+ *      * The names of its contributors may not be used to endorse or
+ *  promote products derived from this software without specific prior
+ *  written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include <config.h>
+
+#include <libtest/common.h>
+
+static test_return_t runner_code(Framework* frame,
+                                 test_st* run, 
+                                 libtest::Timer& _timer)
+{ // Runner Code
+
+  assert(frame->runner());
+  assert(run->test_fn);
+
+  test_return_t return_code;
+  try 
+  {
+    _timer.reset();
+    return_code= frame->runner()->run(run->test_fn, frame->creators_ptr());
+  }
+  // Special case where check for the testing of the exception
+  // system.
+  catch (libtest::fatal &e)
+  {
+    if (libtest::fatal::is_disabled())
+    {
+      libtest::fatal::increment_disabled_counter();
+      return_code= TEST_SUCCESS;
+    }
+    else
+    {
+      throw;
+    }
+  }
+
+  _timer.sample();
+
+  return return_code;
+}
+
+namespace libtest {
+
+Collection::Collection(Framework* frame_arg,
+                       collection_st* arg) :
+  _name(arg->name),
+  _pre(arg->pre),
+  _post(arg->post),
+  _tests(arg->tests),
+  _frame(frame_arg),
+  _success(0),
+  _skipped(0),
+  _failed(0),
+  _total(0)
+{
+  fatal_assert(arg);
+}
+
+test_return_t Collection::exec()
+{
+  Out << "Collection: " << _name;
+
+  if (test_success(_frame->runner()->pre(_pre, _frame->creators_ptr())))
+  {
+    for (test_st *run= _tests; run->name; run++)
+    {
+      long int load_time= 0;
+
+      if (_frame->match(run->name))
+      {
+        continue;
+      }
+      _total++;
+
+      test_return_t return_code;
+      try 
+      {
+        if (run->requires_flush)
+        {
+          if (test_failed(_frame->runner()->flush(_frame->creators_ptr())))
+          {
+            Error << "frame->runner()->flush(creators_ptr)";
+            _skipped++;
+            continue;
+          }
+        }
+
+        return_code= runner_code(_frame, run, _timer);
+      }
+      catch (libtest::fatal &e)
+      {
+        Error << "Fatal exception was thrown: " << e.what();
+        return_code= TEST_FAILURE;
+        _failed++;
+        throw;
+      }
+
+      switch (return_code)
+      {
+      case TEST_SUCCESS:
+        Out << "\tTesting " 
+          << run->name
+          <<  "\t\t\t\t\t" 
+          << _timer 
+          << " [ " << test_strerror(return_code) << " ]";
+        _success++;
+        break;
+
+      case TEST_FAILURE:
+        _failed++;
+        Out << "\tTesting " << run->name <<  "\t\t\t\t\t" << "[ " << test_strerror(return_code) << " ]";
+        break;
+
+      case TEST_SKIPPED:
+        _skipped++;
+        Out << "\tTesting " << run->name <<  "\t\t\t\t\t" << "[ " << test_strerror(return_code) << " ]";
+        break;
+
+      default:
+        fatal_message("invalid return code");
+      }
+#if 0
+      @TODO add code here to allow for a collection to define a method to reset to allow tests to continue.
+#endif
+    }
+
+    (void) _frame->runner()->post(_post, _frame->creators_ptr());
+  }
+
+  if (_failed == 0 and _skipped == 0 and _success)
+  {
+    return TEST_SUCCESS;
+  }
+
+  if (_failed)
+  {
+    return TEST_FAILURE;
+  }
+
+  fatal_assert(_skipped or _success == 0);
+
+  return TEST_SKIPPED;
+}
+
+} // namespace libtest
+
index 044acf036b4db7c6fca3d5494f5f6992117c1ab5..91c76a6d7f9084558a892f2c3779855af2c51471 100644 (file)
 
 #pragma once
 
+#include <libtest/timer.hpp>
+
+class Framework;
+
 /**
   A structure which describes a collection of test cases.
 */
@@ -46,4 +50,50 @@ struct collection_st {
   struct test_st *tests;
 };
 
+namespace libtest {
+
+class Collection {
+public:
+  Collection(Framework*, collection_st*);
+
+  test_return_t exec();
+
+  const char* name()
+  {
+    return _name;
+  }
+
+  uint32_t success()
+  {
+    return _success;
+  }
+
+  uint32_t skipped()
+  {
+    return _skipped;
+  }
+
+  uint32_t failed()
+  {
+    return _failed;
+  }
+
+  uint32_t total()
+  {
+    return _total;
+  }
+
+private:
+  const char *_name;
+  test_callback_fn *_pre;
+  test_callback_fn *_post;
+  struct test_st *_tests;
+  Framework* _frame;
+  uint32_t _success;
+  uint32_t _skipped;
+  uint32_t _failed;
+  uint32_t _total;
+  libtest::Timer _timer;
+};
 
+} // namespace libtest
index a9221916a6139f3ef34e9dc6dc2b361a35b2f4a4..777d21c3cfd85fb0d2ecb136512c9b878aba911a 100644 (file)
@@ -76,6 +76,5 @@
 
 #include <libtest/libtool.hpp>
 #include <libtest/killpid.h>
-#include <libtest/stats.h>
 #include <libtest/signal.h>
 
index 75e276d549aca4ff1bf139a7f6214a3ca9b10f61..9ab3292f3c0a4bec0d0ac14440e0972204e9d7e4 100644 (file)
 
 namespace libtest {
 
-fatal::fatal(const char *file, int line, const char *func, const char *format, ...) :
-  std::runtime_error(func)
+fatal::fatal(const char *file_arg, int line_arg, const char *func_arg, const char *format, ...) :
+  std::runtime_error(func_arg),
+  _file(file_arg),
+  _line(line_arg),
+  _func(func_arg)
   {
     va_list args;
     va_start(args, format);
     char last_error[BUFSIZ];
-    (void)vsnprintf(last_error, sizeof(last_error), format, args);
+    int last_error_length= vsnprintf(last_error, sizeof(last_error), format, args);
     va_end(args);
 
-    snprintf(_error_message, sizeof(_error_message), "%s:%d FATAL:%s (%s)", file, int(line), last_error, func);
+    strncpy(_mesg, last_error, sizeof(_mesg));
+
+    snprintf(_error_message, sizeof(_error_message), "%s:%d FATAL:%s (%s)", _file, int(_line), last_error, _func);
   }
 
 static bool _disabled= false;
index bc288afeb767cf72498ee86348364dc830c5039f..54f672b652a8808973de15800def96a430e8d009 100644 (file)
@@ -56,6 +56,11 @@ public:
     return _error_message;
   }
 
+  const char* mesg() const throw()
+  {
+    return _error_message;
+  }
+
   // The following are just for unittesting the exception class
   static bool is_disabled();
   static void disable();
@@ -63,8 +68,27 @@ public:
   static uint32_t disabled_counter();
   static void increment_disabled_counter();
 
+  int line()
+  {
+    return _line;
+  }
+
+  const char*  file()
+  {
+    return _file;
+  }
+
+  const char* func()
+  {
+    return _func;
+  }
+
 private:
   char _error_message[BUFSIZ];
+  char _mesg[BUFSIZ];
+  int _line;
+  const char*  _file;
+  const char* _func;
 };
 
 class disconnected : std::runtime_error
index 3bab5f0ad3f414f702529f1994c842a4847a746f..114dae46b71e02da242a055dbeb6e3c479164ecd 100644 (file)
  */
 
 #include <config.h>
+
 #include <libtest/common.h>
+#include <libtest/collection.h>
+#include <libtest/signal.h>
+
 #include <iostream>
 
 using namespace libtest;
 
-Framework::Framework() :
+Framework::Framework(libtest::SignalThread& signal,
+                     const std::string& only_run_arg,
+                     const std::string& wildcard_arg) :
   collections(NULL),
+  _total(0),
+  _success(0),
+  _skipped(0),
+  _failed(0),
   _create(NULL),
   _destroy(NULL),
   _runner(NULL),
   _socket(false),
-  _creators_ptr(NULL)
+  _creators_ptr(NULL),
+  _signal(signal),
+  _only_run(only_run_arg),
+  _wildcard(wildcard_arg)
 {
+  get_world(this);
+
+  for (collection_st *next= collections; next and next->name; next++)
+  {
+    _collection.push_back(new Collection(this, next));
+  }
 }
 
 Framework::~Framework()
@@ -60,6 +79,121 @@ Framework::~Framework()
   _servers.shutdown();
 
   delete _runner;
+
+  for (std::vector<Collection*>::iterator iter= _collection.begin();
+       iter != _collection.end();
+       iter++)
+  {
+    delete *iter;
+  }
+}
+
+bool Framework::match(const char* arg)
+{
+  if (_wildcard.empty() == false and fnmatch(_wildcard.c_str(), arg, 0))
+  {
+    return true;
+  }
+
+  return false;
+}
+
+void Framework::exec()
+{
+  for (std::vector<Collection*>::iterator iter= _collection.begin();
+       iter != _collection.end() and (_signal.is_shutdown() == false);
+       iter++)
+  {
+    if (_only_run.empty() == false and
+        fnmatch(_only_run.c_str(), (*iter)->name(), 0))
+    {
+      continue;
+    }
+
+    _total++;
+
+    try {
+      switch ((*iter)->exec())
+      {
+      case TEST_FAILURE:
+        _failed++;
+        break;
+
+      case TEST_SKIPPED:
+        _skipped++;
+        break;
+
+        // exec() can return SUCCESS, but that doesn't mean that some tests did
+        // not fail or get skipped.
+      case TEST_SUCCESS:
+        _success++;
+        break;
+      }
+    }
+    catch (libtest::fatal& e)
+    {
+      stream::cerr(e.file(), e.line(), e.func()) << e.mesg();
+    }
+    catch (libtest::disconnected& e)
+    {
+      Error << "Unhandled disconnection occurred:" << e.what();
+      throw;
+    }
+
+    Outn();
+  }
+}
+
+uint32_t Framework::sum_total()
+{
+  uint32_t count= 0;
+  for (std::vector<Collection*>::iterator iter= _collection.begin();
+       iter != _collection.end();
+       iter++)
+  {
+    count+= (*iter)->total();
+  }
+
+  return count;
+}
+
+uint32_t Framework::sum_success()
+{
+  uint32_t count= 0;
+  for (std::vector<Collection*>::iterator iter= _collection.begin();
+       iter != _collection.end();
+       iter++)
+  {
+    count+= (*iter)->success();
+  }
+
+  return count;
+}
+
+uint32_t Framework::sum_skipped()
+{
+  uint32_t count= 0;
+  for (std::vector<Collection*>::iterator iter= _collection.begin();
+       iter != _collection.end();
+       iter++)
+  {
+    count+= (*iter)->skipped();
+  }
+
+  return count;
+}
+
+uint32_t Framework::sum_failed()
+{
+  uint32_t count= 0;
+  for (std::vector<Collection*>::iterator iter= _collection.begin();
+       iter != _collection.end();
+       iter++)
+  {
+    count+= (*iter)->failed();
+  }
+
+  return count;
 }
 
 libtest::Runner *Framework::runner()
@@ -73,13 +207,13 @@ libtest::Runner *Framework::runner()
   return _runner;
 }
 
-void* Framework::create(test_return_t& arg)
+test_return_t Framework::create()
 {
-  arg= TEST_SUCCESS;
+  test_return_t rc= TEST_SUCCESS;
   if (_create)
   {
-    return _creators_ptr= _create(_servers, arg);
+    _creators_ptr= _create(_servers, rc);
   }
 
-  return NULL;
+  return rc;
 }
index 00959c1829e457fb3518648b2c5c4c6c28c1e1a1..45cd6533c1f78fb413617aab8c62cbf69221b655 100644 (file)
 
 #pragma once
 
+#include <libtest/signal.h>
+
 /**
   Framework is the structure which is passed to the test implementation to be filled.
   This must be implemented in order for the test framework to load the tests. We call
   get_world() in order to fill this structure.
 */
 
+#include <vector>
+
 class Framework {
 public:
   collection_st *collections;
@@ -51,7 +55,7 @@ public:
   test_callback_destroy_fn *_destroy;
 
 public:
-  void* create(test_return_t& arg);
+  test_return_t create();
 
   /**
     If an error occurs during the test, this is called.
@@ -93,17 +97,74 @@ public:
 
   libtest::Runner *runner();
 
+  void exec();
 
-  Framework();
+  libtest::Collection& collection();
+
+  Framework(libtest::SignalThread&, const std::string&);
 
   virtual ~Framework();
 
-  Framework(const Framework&);
+  Framework(libtest::SignalThread&,
+            const std::string&,
+            const std::string&);
+
+  bool match(const char* arg);
+
+  void *creators_ptr()
+  {
+    return _creators_ptr;
+  }
+
+  libtest::SignalThread& signal()
+  {
+    return _signal;
+  }
+
+  uint32_t sum_total();
+  uint32_t sum_success();
+  uint32_t sum_skipped();
+  uint32_t sum_failed();
+
+  size_t size() 
+  {
+    return _collection.size();
+  }
+
+  uint32_t total() const
+  {
+    return _total;
+  }
+
+  uint32_t success() const
+  {
+    return _success;
+  }
+
+  uint32_t skipped() const
+  {
+    return _skipped;
+  }
+
+  uint32_t failed() const
+  {
+    return _failed;
+  }
 
 private:
   Framework& operator=(const Framework&);
+
+  uint32_t _total;
+  uint32_t _success;
+  uint32_t _skipped;
+  uint32_t _failed;
+
   libtest::server_startup_st _servers;
   bool _socket;
   void *_creators_ptr;
   unsigned long int _servers_to_run;
+  std::vector<libtest::Collection*> _collection;
+  libtest::SignalThread& _signal;
+  std::string _only_run;
+  std::string _wildcard;
 };
index 7b47fb114367d8af8c8cd0e9c742652f76e4a414..7e9be22da54672e5814bb197dc304a9bbec4ab4a 100644 (file)
@@ -42,6 +42,7 @@ CLEANFILES+= \
 distclean-libtest-check:
        -rm -rf tmp_chroot
 
+noinst_HEADERS+= libtest/timer.hpp
 noinst_HEADERS+= \
                 libtest/binaries.h \
                 libtest/cpu.hpp \
@@ -73,7 +74,6 @@ noinst_HEADERS+= \
                 libtest/server_container.h \
                 libtest/signal.h \
                 libtest/socket.hpp \
-                libtest/stats.h \
                 libtest/stream.h \
                 libtest/strerror.h \
                 libtest/string.hpp \
@@ -94,6 +94,7 @@ libtest_libtest_la_SOURCES=
 libtest_libtest_la_SOURCES+= libtest/binaries.cc 
 libtest_libtest_la_SOURCES+= libtest/cmdline.cc 
 libtest_libtest_la_SOURCES+= libtest/comparison.cc 
+libtest_libtest_la_SOURCES+= libtest/collection.cc 
 libtest_libtest_la_SOURCES+= libtest/core.cc 
 libtest_libtest_la_SOURCES+= libtest/cpu.cc 
 libtest_libtest_la_SOURCES+= libtest/dream.cc 
@@ -112,7 +113,9 @@ libtest_libtest_la_SOURCES+= libtest/server.cc
 libtest_libtest_la_SOURCES+= libtest/server_container.cc 
 libtest_libtest_la_SOURCES+= libtest/signal.cc 
 libtest_libtest_la_SOURCES+= libtest/socket.cc 
+libtest_libtest_la_SOURCES+= libtest/stream.cc 
 libtest_libtest_la_SOURCES+= libtest/strerror.cc 
+libtest_libtest_la_SOURCES+= libtest/timer.cc 
 libtest_libtest_la_SOURCES+= libtest/tmpfile.cc 
 libtest_libtest_la_SOURCES+= libtest/vchar.cc
 
index 0926dc6486568a35948b4060245fa60a53602372..3ae8ff988ebe14e0662dd9cd49b99ee582dab703 100644 (file)
 
 using namespace libtest;
 
-static void stats_print(Stats *stats)
+static void stats_print(Framework *frame)
 {
-  if (stats->collection_failed == 0 and stats->collection_success == 0)
+  if (frame->failed() == 0 and frame->success() == 0)
   {
     return;
   }
 
-  Out << "\tTotal Collections\t\t\t\t" << stats->collection_total;
-  Out << "\tFailed Collections\t\t\t\t" << stats->collection_failed;
-  Out << "\tSkipped Collections\t\t\t\t" << stats->collection_skipped;
-  Out << "\tSucceeded Collections\t\t\t\t" << stats->collection_success;
   Outn();
-  Out << "Total\t\t\t\t" << stats->total;
-  Out << "\tFailed\t\t\t" << stats->failed;
-  Out << "\tSkipped\t\t\t" << stats->skipped;
-  Out << "\tSucceeded\t\t" << stats->success;
-}
-
-static long int timedif(struct timeval a, struct timeval b)
-{
-  long us, s;
-
-  us = (long)(a.tv_usec - b.tv_usec);
-  us /= 1000;
-  s = (long)(a.tv_sec - b.tv_sec);
-  s *= 1000;
-  return s + us;
-}
-
-static test_return_t runner_code(Framework* frame,
-                                 test_st* run, 
-                                 void* creators_ptr, 
-                                 long int& load_time)
-{ // Runner Code
-
-  struct timeval start_time, end_time;
-
-  gettimeofday(&start_time, NULL);
-  assert(frame->runner());
-  assert(run->test_fn);
-
-  test_return_t return_code;
-  try 
-  {
-    return_code= frame->runner()->run(run->test_fn, creators_ptr);
-  }
-  // Special case where check for the testing of the exception
-  // system.
-  catch (libtest::fatal &e)
-  {
-    if (fatal::is_disabled())
-    {
-      fatal::increment_disabled_counter();
-      return_code= TEST_SUCCESS;
-    }
-    else
-    {
-      throw;
-    }
-  }
-
-  gettimeofday(&end_time, NULL);
-  load_time= timedif(end_time, start_time);
-
-  return return_code;
+  Out << "Collections\t\t\t\t\t" << frame->total();
+  Out << "\tFailed\t\t\t\t\t" << frame->failed();
+  Out << "\tSkipped\t\t\t\t\t" << frame->skipped();
+  Out << "\tSucceeded\t\t\t\t" << frame->success();
+  Outn();
+  Out << "Tests\t\t\t\t\t" << frame->sum_total();
+  Out << "\tFailed\t\t\t\t" << frame->sum_failed();
+  Out << "\tSkipped\t\t\t\t" << frame->sum_skipped();
+  Out << "\tSucceeded\t\t\t" << frame->sum_success();
 }
 
 #include <getopt.h>
@@ -134,6 +86,7 @@ int main(int argc, char *argv[])
   unsigned long int opt_repeat= 1; // Run all tests once
   bool opt_quiet= false;
   std::string collection_to_run;
+  std::string wildcard;
 
   // Options parsing
   {
@@ -142,6 +95,7 @@ int main(int argc, char *argv[])
       OPT_LIBYATL_MATCH_COLLECTION,
       OPT_LIBYATL_MASSIVE,
       OPT_LIBYATL_QUIET,
+      OPT_LIBYATL_MATCH_WILDCARD,
       OPT_LIBYATL_REPEAT
     };
 
@@ -151,6 +105,7 @@ int main(int argc, char *argv[])
       { "quiet", no_argument, NULL, OPT_LIBYATL_QUIET },
       { "repeat", no_argument, NULL, OPT_LIBYATL_REPEAT },
       { "collection", required_argument, NULL, OPT_LIBYATL_MATCH_COLLECTION },
+      { "wildcard", required_argument, NULL, OPT_LIBYATL_MATCH_WILDCARD },
       { "massive", no_argument, NULL, OPT_LIBYATL_MASSIVE },
       { 0, 0, 0, 0 }
     };
@@ -181,6 +136,10 @@ int main(int argc, char *argv[])
         collection_to_run= optarg;
         break;
 
+      case OPT_LIBYATL_MATCH_WILDCARD:
+        wildcard= optarg;
+        break;
+
       case OPT_LIBYATL_MASSIVE:
         opt_massive= true;
         break;
@@ -247,6 +206,24 @@ int main(int argc, char *argv[])
     return EXIT_FAILURE;
   }
 
+  if (getenv("YATL_COLLECTION_TO_RUN"))
+  {
+    if (strlen(getenv("YATL_COLLECTION_TO_RUN")))
+    {
+      collection_to_run= getenv("YATL_COLLECTION_TO_RUN");
+    }
+  }
+
+  if (collection_to_run.compare("none") == 0)
+  {
+    return EXIT_SUCCESS;
+  }
+
+  if (collection_to_run.empty() == false)
+  {
+    Out << "Only testing " <<  collection_to_run;
+  }
+
   int exit_code;
 
   try 
@@ -254,8 +231,6 @@ int main(int argc, char *argv[])
     do
     {
       exit_code= EXIT_SUCCESS;
-      std::auto_ptr<Framework> frame(new Framework);
-
       fatal_assert(sigignore(SIGPIPE) == 0);
 
       libtest::SignalThread signal;
@@ -265,182 +240,26 @@ int main(int argc, char *argv[])
         return EXIT_FAILURE;
       }
 
-      Stats stats;
-
-      get_world(frame.get());
-
-      test_return_t error;
-      void *creators_ptr= frame->create(error);
-
-      switch (error)
-      {
-      case TEST_SUCCESS:
-        break;
-
-      case TEST_SKIPPED:
-        Out << "SKIP " << argv[0];
-        return EXIT_SUCCESS;
-
-      case TEST_FAILURE:
-        return EXIT_FAILURE;
-      }
-
-      if (getenv("YATL_COLLECTION_TO_RUN"))
-      {
-        if (strlen(getenv("YATL_COLLECTION_TO_RUN")))
-        {
-          collection_to_run= getenv("YATL_COLLECTION_TO_RUN");
-        }
-      }
-
-      if (collection_to_run.compare("none") == 0)
-      {
-        return EXIT_SUCCESS;
-      }
-
-      if (collection_to_run.empty() == false)
-      {
-        Out << "Only testing " <<  collection_to_run;
-      }
-
-      char *wildcard= NULL;
-      if (argc == 3)
-      {
-        wildcard= argv[2];
-      }
+      std::auto_ptr<Framework> frame(new Framework(signal, collection_to_run, wildcard));
 
-      for (collection_st *next= frame->collections; next and next->name and (not signal.is_shutdown()); next++)
+      // Run create(), bail on error.
       {
-        if (collection_to_run.empty() == false and fnmatch(collection_to_run.c_str(), next->name, 0))
-        {
-          continue;
-        }
-
-        stats.collection_total++;
-
-        bool failed= false;
-        bool skipped= false;
-        test_return_t collection_rc;
-        if (test_success(collection_rc= frame->runner()->pre(next->pre, creators_ptr)))
-        {
-          Out << "Collection: " << next->name;
-
-          for (test_st *run= next->tests; run->name; run++)
-          {
-            long int load_time= 0;
-
-            if (wildcard && fnmatch(wildcard, run->name, 0))
-            {
-              continue;
-            }
-
-            test_return_t return_code;
-            try 
-            {
-              if (run->requires_flush)
-              {
-                if (test_failed(frame->runner()->flush(creators_ptr)))
-                {
-                  Error << "frame->runner()->flush(creators_ptr)";
-                  continue;
-                }
-              }
-
-              return_code= runner_code(frame.get(), run, creators_ptr, load_time);
-
-              if (return_code == TEST_SKIPPED)
-              { }
-              else if (return_code == TEST_FAILURE)
-              {
-#if 0
-                Error << " frame->runner()->run(failure)";
-                signal.set_shutdown(SHUTDOWN_GRACEFUL);
-#endif
-              }
-
-            }
-            catch (libtest::fatal &e)
-            {
-              Error << "Fatal exception was thrown: " << e.what();
-              return_code= TEST_FAILURE;
-              throw;
-            }
-            catch (std::exception &e)
-            {
-              Error << "Exception was thrown: " << e.what();
-              return_code= TEST_FAILURE;
-              throw;
-            }
-            catch (...)
-            {
-              Error << "Unknown exception occurred";
-              return_code= TEST_FAILURE;
-              throw;
-            }
-
-            stats.total++;
-
-            switch (return_code)
-            {
-            case TEST_SUCCESS:
-              Out << "\tTesting " << run->name <<  "\t\t\t\t\t" << load_time / 1000 << "." << load_time % 1000 << "[ " << test_strerror(return_code) << " ]";
-              stats.success++;
-              break;
-
-            case TEST_FAILURE:
-              stats.failed++;
-              failed= true;
-              Out << "\tTesting " << run->name <<  "\t\t\t\t\t" << "[ " << test_strerror(return_code) << " ]";
-              break;
-
-            case TEST_SKIPPED:
-              stats.skipped++;
-              skipped= true;
-              Out << "\tTesting " << run->name <<  "\t\t\t\t\t" << "[ " << test_strerror(return_code) << " ]";
-              break;
-
-            default:
-              fatal_message("invalid return code");
-            }
-#if 0
-            @TODO add code here to allow for a collection to define a method to reset to allow tests to continue.
-#endif
-          }
-
-          (void) frame->runner()->post(next->post, creators_ptr);
-        }
-        else if (collection_rc == TEST_FAILURE)
-        {
-          Out << next->name << " [ failed ]";
-          failed= true;
-#if 0
-          signal.set_shutdown(SHUTDOWN_GRACEFUL);
-#endif
-        }
-        else if (collection_rc == TEST_SKIPPED)
+        switch (frame->create())
         {
-          Out << next->name << " [ skipping ]";
-          skipped= true;
-        }
-
-        if (failed == false and skipped == false)
-        {
-          stats.collection_success++;
-        }
+        case TEST_SUCCESS:
+          break;
 
-        if (failed)
-        {
-          stats.collection_failed++;
-        }
+        case TEST_SKIPPED:
+          Out << "SKIP " << argv[0];
+          return EXIT_SUCCESS;
 
-        if (skipped)
-        {
-          stats.collection_skipped++;
+        case TEST_FAILURE:
+          return EXIT_FAILURE;
         }
-
-        Outn();
       }
 
+      frame->exec();
+
       if (signal.is_shutdown() == false)
       {
         signal.set_shutdown(SHUTDOWN_GRACEFUL);
@@ -452,21 +271,21 @@ int main(int argc, char *argv[])
         Out << "Tests were aborted.";
         exit_code= EXIT_FAILURE;
       }
-      else if (stats.collection_failed)
+      else if (frame->failed())
       {
         Out << "Some test failed.";
         exit_code= EXIT_FAILURE;
       }
-      else if (stats.collection_skipped and stats.collection_failed and stats.collection_success)
+      else if (frame->skipped() and frame->failed() and frame->success())
       {
         Out << "Some tests were skipped.";
       }
-      else if (stats.collection_success and (stats.collection_failed == 0))
+      else if (frame->success() and (frame->failed() == 0))
       {
         Out << "All tests completed successfully.";
       }
 
-      stats_print(&stats);
+      stats_print(frame.get());
 
       Outn(); // Generate a blank to break up the messages if make check/test has been run
     } while (exit_code == EXIT_SUCCESS and --opt_repeat);
@@ -474,18 +293,22 @@ int main(int argc, char *argv[])
   catch (libtest::fatal& e)
   {
     std::cerr << e.what() << std::endl;
+    exit_code= EXIT_FAILURE;
   }
   catch (libtest::disconnected& e)
   {
     std::cerr << "Unhandled disconnection occurred:" << e.what() << std::endl;
+    exit_code= EXIT_FAILURE;
   }
   catch (std::exception& e)
   {
     std::cerr << e.what() << std::endl;
+    exit_code= EXIT_FAILURE;
   }
   catch (...)
   {
     std::cerr << "Unknown exception halted execution." << std::endl;
+    exit_code= EXIT_FAILURE;
   }
 
   return exit_code;
index 3ef6bd70f1f33ae53a99d94a67d810cb0452ed29..9f9a5bfeede83d9053a1504b2f44cc70bc5e1ab5 100644 (file)
@@ -52,7 +52,6 @@
 
 #include <signal.h>
 
-#include <libtest/stats.h>
 #include <libtest/signal.h>
 
 #ifndef __INTEL_COMPILER
index 726a01ba61f015637ae3d0f082892f0348491db5..31c58094fa86e10bbbb3cc418491bb7c54783a4c 100644 (file)
@@ -164,7 +164,9 @@ bool Server::start()
   // If we find that we already have a pid then kill it.
   if (has_pid() == true)
   {
+#if 0
     fatal_message("has_pid() failed, programer error");
+#endif
   }
 
   // This needs more work.
@@ -262,28 +264,29 @@ bool Server::start()
       if (kill_file(pid_file()) == false)
       {
         throw libtest::fatal(LIBYATL_DEFAULT_PARAM,
-                             "Failed to kill off server, waited: %u after startup occurred, when pinging failed: %s stderr:%s",
+                             "Failed to kill off server, waited: %u after startup occurred, when pinging failed: %.*s stderr:%.*s",
                              this_wait,
-                             pid_file().c_str(),
-                             _app.stderr_c_str());
+                             int(_running.size()), _running.c_str(),
+                             int(_app.stderr_result_length()), _app.stderr_c_str());
       }
 
       throw libtest::fatal(LIBYATL_DEFAULT_PARAM, 
-                           "Failed native ping(), pid: %d is alive: %s waited: %u server started, having pid_file. exec: %s stderr:%s",
+                           "Failed native ping(), pid: %d is alive: %s waited: %u server started, having pid_file. exec: %.*s stderr:%.*s",
                            int(_app.pid()),
                            _app.check() ? "true" : "false",
-                           this_wait, _running.c_str(), 
-                           _app.stderr_c_str());
+                           this_wait,
+                           int(_running.size()), _running.c_str(),
+                           int(_app.stderr_result_length()), _app.stderr_c_str());
     }
     else
     {
       throw libtest::fatal(LIBYATL_DEFAULT_PARAM,
-                           "Failed native ping(), pid: %d is alive: %s waited: %u server started. exec: %s stderr:%s",
+                           "Failed native ping(), pid: %d is alive: %s waited: %u server started. exec: %.*s stderr:%.*s",
                            int(_app.pid()),
                            _app.check() ? "true" : "false",
                            this_wait,
-                           _running.c_str(),
-                           _app.stderr_c_str());
+                           int(_running.size()), _running.c_str(),
+                           int(_app.stderr_result_length()), _app.stderr_c_str());
     }
     _running.clear();
     return false;
index 3315b3bb5a6243a7cdc36929450b1f8d965c62de..f658e6ff83e54c9d4537c8f05cff936ba1e59e95 100644 (file)
@@ -91,13 +91,14 @@ Server* server_startup_st::pop_server()
   return tmp;
 }
 
-bool server_startup_st::shutdown(uint32_t number_of_host)
+// host_to_shutdown => host number to shutdown in array
+bool server_startup_st::shutdown(uint32_t host_to_shutdown)
 {
-  if (servers.size() > number_of_host)
+  if (servers.size() > host_to_shutdown)
   {
-    Server* tmp= servers[number_of_host];
+    Server* tmp= servers[host_to_shutdown];
 
-    if (tmp and tmp->has_pid() and tmp->kill() == false)
+    if (tmp and tmp->kill() == false)
     { }
     else
     {
@@ -108,7 +109,7 @@ bool server_startup_st::shutdown(uint32_t number_of_host)
   return false;
 }
 
-void server_startup_st::shutdown_and_remove()
+void server_startup_st::clear()
 {
   for (std::vector<Server *>::iterator iter= servers.begin(); iter != servers.end(); iter++)
   {
@@ -166,7 +167,7 @@ server_startup_st::server_startup_st() :
 
 server_startup_st::~server_startup_st()
 {
-  shutdown_and_remove();
+  clear();
 }
 
 bool server_startup_st::validate()
index 0a78c4f5345e94d2b6274ea4028097ce0a9d4ffd..b358e28dd93bbff7ce9cd40d47da10c42de9ac73 100644 (file)
@@ -112,7 +112,9 @@ public:
   }
 
 
-  void shutdown_and_remove();
+  // Just remove everything after shutdown
+  void clear();
+
   bool shutdown();
   bool shutdown(uint32_t number_of_host);
 
diff --git a/libtest/stats.h b/libtest/stats.h
deleted file mode 100644 (file)
index 592e9c8..0000000
+++ /dev/null
@@ -1,61 +0,0 @@
-/*  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
- *
- *  Data Differential YATL (i.e. libtest)  library
- *
- *  Copyright (C) 2012 Data Differential, http://datadifferential.com/
- *
- *  Redistribution and use in source and binary forms, with or without
- *  modification, are permitted provided that the following conditions are
- *  met:
- *
- *      * Redistributions of source code must retain the above copyright
- *  notice, this list of conditions and the following disclaimer.
- *
- *      * Redistributions in binary form must reproduce the above
- *  copyright notice, this list of conditions and the following disclaimer
- *  in the documentation and/or other materials provided with the
- *  distribution.
- *
- *      * The names of its contributors may not be used to endorse or
- *  promote products derived from this software without specific prior
- *  written permission.
- *
- *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
-
-#pragma once
-
-struct Stats {
-  int32_t collection_success;
-  int32_t collection_skipped;
-  int32_t collection_failed;
-  int32_t collection_total;
-
-  uint32_t success;
-  uint32_t skipped;
-  uint32_t failed;
-  uint32_t total;
-
-  Stats() :
-    collection_success(0),
-    collection_skipped(0),
-    collection_failed(0),
-    collection_total(0),
-    success(0),
-    skipped(0),
-    failed(0),
-    total(0)
-  { }
-};
-
diff --git a/libtest/stream.cc b/libtest/stream.cc
new file mode 100644 (file)
index 0000000..a9d769f
--- /dev/null
@@ -0,0 +1,64 @@
+/*  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
+ *
+ *  Data Differential YATL (i.e. libtest)  library
+ *
+ *  Copyright (C) 2012 Data Differential, http://datadifferential.com/
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are
+ *  met:
+ *
+ *      * Redistributions of source code must retain the above copyright
+ *  notice, this list of conditions and the following disclaimer.
+ *
+ *      * Redistributions in binary form must reproduce the above
+ *  copyright notice, this list of conditions and the following disclaimer
+ *  in the documentation and/or other materials provided with the
+ *  distribution.
+ *
+ *      * The names of its contributors may not be used to endorse or
+ *  promote products derived from this software without specific prior
+ *  written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include <config.h>
+#include <libtest/stream.h>
+
+namespace libtest {
+namespace stream {
+
+namespace detail {
+
+} // namespace detail
+
+make_cerr::make_cerr(const char* filename, int line_number, const char* func) :
+  log(std::cerr, filename, line_number, func)
+{ }
+
+cerr::cerr(const char* filename, int line_number, const char* func) :
+  log(std::cout, filename, line_number, func)
+  { }
+
+clog::clog(const char* filename, int line_number, const char* func) :
+  log(std::clog, filename, line_number, func)
+  { }
+
+cout::cout(const char* filename, int line_number, const char* func) :
+  log(std::cout, filename, line_number, func)
+  { }
+
+} // namespace stream
+} // namespace libtest
index 1555d98dc776b653e3be7830155c6171ec0f561d..9917b94df253ed0ae103e834bf0e0ae26e7f3040 100644 (file)
@@ -48,58 +48,66 @@ namespace stream {
 namespace detail {
 
 template<class Ch, class Tr, class A>
-  class cerr {
+  class channel {
   private:
 
   public:
     typedef std::basic_ostringstream<Ch, Tr, A> stream_buffer;
 
   public:
-    void operator()(const stream_buffer &s)
+    void operator()(const stream_buffer& s, std::ostream& _out,
+                    const char* filename, int line_number, const char* func)
     {
-      std::cerr << s.str() << std::endl;
-    }
-  };
-
-template<class Ch, class Tr, class A>
-  class make_cerr {
-  private:
-
-  public:
-    typedef std::basic_ostringstream<Ch, Tr, A> stream_buffer;
-
-  public:
-    void operator()(const stream_buffer &s)
-    {
-      std::cerr << std::endl << s.str() << std::endl;
-    }
-  };
-
-template<class Ch, class Tr, class A>
-  class cout {
-  private:
-
-  public:
-    typedef std::basic_ostringstream<Ch, Tr, A> stream_buffer;
-
-  public:
-    void operator()(const stream_buffer &s)
-    {
-      std::cout << s.str() << std::endl;
+      if (filename)
+      {
+        _out
+          << filename 
+          << ":" 
+          << line_number 
+          << ": in " 
+          << func << "() "
+          << s.str()
+          << std::endl;
+      }
+      else
+      {
+        _out
+          << s.str()
+          << std::endl;
+      }
     }
   };
 
 template<class Ch, class Tr, class A>
-  class clog {
+  class channelln {
   private:
 
   public:
     typedef std::basic_ostringstream<Ch, Tr, A> stream_buffer;
 
   public:
-    void operator()(const stream_buffer &s)
+    void operator()(const stream_buffer& s, std::ostream& _out,
+                    const char* filename, int line_number, const char* func)
     {
-      std::cerr<< s.str() << std::endl;
+      if (filename)
+      {
+        _out
+          << std::endl
+          << filename 
+          << ":" 
+          << line_number 
+          << ": in " 
+          << func << "() "
+          << s.str()
+          << std::endl;
+      }
+      else
+      {
+        _out
+          << std::endl
+          << s.str()
+          << std::endl;
+      }
     }
   };
 
@@ -107,37 +115,30 @@ template<template <class Ch, class Tr, class A> class OutputPolicy, class Ch = c
   class log {
   private:
     typedef OutputPolicy<Ch, Tr, A> output_policy;
+
+  private:
+    std::ostream& _out;
     const char *_filename;
     int _line_number;
     const char *_func;
 
   public:
-    log() :
-      _filename(NULL),
-      _line_number(0)
+    log(std::ostream& out_arg, const char* filename, int line_number, const char* func) :
+      _out(out_arg),
+      _filename(filename),
+      _line_number(line_number),
+      _func(func)
     { }
 
-    void set_filename(const char *filename, int line_number, const char *func)
-    {
-      _filename= filename;
-      _line_number= line_number;
-      _func= func;
-    }
-
     ~log()
     {
-      output_policy()(arg);
+      output_policy()(arg, _out, _filename, _line_number, _func);
     }
 
   public:
     template<class T>
       log &operator<<(const T &x)
       {
-        if (_filename)
-        {
-          arg << _filename << ":" << _line_number << ": in " << _func << "() ";
-          _filename= NULL;
-        }
         arg << x;
         return *this;
       }
@@ -145,34 +146,26 @@ template<template <class Ch, class Tr, class A> class OutputPolicy, class Ch = c
   private:
     typename output_policy::stream_buffer arg;
   };
-}
+} // namespace detail
 
-class make_cerr : public detail::log<detail::make_cerr> {
+class make_cerr : public detail::log<detail::channelln> {
 public:
-  make_cerr(const char *filename, int line_number, const char *func)
-  {
-    set_filename(filename, line_number, func);
-  }
+  make_cerr(const char* filename, int line_number, const char* func);
 };
 
-class cerr : public detail::log<detail::cerr> {
+class cerr : public detail::log<detail::channel> {
 public:
-  cerr(const char *filename, int line_number, const char *func)
-  {
-    set_filename(filename, line_number, func);
-  }
+  cerr(const char* filename, int line_number, const char* func);
 };
 
-class clog : public detail::log<detail::clog> {
+class clog : public detail::log<detail::channel> {
 public:
-  clog(const char *, int, const char*)
-  { }
+  clog(const char* filename, int line_number, const char* func);
 };
 
-class cout : public detail::log<detail::cout> {
+class cout : public detail::log<detail::channel> {
 public:
-  cout(const char *, int, const char *)
-  { }
+  cout(const char* filename, int line_number, const char* func);
 };
 
 
index c269e54185fe892d4c318b52d555a8198dca8d20..53db247a7ebc8d8c46d2a64ee18a9dc1afe3c701 100644 (file)
@@ -51,6 +51,7 @@
 #include <libtest/has.hpp>
 #include <libtest/error.h>
 #include <libtest/strerror.h>
+#include <libtest/timer.hpp>
 #include <libtest/stream.h>
 #include <libtest/comparison.hpp>
 #include <libtest/server.h>
 #include <libtest/port.h>
 #include <libtest/is_local.hpp>
 #include <libtest/socket.hpp>
-#include <libtest/stats.h>
 #include <libtest/collection.h>
 #include <libtest/framework.h>
 #include <libtest/get.h>
-#include <libtest/stream.h>
 #include <libtest/cmdline.h>
 #include <libtest/string.hpp>
 #include <libtest/binaries.h>
diff --git a/libtest/timer.cc b/libtest/timer.cc
new file mode 100644 (file)
index 0000000..0a8d69b
--- /dev/null
@@ -0,0 +1,55 @@
+/*  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
+ *
+ *  Data Differential YATL (i.e. libtest)  library
+ *
+ *  Copyright (C) 2012 Data Differential, http://datadifferential.com/
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are
+ *  met:
+ *
+ *      * Redistributions of source code must retain the above copyright
+ *  notice, this list of conditions and the following disclaimer.
+ *
+ *      * Redistributions in binary form must reproduce the above
+ *  copyright notice, this list of conditions and the following disclaimer
+ *  in the documentation and/or other materials provided with the
+ *  distribution.
+ *
+ *      * The names of its contributors may not be used to endorse or
+ *  promote products derived from this software without specific prior
+ *  written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include <config.h>
+#include <libtest/timer.hpp>
+#include <ctime>
+
+namespace libtest {
+
+std::ostream& operator<<(std::ostream& output, const libtest::Timer& arg)
+{
+  struct timespec temp;
+  arg.difference(temp);
+
+  output << temp.tv_sec;
+  output << ":";
+  output << temp.tv_nsec;
+
+  return output;
+}
+
+} // namespace libtest
diff --git a/libtest/timer.hpp b/libtest/timer.hpp
new file mode 100644 (file)
index 0000000..37da32f
--- /dev/null
@@ -0,0 +1,113 @@
+/*  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
+ *
+ *  Data Differential YATL (i.e. libtest)  library
+ *
+ *  Copyright (C) 2012 Data Differential, http://datadifferential.com/
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions are
+ *  met:
+ *
+ *      * Redistributions of source code must retain the above copyright
+ *  notice, this list of conditions and the following disclaimer.
+ *
+ *      * Redistributions in binary form must reproduce the above
+ *  copyright notice, this list of conditions and the following disclaimer
+ *  in the documentation and/or other materials provided with the
+ *  distribution.
+ *
+ *      * The names of its contributors may not be used to endorse or
+ *  promote products derived from this software without specific prior
+ *  written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#pragma once
+
+#include <ctime>
+#include <ostream>
+
+#ifdef __MACH__
+#  include <mach/clock.h>
+#  include <mach/mach.h>
+#else
+#  include <sys/time.h>
+#endif
+
+
+namespace libtest {
+
+class Timer {
+public:
+
+  Timer()
+  {
+    _begin.tv_sec= 0;
+    _begin.tv_nsec= 0;
+    _end.tv_sec= 0;
+    _end.tv_nsec= 0;
+  }
+
+  void reset()
+  {
+    _end.tv_sec= 0;
+    _end.tv_nsec= 0;
+    _time(_begin);
+  }
+
+  void sample()
+  {
+    _time(_end);
+  }
+
+  void difference(struct timespec& arg) const
+  {
+    if ((_end.tv_nsec -_begin.tv_nsec) < 0)
+    {
+      arg.tv_sec= _end.tv_sec -_begin.tv_sec-1;
+      arg.tv_nsec= 1000000000 +_end.tv_nsec -_begin.tv_nsec;
+
+    }
+    else
+    {
+      arg.tv_sec= _end.tv_sec -_begin.tv_sec;
+      arg.tv_nsec= _end.tv_nsec -_begin.tv_nsec;
+    }
+  }
+
+private:
+  void _time(struct timespec& ts)
+  {
+#ifdef __MACH__ // OSX lacks clock_gettime()
+    clock_serv_t _clock_serv;
+    mach_timespec_t _mach_timespec;
+    host_get_clock_service(mach_host_self(), CALENDAR_CLOCK, &_clock_serv);
+    clock_get_time(_clock_serv, &_mach_timespec);
+    mach_port_deallocate(mach_task_self(), _clock_serv);
+    ts.tv_sec= _mach_timespec.tv_sec;
+    ts.tv_nsec= _mach_timespec.tv_nsec;
+#else
+    clock_gettime(CLOCK_REALTIME, &ts);
+#endif
+  }
+
+private:
+  struct timespec _begin;
+  struct timespec _end;
+};
+
+std::ostream& operator<<(std::ostream& output, const libtest::Timer& arg);
+
+} // namespace libtest
index ac087f4f2e6f47c28e24c426b4231ff02a63cf24..788d7e67bf88bd7ac8eb9d09d89cbc1aa776a8c7 100644 (file)
@@ -70,7 +70,7 @@ static test_return_t server_startup_multiple_TEST(void *obj)
 static test_return_t shutdown_and_remove_TEST(void *obj)
 {
   server_startup_st *servers= (server_startup_st*)obj;
-  servers->shutdown_and_remove();
+  servers->clear();
 
   return TEST_SUCCESS;
 }
@@ -106,7 +106,7 @@ static test_return_t validate_sanity_INIT(void *object)
 static test_return_t collection_FINAL(void *object)
 {
   server_startup_st *servers= (server_startup_st*)object;
-  servers->shutdown_and_remove();
+  servers->clear();
 
   return TEST_SUCCESS;
 }
index cfee6cb7783da3142a950ff957a403841368ea0f..d31518ee137d8f2151bda7ece605451ea4a43c5c 100644 (file)
@@ -152,7 +152,7 @@ static test_return_t MEMCACHED_SERVER_TEMPORARILY_DISABLED_to_success_TEST(memca
 
   memcached_return_t ret;
   do {
-    sleep(3);
+    libtest::dream(3, 0);
     ret= memcached_set(memc, test_literal_param("foo"), NULL, 0, time_t(0), uint32_t(0));
   } while (ret == MEMCACHED_SERVER_TEMPORARILY_DISABLED);
 
@@ -175,7 +175,7 @@ static test_return_t MEMCACHED_SERVER_MARKED_DEAD_TEST(memcached_st *memc)
   test_compare(MEMCACHED_SERVER_TEMPORARILY_DISABLED, ret);
 
   do {
-    sleep(3);
+    libtest::dream(3, 0);
     ret= memcached_set(memc, test_literal_param("foo"), NULL, 0, time_t(0), uint32_t(0));
   } while (ret == MEMCACHED_SERVER_TEMPORARILY_DISABLED or ret == MEMCACHED_SUCCESS);
 
@@ -207,7 +207,7 @@ collection_st collection[] ={
   { 0, 0, 0, 0 }
 };
 
-#include "libmemcached_world.h"
+#include "tests/libmemcached_world.h"
 
 void get_world(Framework *world)
 {
index 165b79b8e78d9d813a256b988d07a15f9959d021..938014222884057540dacd87b822229bdabf9741 100644 (file)
@@ -56,12 +56,23 @@ tests_failure_LDADD= $(tests_failure_DEPENDENCIES)
 check_PROGRAMS+= tests/failure
 noinst_PROGRAMS+= tests/failure
 
-tests_testhashkit_SOURCES = tests/hashkit_functions.cc
-tests_testhashkit_DEPENDENCIES = libtest/libtest.la libhashkit/libhashkit.la $(TESTS_LDADDS)
-tests_testhashkit_LDADD = $(tests_testhashkit_DEPENDENCIES)
+test-failure: tests/failure
+       @tests/failure
+
+gdb-failure: tests/failure
+       @$(DEBUG_COMMAND) tests/failure
+
+
+tests_testhashkit_SOURCES= tests/hashkit_functions.cc
+tests_testhashkit_DEPENDENCIES= libtest/libtest.la libhashkit/libhashkit.la $(TESTS_LDADDS)
+tests_testhashkit_LDADD= $(tests_testhashkit_DEPENDENCIES)
 check_PROGRAMS+= tests/testhashkit
 noinst_PROGRAMS+= tests/testhashkit
 
+test-hash: tests/testhashkit
+       @tests/testhashkit
+
+
 tests_hash_plus_SOURCES= tests/hash_plus.cc
 tests_hash_plus_CXXFLAGS= $(AM_CXXFLAGS) $(NO_EFF_CXX)
 tests_hash_plus_DEPENDENCIES= $(tests_testhashkit_DEPENDENCIES)
@@ -88,9 +99,6 @@ test-atom: tests/atomsmasher
 test-plus: tests/testplus
        @tests/testplus
 
-test-hash: tests/testhashkit
-       @tests/testhashkit
-
 test-hashplus: tests/hash_plus
        @tests/hash_plus
 
@@ -124,9 +132,6 @@ gdb-hashplus: tests/hash_plus
 gdb-cycle: tests/cycle
        @$(DEBUG_COMMAND) tests/cycle
 
-gdb-failure: tests/failure
-       @$(DEBUG_COMMAND) tests/failure
-
 valgrind-cycle: tests/cycle
        $(VALGRIND_COMMAND) tests/cycle
 
index 577f09ba95835b8710c7604a1b85232ae33729aa..fcce6e2f38bd099108801e383ccbbe574fd24ed6 100644 (file)
@@ -113,7 +113,9 @@ private:
       test_null(container->parent());
       container->parent(memcached(container->construct.option_string().c_str(), container->construct.option_string().size()));
       test_true(container->parent());
+#if 0
       test_compare(MEMCACHED_SUCCESS, memcached_version(container->parent()));
+#endif
 
       if (container->construct.sasl())
       {