-#SUBDIRS = . tests
-SUBDIRS = .
+SUBDIRS = . tests
AM_CPPFLAGS = -I$(top_srcdir)/src/lib -I$(top_builddir)/src/lib
AM_CPPFLAGS += -I$(top_srcdir)/src/bin -I$(top_builddir)/src/bin
#include <exceptions/exceptions.h>
#include <log/logger_support.h>
#include <log/logger_manager.h>
-//#include <dhcpsrv/cfgmgr.h>
#include <iostream>
using namespace std;
/// @brief Defines the application name, it may be used to locate
/// configuration data and appears in log statements.
-const char* lfc::lfc_app_name_ = "DhcpLFC";
+const char* lfcController::lfc_app_name_ = "DhcpLFC";
/// @brief Defines the executable name.
-const char*lfc::lfc_bin_name_ = "kea-lfc";
+const char* lfcController::lfc_bin_name_ = "kea-lfc";
-lfc::lfc()
- : dhcp_version_(0), verbose_(false), config_file_(""),
- previous_file_(""), copy_file_(""), output_file_("") {
+lfcController::lfcController()
+ : protocol_version_(0), verbose_(false), config_file_(""), previous_file_(""),
+ copy_file_(""), output_file_(""), finish_file_(""), pid_file_("./test_pid") {
std::cerr << "created lfc" << std::endl;
}
-lfc::~lfc() {
+lfcController::~lfcController() {
std::cerr << "destroyed lfc" << std::endl;
}
void
-lfc::launch(int argc, char* argv[], const bool test_mode) {
+lfcController::launch(int argc, char* argv[], const bool test_mode) {
try {
parseArgs(argc, argv);
} catch (const InvalidUsage& ex) {
}
void
-lfc::parseArgs(int argc, char* argv[])
+lfcController::parseArgs(int argc, char* argv[])
{
int ch;
- while ((ch = getopt(argc, argv, "46dvVp:i:o:c:")) != -1) {
+ while ((ch = getopt(argc, argv, "46dvVp:i:o:c:f:")) != -1) {
switch (ch) {
case '4':
// Process DHCPv4 lease files.
- dhcp_version_ = 4;
+ protocol_version_ = 4;
break;
case '6':
// Process DHCPv6 lease files.
- dhcp_version_ = 6;
+ protocol_version_ = 6;
break;
case 'v':
// Print just Kea vesion and exit.
- // std::cout << getVersion(false) << std::endl;
+ std::cout << getVersion(false) << std::endl;
exit(EXIT_SUCCESS);
case 'V':
// Print extended Kea vesion and exit.
- //std::cout << getVersion(true) << std::endl;
+ std::cout << getVersion(true) << std::endl;
exit(EXIT_SUCCESS);
case 'd':
output_file_ = optarg;
break;
+ case 'f':
+ // Output file name.
+ if (optarg == NULL) {
+ isc_throw(InvalidUsage, "Finish file name missing");
+ }
+ finish_file_ = optarg;
+ break;
+
case 'c':
// Previous file name.
if (optarg == NULL) {
isc_throw(InvalidUsage, "Extraneous parameters.");
}
- if (dhcp_version_ == 0) {
+ if (protocol_version_ == 0) {
isc_throw(InvalidUsage, "DHCP version required");
}
isc_throw(InvalidUsage, "Output file not specified");
}
+ if (finish_file_.empty()) {
+ isc_throw(InvalidUsage, "Finish file not specified");
+ }
+
if (config_file_.empty()) {
isc_throw(InvalidUsage, "Config file not specified");
}
// If verbose is set echo the input information
if (verbose_ == true) {
- std::cerr << "Protocol version: " << dhcp_version_ << std::endl
+ std::cerr << "Protocol version: " << protocol_version_ << std::endl
<< "Previous lease file: " << previous_file_ << std::endl
<< "Copy lease file: " << copy_file_ << std::endl
<< "Output lease file: " << output_file_ << std::endl
- << "Config file: " << config_file_ << std::endl;
+ << "Finishn file: " << finish_file_ << std::endl
+ << "Config file: " << config_file_ << std::endl
+ << "PID file: " << pid_file_ << std::endl;
}
}
-void
-lfc::pidCheck()
+bool
+lfcController::pidCheck(const std::string & pid_file)
+{
+ return (false);
+}
+
+bool
+lfcController::pidWrite(const std::string & pid_file)
{
+ return (true);
}
void
-lfc::pidDelete()
+lfcController::pidDelete(const std::string & pid_file)
{
}
void
-lfc::usage(const std::string & text)
+lfcController::usage(const std::string & text)
{
if (text != "") {
std::cerr << "Usage error: " << text << std::endl;
}
std::cerr << "Usage: " << lfc_bin_name_ << std::endl
- << " [-4|-6] -p file -i file -o file -c file" << std::endl
+ << " [-4|-6] -p file -i file -o file -f file -c file" << std::endl
<< " -4 or -6 clean a set of v4 or v6 lease files" << std::endl
<< " -p <file>: previous lease file" << std::endl
<< " -i <file>: copy of lease file" << std::endl
<< " -o <file>: output lease file" << std::endl
+ << " -f <file>: finish file" << std::endl
<< " -c <file>: configuration file" << std::endl
<< " -v: print version number and exit" << std::endl
<< " -V: print extended version inforamtion and exit" << std::endl
<< std::endl;
}
+std::string
+lfcController::getVersion(bool extended) {
+ std::stringstream tmp;
+
+ tmp << VERSION;
+ if (extended) {
+ tmp << std::endl << EXTENDED_VERSION;
+ }
+
+ return (tmp.str());
+}
+
}; // namespace isc::lfc
}; // namespace isc
-
-//std::string
-//isc::dhcp::Daemon::getVersion(bool extended) {
-// std::stringstream tmp;
-//
-// tmp << VERSION;
-// if (extended) {
-// tmp << std::endl << EXTENDED_VERSION;
-//
- // @todo print more details (is it Botan or OpenSSL build,
- // with or without MySQL/Postgres? What compilation options were
- // used? etc)
-// }
-//
-// return (tmp.str());
-//}
//class lfcBase;
//typedef boost::shared_ptr<lfcBase> lfcBasePtr;
-class lfc {
+class lfcController {
public:
/// @brief Defines the application name, it may be used to locate
/// configuration data and appears in log statements.
static const char* lfc_bin_name_;
/// @brief Constructor
- lfc();
+ lfcController();
/// @brief Destructor
- ~lfc();
+ ~lfcController();
/// @brief Acts as the primary entry point to start execution
/// of the process. Provides the control logic:
/// step taken after the process has been launched.
void parseArgs(int argc, char* argv[]);
- /// @brief Use the pid to determine if there is another instance
- /// and create a pid file if we are alone.
- void pidCheck();
+ /// @brief Use the pid file to determine if there is another instance
+ ///
+ /// @param pid_file is the name of the file which holds the pid to check
+ /// returns true if there is a process with that pid
+ bool pidCheck(const std::string & pid_file);
+
+ /// @brief Extract the pid and Write it out to the pid file
+ ///
+ /// @param pid_file is the name of the file in which to write the pid
+ /// returns true if the write was successful
+ bool pidWrite(const std::string & pid_file);
/// @brief Get rid of the pid file we created earlier
- void pidDelete();
+ void pidDelete(const std::string & pid_file);
- /// #brief prints the program usage text to std error.
+ /// @brief Prints the program usage text to std error.
///
/// @param text is a string message which will preceded the usage text.
/// This is intended to be used for specific usage violation messages.
void usage(const std::string& text);
+ /// @brief Gets the Kea version number for printing
+ ///
+ /// @param extended is a boolean indicating if the version string
+ /// should be short (false) or extended (true)
+ std::string getVersion(bool extended);
+
+ // The following are primarly for the test code and not expected
+ // to be used in normal situations
+
+ /// @brief Gets the protocol version of the leaes files
+ ///
+ /// @return Returns the value of the protocol version
+ int getProtocolVersion() {
+ return (protocol_version_);
+ }
+
+ /// @brief Gets the config file name
+ ///
+ /// @return Returns the name of the config file
+ std::string getConfigFile() const {
+ return (config_file_);
+ }
+
+ /// @brief Gets the prevous file name
+ ///
+ /// @return Returns the name of the previous file
+ std::string getPreviousFile() const {
+ return (previous_file_);
+ }
+
+ /// @brief Gets the copy file name
+ ///
+ /// @return Returns the name of the copy file
+ std::string getCopyFile() const {
+ return (copy_file_);
+ }
+
+ /// @brief Gets the output file name
+ ///
+ /// @return Returns the name of the output file
+ std::string getOutputFile() const {
+ return (output_file_);
+ }
+
+ /// @brief Gets the finish file name
+ ///
+ /// @return Returns the name of the finish file
+ std::string getFinishFile() const {
+ return (finish_file_);
+ }
+
+ /// @brief Gets the pid file name
+ ///
+ /// @return Returns the name of the pid file
+ std::string getPidFile() const {
+ return (pid_file_);
+ }
+
private:
- int dhcp_version_;
+ int protocol_version_;
bool verbose_;
std::string config_file_;
std::string previous_file_;
std::string copy_file_;
std::string output_file_;
+ std::string finish_file_;
+ std::string pid_file_;
};
}; // namespace isc:lfc
/// errors, EXIT_FAILURE otherwise.
int main(int argc, char* argv[]) {
int ret = EXIT_SUCCESS;
- lfc lfc;
-
- // Instantiate/fetch the lfc application controller.
- // lfc& lfc = lfc::lfc();
+ lfcController lfcController;
// Launch the controller passing in command line arguments.
// Exit program with the controller's return code.
try {
// 'false' value disables test mode.
- lfc.launch(argc, argv, false);
+ lfcController.launch(argc, argv, false);
} catch (const isc::Exception& ex) {
std::cerr << "Service failed:" << ex.what() << std::endl;
ret = EXIT_FAILURE;
SHTESTS =
-noinst_SCRIPTS = lfc_tests.sh
+noinst_SCRIPTS =
-EXTRA_DIST = lfc_tests.sh.in
+EXTRA_DIST =
# test using command-line arguments, so use check-local target instead of TESTS
check-local:
CLEANFILES = $(builddir)/interfaces.txt $(builddir)/logger_lockfile
-DISTCLEANFILES = lfc_process_tests.sh
+DISTCLEANFILES =
AM_CXXFLAGS = $(KEA_CXXFLAGS)
if USE_CLANGPP
TESTS += lfc_unittests
-#lfc_unittests_SOURCES = d_test_stubs.cc d_test_stubs.h
+lfc_unittests_SOURCES = lfc_unittests.cc
+lfc_unittests_SOURCES += lfc_controller_unittests.cc
lfc_unittests_CPPFLAGS = $(AM_CPPFLAGS) $(GTEST_INCLUDES)
lfc_unittests_LDFLAGS = $(AM_LDFLAGS) $(GTEST_LDFLAGS)
lfc_unittests_LDADD = $(GTEST_LDADD)
-lfc_unittests_LDADD += $(top_builddir)/src/bin/d2/libd2.la
+lfc_unittests_LDADD += $(top_builddir)/src/bin/lfc/liblfc.la
lfc_unittests_LDADD += $(top_builddir)/src/lib/exceptions/libkea-exceptions.la
lfc_unittests_LDADD += $(top_builddir)/src/lib/log/libkea-log.la
lfc_unittests_LDADD += $(top_builddir)/src/lib/asiodns/libkea-asiodns.la
--- /dev/null
+// Copyright (C) 2015 Internet Systems Consortium, Inc. ("ISC")
+//
+// Permission to use, copy, modify, and/or distribute this software for any
+// purpose with or without fee is hereby granted, provided that the above
+// copyright notice and this permission notice appear in all copies.
+//
+// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+// AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+// PERFORMANCE OF THIS SOFTWARE.
+
+#include <log/logger_support.h>
+#include <gtest/gtest.h>
+#include <lfc/lfc.h>
+
+using namespace isc::lfc;
+using namespace std;
+
+TEST(lfcControllerTest, initialValues) {
+ lfcController lfcController;
+
+ // Verify that we start with everything empty
+ EXPECT_TRUE(lfcController.getProtocolVersion() == 0);
+ EXPECT_TRUE(lfcController.getConfigFile() == "");
+ EXPECT_TRUE(lfcController.getPreviousFile() == "");
+ EXPECT_TRUE(lfcController.getCopyFile() == "");
+ EXPECT_TRUE(lfcController.getOutputFile() == "");
+ EXPECT_TRUE(lfcController.getFinishFile() == "");
+ // Currently defaulting pid file for testing
+ // EXPECT_TRUE(lfcController.getPidFile() == "");
+}
+
+TEST(lfcControllerTest, fullCommandLine) {
+ lfcController lfcController;
+
+ // Verify that standard options can be parsed without error
+ char* argv[] = { const_cast<char*>("progName"),
+ const_cast<char*>("-4"),
+ const_cast<char*>("-p"),
+ const_cast<char*>("previous"),
+ const_cast<char*>("-i"),
+ const_cast<char*>("copy"),
+ const_cast<char*>("-o"),
+ const_cast<char*>("output"),
+ const_cast<char*>("-c"),
+ const_cast<char*>("config"),
+ const_cast<char*>("-f"),
+ const_cast<char*>("finish") };
+ int argc = 12;
+
+ EXPECT_NO_THROW(lfcController.parseArgs(argc, argv));
+
+ // The parsed data
+ EXPECT_TRUE(lfcController.getProtocolVersion() == 4);
+ EXPECT_TRUE(lfcController.getConfigFile() == "config");
+ EXPECT_TRUE(lfcController.getPreviousFile() == "previous");
+ EXPECT_TRUE(lfcController.getCopyFile() == "copy");
+ EXPECT_TRUE(lfcController.getOutputFile() == "output");
+ EXPECT_TRUE(lfcController.getFinishFile() == "finish");
+}
+
+TEST(lfcControllerTest, notEnoughData) {
+ lfcController lfcController;
+
+ // The standard options we shall test what happens
+ // if we don't include all of them
+ char* argv[] = { const_cast<char*>("progName"),
+ const_cast<char*>("-4"),
+ const_cast<char*>("-p"),
+ const_cast<char*>("previous"),
+ const_cast<char*>("-i"),
+ const_cast<char*>("copy"),
+ const_cast<char*>("-o"),
+ const_cast<char*>("output"),
+ const_cast<char*>("-c"),
+ const_cast<char*>("config"),
+ const_cast<char*>("-f"),
+ const_cast<char*>("finish") };
+ int argc = 1;
+
+ EXPECT_THROW(lfcController.parseArgs(argc, argv), InvalidUsage);
+
+ argc = 2;
+ EXPECT_THROW(lfcController.parseArgs(argc, argv), InvalidUsage);
+
+ argc = 3;
+ EXPECT_THROW(lfcController.parseArgs(argc, argv), InvalidUsage);
+
+ argc = 4;
+ EXPECT_THROW(lfcController.parseArgs(argc, argv), InvalidUsage);
+
+ argc = 5;
+ EXPECT_THROW(lfcController.parseArgs(argc, argv), InvalidUsage);
+
+ argc = 6;
+ EXPECT_THROW(lfcController.parseArgs(argc, argv), InvalidUsage);
+
+ argc = 7;
+ EXPECT_THROW(lfcController.parseArgs(argc, argv), InvalidUsage);
+
+ argc = 8;
+ EXPECT_THROW(lfcController.parseArgs(argc, argv), InvalidUsage);
+
+ argc = 9;
+ EXPECT_THROW(lfcController.parseArgs(argc, argv), InvalidUsage);
+
+ argc = 10;
+ EXPECT_THROW(lfcController.parseArgs(argc, argv), InvalidUsage);
+
+ argc = 11;
+ EXPECT_THROW(lfcController.parseArgs(argc, argv), InvalidUsage);
+
+}
+
+TEST(lfcControllerTest, tooMuchData) {
+ lfcController lfcController;
+
+ // The standard options plus some others
+
+ char* argv[] = { const_cast<char*>("progName"),
+ const_cast<char*>("-4"),
+ const_cast<char*>("-p"),
+ const_cast<char*>("previous"),
+ const_cast<char*>("-i"),
+ const_cast<char*>("copy"),
+ const_cast<char*>("-o"),
+ const_cast<char*>("output"),
+ const_cast<char*>("-c"),
+ const_cast<char*>("config"),
+ const_cast<char*>("-f"),
+ const_cast<char*>("finish"),
+ const_cast<char*>("some"),
+ const_cast<char*>("other"),
+ const_cast<char*>("args"),
+ };
+ int argc = 15;
+
+ EXPECT_THROW(lfcController.parseArgs(argc, argv), InvalidUsage);
+}
+
+TEST(lfcControllerTest, someBadData) {
+ lfcController lfcController;
+
+ // The standard options plus some others
+
+ char* argv[] = { const_cast<char*>("progName"),
+ const_cast<char*>("some"),
+ const_cast<char*>("bad"),
+ const_cast<char*>("args"),
+ };
+ int argc = 4;
+
+ EXPECT_THROW(lfcController.parseArgs(argc, argv), InvalidUsage);
+}
+//-4 -p previous -i copy -o output -c config -f finish -d
--- /dev/null
+// Copyright (C) 2015 Internet Systems Consortium, Inc. ("ISC")
+//
+// Permission to use, copy, modify, and/or distribute this software for any
+// purpose with or without fee is hereby granted, provided that the above
+// copyright notice and this permission notice appear in all copies.
+//
+// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+// AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+// PERFORMANCE OF THIS SOFTWARE.
+
+#include <log/logger_support.h>
+#include <gtest/gtest.h>
+
+int
+main(int argc, char* argv[]) {
+
+ ::testing::InitGoogleTest(&argc, argv);
+
+ // See the documentation of the KEA_* environment variables in
+ // src/lib/log/README for info on how to tweak logging
+ isc::log::initLogger();
+
+ int result = RUN_ALL_TESTS();
+
+ return (result);
+}