Browse Source

1) Have server delay becoming a daemon until we know it really has started.
2) Import the new framework for testing servers.

Brian Aker 13 years ago
parent
commit
eed9cd1e76
10 changed files with 294 additions and 34 deletions
  1. 37 4
      bin/gearadmin.cc
  2. 5 5
      bin/gearman.cc
  3. 25 12
      gearmand/gearmand.cc
  4. 4 0
      libgearman-server/server.c
  5. 3 2
      libtest/callbacks.h
  6. 5 4
      libtest/common.h
  7. 1 0
      libtest/error.h
  8. 74 0
      libtest/failed.cc
  9. 52 0
      libtest/failed.h
  10. 88 7
      libtest/framework.cc

+ 37 - 4
bin/gearadmin.cc

@@ -93,6 +93,35 @@ using namespace gearman_util;
 
 #define STRING_WITH_LEN(X) (X), (static_cast<size_t>((sizeof(X) - 1)))
 
+class Finish : public Instance::Finish
+{
+public:
+  bool call(bool success, const std::string &response)
+  {
+    if (success)
+    {
+      if (response.empty())
+      {
+        std::cout << "OK" << std::endl;
+      }
+      else
+      {
+        std::cout << response;
+      }
+    }
+    else if (not response.empty())
+    {
+      std::cerr << "Error: " << response;
+    }
+    else
+    {
+      std::cerr << "Error" << std::endl;
+    }
+
+    return true;
+  }
+};
+
 
 int main(int args, char *argv[])
 {
@@ -108,6 +137,7 @@ int main(int args, char *argv[])
     ("server-verbose", "Fetch the verbose setting for the server.")
     ("create-function",  boost::program_options::value<std::string>(), "Create the function from the server.") 
     ("drop-function",  boost::program_options::value<std::string>(), "Drop the function from the server.")
+    ("getpid", "Get Process ID for the server.")
     ("status", "Status for the server.")
     ("workers", "Workers for the server.")
     ("shutdown", "Shutdown server.")
@@ -126,10 +156,8 @@ int main(int args, char *argv[])
     return EXIT_FAILURE;
   }
 
-  Instance instance;
-
-  instance.set_host(host);
-  instance.set_port(port);
+  Instance instance(host, port);
+  instance.set_finish(new Finish);
 
   if (vm.count("help"))
   {
@@ -178,6 +206,11 @@ int main(int args, char *argv[])
     instance.push(new Operation(execute.c_str(), execute.size()));
   }
 
+  if (vm.count("getpid"))
+  {
+    instance.push(new Operation(STRING_WITH_LEN("getpid\r\n"), true));
+  }
+
   instance.run();
 
   return EXIT_SUCCESS;

+ 5 - 5
bin/gearman.cc

@@ -136,7 +136,7 @@ int main(int argc, char *argv[])
     switch (fork())
     {
     case -1:
-      fprintf(stderr, "gearmand: fork:%d\n", errno);
+      error::perror("fork");
       return EXIT_FAILURE;
 
     case 0:
@@ -148,7 +148,7 @@ int main(int argc, char *argv[])
 
     if (setsid() == -1)
     {
-      fprintf(stderr, "gearmand: setsid:%d\n", errno);
+      error::perror("setsid");
       return EXIT_FAILURE;
     }
 
@@ -164,19 +164,19 @@ int main(int argc, char *argv[])
     {
       if (dup2(fd, STDIN_FILENO) == -1)
       {
-        fprintf(stderr, "gearmand: dup2:%d\n", errno);
+        error::perror("dup2");
         return EXIT_FAILURE;
       }
 
       if (dup2(fd, STDOUT_FILENO) == -1)
       {
-        fprintf(stderr, "gearmand: dup2:%d\n", errno);
+        error::perror("dup2");
         return EXIT_FAILURE;
       }
 
       if (dup2(fd, STDERR_FILENO) == -1)
       {
-        fprintf(stderr, "gearmand: dup2:%d\n", errno);
+        error::perror("dup2");
         return EXIT_FAILURE;
       }
 

+ 25 - 12
gearmand/gearmand.cc

@@ -92,6 +92,12 @@ struct gearmand_log_info_st
     reopen(0)
   {
   }
+
+  ~gearmand_log_info_st()
+  {
+    if (fd != -1)
+      close(fd);
+  }
 };
 
 static bool _set_fdlimit(rlim_t fds);
@@ -230,18 +236,15 @@ int main(int argc, char *argv[])
     return EXIT_FAILURE;
   }
 
-  if (_set_signals())
-  {
-    return EXIT_FAILURE;
-  }
-
   if (opt_daemon)
   {
     gearmand::daemonize(false, true);
   }
 
-  if (opt_daemon)
-    gearmand::daemon_is_ready(verbose_count == 0);
+  if (_set_signals())
+  {
+    return EXIT_FAILURE;
+  }
 
   gearmand_verbose_t verbose= verbose_count > static_cast<int>(GEARMAND_VERBOSE_CRAZY) ? GEARMAND_VERBOSE_CRAZY : static_cast<gearmand_verbose_t>(verbose_count);
 
@@ -273,6 +276,7 @@ int main(int argc, char *argv[])
     gearmand_error_t rc;
     if ((rc= gearmand::queue::initialize(_gearmand, queue_type.c_str())) != GEARMAN_SUCCESS)
     {
+      error::message("Error while initializing the queue", protocol.c_str());
       gearmand_free(_gearmand);
 
       return EXIT_FAILURE;
@@ -284,23 +288,32 @@ int main(int argc, char *argv[])
     if (http.start(_gearmand) != GEARMAN_SUCCESS)
     {
       error::message("Error while enabling protocol module", protocol.c_str());
+      gearmand_free(_gearmand);
+
       return EXIT_FAILURE;
     }
   }
   else if (not protocol.empty())
   {
     error::message("Unknown protocol module", protocol.c_str());
+    gearmand_free(_gearmand);
+
     return EXIT_FAILURE;
   }
 
-  gearmand_error_t ret;
-  ret= gearmand_run(_gearmand);
+  if (opt_daemon)
+  {
+    bool close_io= verbose_count == 0 or log_file.size();
+    if (not gearmand::daemon_is_ready(close_io))
+    {
+      return EXIT_FAILURE;
+    }
+  }
+
+  gearmand_error_t ret= gearmand_run(_gearmand);
 
   gearmand_free(_gearmand);
 
-  if (log_info.fd != -1)
-    (void) close(log_info.fd);
-
   return (ret == GEARMAN_SUCCESS || ret == GEARMAN_SHUTDOWN) ? 0 : 1;
 }
 

+ 4 - 0
libgearman-server/server.c

@@ -1089,6 +1089,10 @@ static gearmand_error_t _server_run_text(gearman_server_con_st *server_con,
       snprintf(data, GEARMAN_TEXT_RESPONSE_SIZE, TEXT_SUCCESS);
     }
   }
+  else if (strcasecmp("getpid", (char *)(packet->arg[0])) == 0)
+  {
+    snprintf(data, GEARMAN_TEXT_RESPONSE_SIZE, "OK %d\n", (int)getpid());
+  }
   else if (!strcasecmp("shutdown", (char *)(packet->arg[0])))
   {
     if (packet->argc == 1)

+ 3 - 2
libtest/callbacks.h

@@ -10,10 +10,11 @@
 extern "C" {
 #endif
 
-typedef void* (test_callback_create_fn)(enum test_return_t*);
+typedef void* (test_callback_create_fn)(libtest::server_startup_st&, test_return_t&);
+typedef bool test_callback_destroy_fn(void *);
 typedef enum test_return_t (test_callback_fn)(void *);
 typedef enum test_return_t (test_callback_runner_fn)(test_callback_fn*, void *);
-typedef enum test_return_t (test_callback_error_fn)(const enum test_return_t, void *);
+typedef enum test_return_t (test_callback_error_fn)(const test_return_t, void *);
 
 #ifdef	__cplusplus
 }

+ 5 - 4
libtest/common.h

@@ -43,12 +43,13 @@
 
 #include <config.h>
 
-#if defined(NDEBUG)
-# undef NDEBUG
-#endif
-
 #include <inttypes.h>
 #include <cstdlib>
 #include <sys/types.h>
 
+#include <cerrno>
+#include <cassert>
+
 #include <libtest/test.hpp>
+
+using namespace libtest;

+ 1 - 0
libtest/error.h

@@ -16,3 +16,4 @@ enum test_return_t {
 
 
 #define test_failed(__test_return_t) ((__test_return_t) != TEST_SUCCESS)
+#define test_success(__test_return_t) ((__test_return_t) == TEST_SUCCESS)

+ 74 - 0
libtest/failed.cc

@@ -0,0 +1,74 @@
+/*  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
+ * 
+ *  uTest Framework
+ *
+ *  Copyright (C) 2011 Data Differential, http://datadifferential.com/
+ *  All rights reserved.
+ *
+ *  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 <libtest/common.h>
+
+#include <libtest/failed.h>
+
+#include <iostream>
+#include <string>
+#include <vector>
+
+struct failed_test_names_st
+{
+  failed_test_names_st(const char *collection_arg, const char *test_arg) :
+    collection(collection_arg),
+    test(test_arg)
+  {
+  }
+
+  std::string collection;
+  std::string test;
+};
+
+typedef std::vector<failed_test_names_st> Failures;
+
+static Failures failures;
+
+void push_failed_test(const char *collection, const char *test)
+{
+  failures.push_back(failed_test_names_st(collection, test));
+}
+
+void print_failed_test(void)
+{
+  for (Failures::iterator iter= failures.begin(); iter != failures.end(); iter++)
+  {
+    Error << "\t" << (*iter).collection << " " << (*iter).test;
+  }
+}
+

+ 52 - 0
libtest/failed.h

@@ -0,0 +1,52 @@
+/*  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
+ * 
+ *  uTest Framework
+ *
+ *  Copyright (C) 2011 Data Differential, http://datadifferential.com/
+ *  All rights reserved.
+ *
+ *  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
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+LIBTEST_INTERNAL_API
+  void push_failed_test(const char *collection, const char *test);
+
+LIBTEST_INTERNAL_API
+  void print_failed_test(void);
+
+#ifdef __cplusplus
+}
+#endif

+ 88 - 7
libtest/framework.cc

@@ -1,23 +1,93 @@
-/* uTest Copyright (C) 2011 Data Differential, http://datadifferential.com/
+/*  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
+ * 
+ *  uTest, libtest
+ *
+ *  Copyright (C) 2011 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.
  *
- * Use and distribution licensed under the BSD license.  See
- * the COPYING file in the parent directory for full text.
  */
 
-#include <libtest/common.h>
 
+#include <libtest/common.h>
 #include <iostream>
 
-test_return_t Framework::destroy(void* arg)
+using namespace libtest;
+
+static test_return_t _runner_default(test_callback_fn func, void *p)
 {
-  if (_destroy)
+  if (func)
   {
-    return _destroy(arg);
+    return func(p);
   }
 
   return TEST_SUCCESS;
 }
 
+static Runner defualt_runners= {
+  _runner_default,
+  _runner_default,
+  _runner_default
+};
+
+static test_return_t _default_callback(void *p)
+{
+  (void)p;
+
+  return TEST_SUCCESS;
+}
+
+Framework::Framework() :
+  collections(NULL),
+  _create(NULL),
+  _destroy(NULL),
+  collection_startup(_default_callback),
+  collection_shutdown(_default_callback),
+  _on_error(NULL),
+  runner(&defualt_runners),
+  _creators_ptr(NULL)
+{
+}
+
+Framework::~Framework()
+{
+  server_shutdown(_servers);
+
+  if (_destroy)
+  {
+    if (_destroy(_creators_ptr))
+    {
+      Error << "Failure in _destroy(), some resources may not have been cleaned up.";
+    }
+  }
+}
+
 test_return_t Framework::Item::flush(void* arg, test_st* run)
 {
   if (run->requires_flush and _flush)
@@ -57,3 +127,14 @@ test_return_t Framework::Item::startup(void* arg)
 
   return TEST_SUCCESS;
 }
+
+void* Framework::create(test_return_t& arg)
+{
+  arg= TEST_SUCCESS;
+  if (_create)
+  {
+    return _creators_ptr= _create(_servers, arg);
+  }
+
+  return NULL;
+}

Some files were not shown because too many files changed in this diff