Commit 07e8277f authored by Steven Murray's avatar Steven Murray
Browse files

Added parseCommandLine to the single thread daemon class:

    castor::server::Daemon
parent c00c875e
......@@ -25,6 +25,7 @@
#include "castor/server/Daemon.hpp"
#include "castor/server/ThreadNotification.hpp"
#include "castor/System.hpp"
#include "h/Cgetopt.h"
#include <signal.h>
#include <stdio.h>
......@@ -32,8 +33,9 @@
//------------------------------------------------------------------------------
// constructor
//------------------------------------------------------------------------------
castor::server::Daemon::Daemon(log::Logger &logger):
castor::server::Daemon::Daemon(log::Logger &logger) throw():
m_foreground(false),
m_commandLineHasBeenParsed(false),
m_runAsStagerSuperuser(false),
m_logger(logger) {
}
......@@ -44,6 +46,73 @@ castor::server::Daemon::Daemon(log::Logger &logger):
castor::server::Daemon::~Daemon() throw() {
}
//------------------------------------------------------------------------------
// parseCommandLine
//------------------------------------------------------------------------------
void castor::server::Daemon::parseCommandLine(int argc,
char *argv[]) throw(castor::exception::Exception) {
Coptions_t longopts[4];
longopts[0].name = "foreground";
longopts[0].has_arg = NO_ARGUMENT;
longopts[0].flag = NULL;
longopts[0].val = 'f';
longopts[1].name = "config";
longopts[1].has_arg = REQUIRED_ARGUMENT;
longopts[1].flag = NULL;
longopts[1].val = 'c';
longopts[2].name = "help";
longopts[2].has_arg = NO_ARGUMENT;
longopts[2].flag = NULL;
longopts[2].val = 'h';
longopts[3].name = 0;
Coptind = 1;
Copterr = 0;
Coptreset = 1;
char c;
while ((c = Cgetopt_long(argc, argv, "fc:h", longopts, NULL)) != -1) {
switch (c) {
case 'f':
m_foreground = true;
break;
case 'c':
setenv("PATH_CONFIG", Coptarg, 1);
std::cout << "Using configuration file " << Coptarg << std::endl;
break;
case 'h':
help(argv[0]);
exit(0);
break;
default:
break;
}
}
m_commandLineHasBeenParsed = true;
}
//------------------------------------------------------------------------------
// help
//------------------------------------------------------------------------------
void castor::server::Daemon::help(const std::string &programName)
throw() {
std::cout << "Usage: " << programName << " [options]\n"
"\n"
"where options can be:\n"
"\n"
"\t--foreground or -f \tRemain in the Foreground\n"
"\t--config <config-file> or -c \tConfiguration file\n"
"\t--metrics or -m \tEnable metrics collection\n"
"\t--help or -h \tPrint this help and exit\n"
"\n"
"Comments to: Castor.Support@cern.ch\n";
}
//------------------------------------------------------------------------------
// getServerName
//------------------------------------------------------------------------------
......@@ -58,6 +127,22 @@ void castor::server::Daemon::runAsStagerSuperuser() throw() {
m_runAsStagerSuperuser = true;
}
//------------------------------------------------------------------------------
// getForeground
//------------------------------------------------------------------------------
bool castor::server::Daemon::getForeground() const
throw(castor::exception::CommandLineNotParsed) {
if(!m_commandLineHasBeenParsed) {
castor::exception::CommandLineNotParsed ex;
ex.getMessage() <<
"Failed to determine whether or not the daemon should run in the"
" foreground because the command-line has not yet been parsed";
throw ex;
}
return m_foreground;
}
//-----------------------------------------------------------------------------
// dlfInit
//-----------------------------------------------------------------------------
......
......@@ -24,6 +24,8 @@
#define CASTOR_SERVER_DAEMON_HPP 1
#include "castor/dlf/Message.hpp"
#include "castor/exception/CommandLineNotParsed.hpp"
#include "castor/exception/Exception.hpp"
#include "castor/log/Logger.hpp"
namespace castor {
......@@ -43,13 +45,27 @@ public:
*
* @param logger Object representing the API of the CASTOR logging system.
*/
Daemon(log::Logger &logger);
Daemon(log::Logger &logger) throw();
/**
* Destructor.
*/
virtual ~Daemon() throw();
/**
* Parses a command line to set the server options.
*
* @param argc The size of the command-line vector.
* @param argv The command-line vector.
*/
virtual void parseCommandLine(int argc, char *argv[])
throw(castor::exception::Exception);
/**
* Prints out the online help
*/
virtual void help(const std::string &programName) throw();
/**
* Returns this server's name as used by the CASTOR logging system.
*/
......@@ -63,6 +79,11 @@ public:
*/
void runAsStagerSuperuser() throw();
/**
* Returns true if the daemon is configured to run in the foreground.
*/
bool getForeground() const throw(castor::exception::CommandLineNotParsed);
protected:
/**
......@@ -200,6 +221,11 @@ protected:
*/
bool m_foreground;
/**
* True if the command-line has been parsed.
*/
bool m_commandLineHasBeenParsed;
private:
/**
......
/******************************************************************************
* castor/server/DaemonTest.cpp
*
* This file is part of the Castor project.
* See http://castor.web.cern.ch/castor
*
* Copyright (C) 2003 CERN
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
*
*
* @author Castor Dev team, castor-dev@cern.ch
*****************************************************************************/
#include "castor/log/DummyLogger.hpp"
#include "castor/server/Daemon.hpp"
#include <gtest/gtest.h>
#include <stdio.h>
#include <string.h>
namespace UnitTests {
class castor_server_DaemonTest : public ::testing::Test {
protected:
const std::string m_programName;
int m_argc;
char **m_argv;
castor_server_DaemonTest() :
m_programName("testdaemon"),
m_argc(0),
m_argv(NULL) {
}
virtual void SetUp() {
m_argc = 0;
m_argv = NULL;
}
virtual void TearDown() {
for(int i = 0; i < m_argc; i++) {
free(m_argv[i]);
}
delete[] m_argv;
}
};
TEST_F(castor_server_DaemonTest, getForegroundBeforeParseCommandLine) {
castor::log::DummyLogger log(m_programName);
castor::server::Daemon daemon(log);
ASSERT_THROW(daemon.getForeground(), castor::exception::CommandLineNotParsed);
}
TEST_F(castor_server_DaemonTest, parseEmptyCmdLine) {
m_argv = new char *[2];
m_argv[0] = strdup(m_programName.c_str());
m_argv[1] = NULL;
m_argc = 1;
castor::log::DummyLogger log(m_programName);
castor::server::Daemon daemon(log);
ASSERT_NO_THROW(daemon.parseCommandLine(m_argc, m_argv));
ASSERT_EQ(false, daemon.getForeground());
}
TEST_F(castor_server_DaemonTest, parseFOnCmdLine) {
m_argv = new char *[3];
m_argv[0] = strdup(m_programName.c_str());
m_argv[1] = strdup("-f");
m_argv[2] = NULL;
m_argc = 2;
castor::log::DummyLogger log(m_programName);
castor::server::Daemon daemon(log);
ASSERT_NO_THROW(daemon.parseCommandLine(m_argc, m_argv));
ASSERT_EQ(true, daemon.getForeground());
}
} // namespace UnitTests
......@@ -46,7 +46,7 @@ castor::server::MultiThreadedDaemon::~MultiThreadedDaemon() throw() {
// parseCommandLine
//------------------------------------------------------------------------------
void castor::server::MultiThreadedDaemon::parseCommandLine(int argc,
char *argv[]) {
char *argv[]) throw(castor::exception::Exception) {
Coptions_t* longopts = new Coptions_t[m_threadPools.size() + 5];
char tparam[] = "Xthreads";
......@@ -115,12 +115,15 @@ void castor::server::MultiThreadedDaemon::parseCommandLine(int argc,
free((char*)longopts[j].name);
};
delete[] longopts;
m_commandLineHasBeenParsed = true;
}
//------------------------------------------------------------------------------
// help
//------------------------------------------------------------------------------
void castor::server::MultiThreadedDaemon::help(const std::string &programName) {
void castor::server::MultiThreadedDaemon::help(const std::string &programName)
throw() {
std::cout << "Usage: " << programName << " [options]\n"
"\n"
"where options can be:\n"
......
......@@ -98,7 +98,8 @@ public:
* @param argc The size of the command-line vector.
* @param argv The command-line vector.
*/
virtual void parseCommandLine(int argc, char *argv[]);
virtual void parseCommandLine(int argc, char *argv[])
throw(castor::exception::Exception);
protected:
......@@ -119,7 +120,7 @@ private:
/**
* Prints out the online help
*/
void help(const std::string &programName);
void help(const std::string &programName) throw();
/**
* Sets up the signal handling for this multi-threaded daemon.
......
......@@ -27,6 +27,7 @@ cmake_minimum_required (VERSION 2.6)
add_executable(castorUnitTests
castorUnitTests.cpp
../castor/exception/ExceptionTest.cpp
../castor/server/DaemonTest.cpp
../castor/tape/tapeserver/SCSI/DeviceTest.cpp
../castor/tape/tapeserver/SCSI/StructuresTest.cpp
../castor/tape/tapeserver/utils/RegexTest.cpp
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment