noinst_LTLIBRARIES = libclient.la
-libclnt_la_SOURCES =
-libclnt_la_SOURCES += main.cc
-libclnt_la_SOURCES += client_interface.h client_interface.cc
-libclnt_la_SOURCES += executor.cc executor.h
-libclnt_la_SOURCES += clnt_process.cc clnt_process.h
-libclnt_la_SOURCES += clnt_cfg_mgr.cc clnt_cfg_mgr.h
-libclnt_la_SOURCES += clnt_config.cc clnt_config.h
+libclient_la_SOURCES =
+libclient_la_SOURCES += main.cc
+libclient_la_SOURCES += client_interface.h client_interface.cc
+libclient_la_SOURCES += executor.cc executor.h
+libclient_la_SOURCES += clnt_process.cc clnt_process.h
+libclient_la_SOURCES += clnt_cfg_mgr.cc clnt_cfg_mgr.h
+libclient_la_SOURCES += clnt_config.cc clnt_config.h
sbin_PROGRAMS = kea-client
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
#include <config.h>
+#include <boost/bind.hpp>
#include <client/client_interface.h>
+#include <iostream>
using namespace isc::util;
namespace isc {
namespace client {
+// Define the constants
+const int ClientInterface::ST_BEGIN;
+const int ClientInterface::ST_SERVER_DISCOVERY;
+const int ClientInterface::ST_AWAITING_RECOGNITION;
+
+const int ClientInterface::EVT_SEND_SOLICIT;
+const int ClientInterface::EVT_SOLICIT_RESPONSE_RECEIVED;
+const int ClientInterface::EVT_SOLICIT_TIMEOUT;
+const int ClientInterface::EVT_SEND_REQUEST;
+
+
// Constructor.
-ClientInterface(const str::string& name, int ifindex,
- IOServicePtr& io_service) :
- isc::dhcp::Iface(string, ifindex), io_service_(io_service)
+ClientInterface::ClientInterface(const std::string& name, int ifindex,
+ isc::asiolink::IOServicePtr& io_service) :
+ isc::dhcp::Iface(name, ifindex), io_service_(io_service)
{
}
// Define NCT events.
defineEvent(EVT_SEND_SOLICIT, "EVT_SEND_SOLICIT");
defineEvent(EVT_SOLICIT_RESPONSE_RECEIVED, "EVT_SOLICIT_RESPONSE_RECEIVED");
- defineEvent(EVT_SOLICIT_RESPONSE_TIMEOUT, "EVT_SOLICIT_RESPONSE_TIMEOUT");
+ defineEvent(EVT_SOLICIT_TIMEOUT, "EVT_SOLICIT_TIMEOUT");
defineEvent(EVT_SEND_REQUEST, "EVT_SEND_REQUEST");
defineEvent(EVT_REQUEST_RESPONSE_RECEIVED, "EVT_REQUEST_RESPONSE_RECEIVED");
defineEvent(EVT_REQUEST_RESPONSE_TIMEOUT, "EVT_REQUEST_RESPONSE_TIMEOUT");
// Verify events by trying to get them.
getEvent(EVT_SEND_SOLICIT);
getEvent(EVT_SOLICIT_RESPONSE_RECEIVED);
- getEvent(EVT_SOLICIT_RESPONSE_TIMEOUT);
+ getEvent(EVT_SOLICIT_TIMEOUT);
getEvent(EVT_SEND_REQUEST);
getEvent(EVT_REQUEST_RESPONSE_RECEIVED);
getEvent(EVT_REQUEST_RESPONSE_TIMEOUT);
defineState(ST_SERVER_DISCOVERY, "ST_SERVER_DISCOVERY",
boost::bind(&ClientInterface::serverDiscoveryHandler, this));
+ defineState(ST_AWAITING_RECOGNITION, "ST_AWAITING_RECOGNITION",
+ boost::bind(&ClientInterface::awaitingRecognitionHandler,
+ this));
+
+}
+
+void
+ClientInterface::verifyStates() {
+ // Call the superclass implementation first
+ StateModel::verifyStates();
+
+ // Verify ClientInterface states by attempting to fetch them.
+ getState(ST_BEGIN);
+ getState(ST_SERVER_DISCOVERY);
+ getState(ST_AWAITING_RECOGNITION);
+}
+
+
+// Asynchronous operation completion handler. Justs post the appropriate
+// event and enters the given state.
+
+void
+ClientInterface::asynchCompletion(const boost::system::error_code&, int event) {
+// TODO: Check error code
+ runModel(event);
+}
+
+
+// Begin handler. Initialise, then transition to SERVER_DISCOVERY
+
+void
+ClientInterface::beginHandler() {
+ std::cout << "beginHandler()\n";
+ // TODO: Initialization
+
+ // Move to the server discovery stage.
+ transition(ST_SERVER_DISCOVERY, EVT_SEND_SOLICIT);
+}
+
+// Server discovery handler. Broadcast a SOLICT message, then start a timer
+// and issue a read for a response.
+
+void
+ClientInterface::serverDiscoveryHandler() {
+ if (doOnEntry()) {
+ std::cout << "serverDiscoveryHandler()\n";
+ postNextEvent(NOP_EVT);
+
+ } else {
+ // All events (the completion of the I/O or the expiry of the timer)
+ // cause a transition to the AWAITING_RECOGNITION state.
+ transition(ST_AWAITING_RECOGNITION, getNextEvent());
+ }
+}
+
+// Awaiting recognition state. Process the response and timer handlers.
+
+void
+ClientInterface::awaitingRecognitionHandler() {
+ std::cout << "awaitingRecognitionHandler()\n";
+
+ // Stay in the AWAITING_RECOGNITION state.
+ transition(ST_AWAITING_RECOGNITION, NOP_EVT);
}
} // namespace isc::client
--- /dev/null
+// Copyright (C) 2013-2017 Internet Systems Consortium, Inc. ("ISC")
+//
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+#ifndef CLIENT6_INTERFACE_H
+#define CLIENT6_INTERFACE_H
+
+#include <asiolink/io_service.h>
+#include <dhcp/iface_mgr.h>
+#include <exceptions/exceptions.h>
+#include <util/state_model.h>
+
+#include <string>
+
+namespace isc {
+namespace client {
+
+/// @brief Thrown if the some error is encountered
+class Client6InterfaceError : public isc::Exception {
+public:
+ Client6InterfaceError(const char* file, size_t line, const char* what) :
+ isc::Exception(file, line, what) {};
+};
+
+/// @brief DHCPv6 Client Interface
+///
+/// This is the class that represents an interface that the client is managing.
+/// It has a dual inheritance:
+///
+/// The first parent is the Iface class, representing a physical interface. It
+/// contains all information, e.g. name, MAC address etc.
+///
+/// The other parent is the StateModel, which defines the state the interface
+/// is in and handles the logic for the process of acquring an address. Each
+/// state has an associate method that handles the processing of the state.
+/// Transitions between states are mainly (not always) triggered by the
+/// completion of an asynchronous operation.
+///
+/// To illustrate the flow of control in such a situation, assume the following:
+/// The Client Interface moves from state A to state B. In state B, it queues
+/// an asynchronous operation, the completion of which causes it to move to
+/// state C. The processing is as follows:
+///
+/// 1. State A is entered from state B. Any processing required on entry to
+/// state B is done in the state B's handler at that time: either
+/// the state is entered via a unique event, when a check on the event is
+/// sufficient to determine that the state has been entered from state A,
+/// or the single-shot doOnEntry() flag is checked.
+///
+/// 2. State B's handler queues an asynchronous I/O operation, passing to it
+/// as a parameter the event to invoke when the operation completes.
+///
+/// 3. The handler calls postNextEvent(NOP_EVT) then exits, causing the
+/// runModel() call that invoked the state machine processing to exit.
+/// The process goes back to waiting on the IOService object.
+///
+/// 4. The asynchronous event completes, and the completion handler calls
+/// the state machine's runModel() method, passing to it the event that
+/// was associated with the operation.
+///
+/// 5. The state machine calls state B's handler again, passing to it the
+/// event associated with the asynchronous operation. The handler calls
+/// the state machine's "transition" method to move to state C.
+///
+/// The upshot of this is that if an asynchronous operation is triggered, the
+/// Client Interface will wait for completion in the state that triggered the
+/// operation, transitioning to the new state when the operation completes.
+
+class Client6Interface : public isc::util::StateModel,
+ public isc::dhcp::Iface {
+public:
+
+ /// @brief State list
+ ///
+ /// See http://kea.isc.org/wiki/ClientDesign for the definitions of each
+ /// state.
+ enum {
+ ST_BEGIN = SM_DERIVED_STATE_MIN + 1,
+ ST_SERVER_DISCOVERY,
+ ST_SEND_SOLICIT,
+ ST_SOLICIT_TIMEOUT,
+ ST_ADVERTISE_RECEIVED,
+ ST_SEND_REQUEST,
+ ST_REQUEST_TIMEOUT,
+ ST_REPLY_RECEIVED,
+ ST_DUPLICATE_CHECK,
+ ST_DUPLICATE_TIMEOUT,
+ ST_CONFIGURED,
+ ST_START_RENEW,
+ ST_RESENT_RENEW,
+ ST_RENEW_COMPLETE,
+ ST_REBINDING,
+ ST_PROCESS_REBINDING,
+ ST_REBINDING_TIMEOUT
+ };
+
+ /// @brief Event List
+ ///
+ /// List of events. Effectively these are the list of states, as each
+ /// event indicates the target of the transition.
+ enum {
+ EVT_SERVER_DISCOVERY = SM_DERIVED_EVENT_MIN + 1,
+ EVT_SEND_SOLICIT,
+ EVT_ADVERTISE_RECEIVED,
+ EVT_SOLICIT_TIMEOUT,
+ EVT_SEND_REQUEST
+ EVT_REQUEST_TIMEOUT,
+ EVT_REPLY_RECEIVED,
+ EVT_DUPLICATE_CHECK,
+ EVT_DUPLICATE_TIMEOUT,
+ EVT_CONFIGURED,
+ EVT_START_RENEW,
+ EVT_RESEND_RENEW,
+ EVT_REBINDING,
+ EVT_PROCESS_REBINDING,
+ EVT_REBINDING_TIMEOUT
+ };
+
+ /// @brief Constructor
+ ///
+ /// @param name Name of the interface
+ /// @param index Index of the interface
+ /// @param io_service Pointer to the IOService object used to keep track of
+ /// all asynchronous operations.
+ Client6Interface(const std::string& name, int ifindex,
+ isc::asiolink::IOServicePtr& io_service);
+
+ /// @brief Destructor
+ virtual ~Client6Interface();
+
+ /// @brief Adds events defined by Client6Interface to the event set.
+ ///
+ /// This method adds the events defined for this state machine to the set
+ /// of defined events. It invokes the superclass's implementation
+ /// first to maintain the hierarchical chain of event definition.
+ ///
+ /// @throw StateModelError if an event definition is invalid or a duplicate.
+ virtual void defineEvents();
+
+ /// @brief Validates the contents of the set of events.
+ ///
+ /// This method verifies that the events defined by both the superclass and
+ /// this class are defined. As with defineEvents, this method calls the
+ /// superclass's implementation first, to verify events defined by it and
+ /// then this implementation to verify events defined by
+ /// NameChangeTransaction.
+ ///
+ /// @throw StateModelError if an event value is undefined.
+ virtual void verifyEvents();
+
+ /// @brief Adds states defined by Client6Interface to the state set.
+ ///
+ /// This method adds the states associated with the Client6Interface to
+ /// the dictionary of states. It invokes the superclass's implementation
+ /// first to maintain the hierarchical chain of state definition.
+ ///
+ /// @throw StateModelError if an state definition is invalid or a duplicate.
+ virtual void defineStates();
+
+ /// @brief Validates the contents of the set of states.
+ ///
+ /// This method verifies that the states defined by both the superclass and
+ /// this class are defined. As with defineStates, this method calls the
+ /// superclass's implementation first, to verify states defined by it and
+ /// then this implementation to verify states defined by Client6Interface.
+ ///
+ /// @throw StateModelError if an event value is undefined.
+ virtual void verifyStates();
+
+
+ //@{ State Methods
+
+ /// @brief State handler for BEGIN
+ ///
+ /// BEGIN is the state the model transitions into when the method
+ /// startTransaction is called, It is the entry point into the state
+ /// machine. It performs all the initialization then unconditionally
+ /// transitions to the SEND_SOLICIT state.
+ void beginHandler();
+
+ /// @brief State handler for SEND_SOLICIT
+ ///
+ /// SEND_SOLICIT is the state that initiates the discovery of servers.
+ /// It initializes the list of servers, then broadcasts the SOLICIT message.
+ /// It then kicks off an asynchronous read, as well as a read timer.
+ void serverDiscoveryHandler();
+
+ /// @brief State handler for ADVERTISE_RECEIVED
+ ///
+ /// The client enters this state when an ADVERTISE is received from the
+ /// server. If the SOLICIT has not timed out, it will - unless the
+ /// server is one with the maximum preference value - loop round and
+ /// wait for more responses until teh solicit timer times out.
+ void advertiseReceivedHandler();
+
+ /// @brief State handler for SEND_REQUEST
+ ///
+ /// Starts a timer and sends the REQUEST to the server at the top of the
+ /// servers list.
+ void sendRequestHandler();
+
+ /// @brief State handler for REQUEST_TIMEOUT
+ ///
+ /// Called when the timer associated with waiting for a REPLY from the
+ /// server has timed out, this either sends another request (to the same
+ /// or a different server) or goes back to looking for servers.
+ void requestTimeoutHandler()l
+
+ /// @brief State handler for REPLY_RECEIVED
+ ///
+ /// When the server responds with a REPLY message, the client enters this
+ /// state. Depending on the response, it will either look for duplicate
+ /// addresses or try to contact another server.
+ void replyReceivedTimer();
+
+ /// @brief State handler for DUPLICATE_CHECK
+ ///
+ /// The client enters this state to look for duplicates. It waits here
+ /// for a fixed period of time to see if the kernel realises that there
+ /// are duplicate addresses.
+ void duplicateCheckHandler();
+
+ /// @brief State handler for DUPLICATE_TIMEOUT
+ ///
+ /// This state is entered when the duplicate wait period expires. The
+ /// client consults the kernel to see if duplicate addresses were found.
+ void duplicateTimeoutHandler();
+
+ /// @brief State handler for CONFIGURED
+ ///
+ /// The CONFIGURED state is the state where the client should spend most of
+ /// its time. It only leaves this state when the T1 timer expires,
+ /// telling it that it should renew its lease.
+ void configuredHandler();
+
+ /// @brief State handler for START_RENEW
+ ///
+ /// The client enters this state when the T1 timer expires. From here, it
+ /// tries to renew its lease.
+ void startRenewHandler();
+
+ /// @brief State handler for RESEND_RENEW
+ ///
+ /// Entered when the iretransmission timer associated with receiving a
+ /// response to the renewal request times out, the renew request is resent
+ /// to the server.
+ void resendRenewHandler();
+
+ /// @brief State handler for RENEW_COMPLETE
+ ///
+ /// Entered when a response is received to the renew request, in this state
+ /// the client decides whether it can accept the answer or has to start
+ /// the process of acquiring a new lease.
+ void renewCompleteHandler();
+
+ /// @brief State handler for REBINDING
+ ///
+ /// If the T2 timer times out (this is started when a renewal request is
+ /// made), the client will start the process of rebinding to a new address.
+ void rebindingHandler();
+
+ /// @brief State handler for PROCESS_REBINDING
+ ///
+ /// Entered when a rebinding response has been received, in this state
+ /// the client decides whether to acept the response of take some other
+ /// action.
+ void processRebdingingHandler();
+
+ /// @brief State handler for REBINDING_TIMEOUT
+ ///
+ /// Enters when the timer assoiated with the rebinding request expires,
+ /// the client tidies up and starts the server discovery process again.
+ void rebindingTimeoutHandler();
+
+ //@}
+
+ /// @brief Asynchronous Operation Completion Handler
+ ///
+ /// Called when any asynchronous option completes, it causes the state
+ /// machine to transition to the next state.
+ ///
+ /// @param ec System error code
+ /// @param event Event that causes the transition
+ void asynchCompletion(const boost::system::error_code& ec, int event);
+
+
+ /// @brief Fetches the IOService the transaction uses for IO processing.
+ ///
+ /// @return returns a const pointer to the IOService.
+ const asiolink::IOServicePtr& getIOService() {
+ return (io_service_);
+ }
+
+private:
+ /// @brief The IOService which should be used to for IO processing.
+ asiolink::IOServicePtr io_service_;
+};
+
+/// @brief Defines a pointer to a Client6Interface
+typedef boost::shared_ptr<Client6Interface> Client6InterfacePtr;
+
+} // namespace isc::client
+} // namespace isc
+
+#endif // CLIENT6_INTERFACE_H
+++ /dev/null
-// Copyright (C) 2013-2017 Internet Systems Consortium, Inc. ("ISC")
-//
-// This Source Code Form is subject to the terms of the Mozilla Public
-// License, v. 2.0. If a copy of the MPL was not distributed with this
-// file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#ifndef CLIENT_INTERFACE_H
-#define CLIENT_INTERFACE_H
-
-#include <asiolink/io_service.h>
-#include <exceptions/exceptions.h>
-#include <util/state_model.h>
-
-#include <string>
-
-namespace isc {
-namespace client {
-
-/// @brief Thrown if the some error is encountered
-class ClientInterfaceError : public isc::Exception {
-public:
- ClientInterfaceError(const char* file, size_t line, const char* what) :
- isc::Exception(file, line, what) {};
-};
-
-/// @brief Client Interface
-///
-/// This is the class that represents an interface that the client is managing.
-/// It has a dual inheritance: the first parent is the Iface class,
-/// representing a physical interface. It contains all information, e.g.
-/// name, MAC address etc.
-///
-/// The other parent is the StateModel, which defines the state the interface
-/// is in and handles the logic for the process of acquring an address. Each
-/// state has an associate method, which is invoked when the state is entered.
-/// This will usually carry out a certain amount of processing before
-/// initiating an asynchronous operation (either an I/O or setting a timer).
-/// The callback handlers on these operations are methods in this class and
-/// after performing the necessary processing, cause a transition to some other
-/// state.
-///
-/// The processing required for the client is quite lengthy and is described in
-/// http://kea.isc.org/wiki/ClientDesign.
-
-class ClientInterface : public isc::util::StateModel, isc::dhcp::Iface {
-public:
-
- //@{ States
-
- /// @brief ST_BEGIN - Initialization
- ///
- /// The entry point into the state machine. The relevant sockets are
- /// opened, and the timer interval initialzied.
- static const int ST_BEGIN = SM_DERIVED_STATE_MIN + 1;
-
- /// @brief ST_SERVER_DISCOVERY - Initiate I/O to find servers
- ///
- /// Sends a SOLICIT meassage on the relevant interface and starts a timer.
- /// A wait state is then entered until the timer expires.
- static const int ST_ SERVER_DISCOVERY = SM_DERIVED_STATE_MIN + 2;
-
- /// @brief ST_AWAITING_RECOGNITION - Wait for server to respond
- ///
- /// A request has been broadcast, so we are now waiting for a server to
- /// respond.
- static const int ST_AWAITING_RECOGNITION = SM_DERIVED_STATE_MIN + 3;
-
- /// @brief ST_SEND_REQUEST - Send REQUEST to server
- ///
- /// One or more servers have responded, so select a server and send it
- /// a REQUEST.
- static const int ST_SEND_REQUEST = SM_DERIVED_STATE_MIN +4;
-
- /// @brief ST_AWAITING_RESPONSE - Await response from chosen server
- ///
- /// After a request has been sent to the selected server, the client must
- /// wait for a response.
- static const int ST_AWAITING_RESPONSE = SM_DERIVED_STATE_MIN + 5;
-
- /// @brief ST_DUPLICATE_CHECK - Look for address already in use
- ///
- /// Before starting to use the address, we need to wait for a bit to ensure
- /// that the address is not already in use.
- static const int ST_DUPLICATE_CHECK = SM_DERIVED_STATE_MIN + 6;
-
- /// @brief ST_DUPLICATE_CHECK_TIMEOUT - Duplicate check period has ended
- ///
- /// The waiting period for the duplicate check has ended, so now process
- /// the results.
- static const int ST_DUPLICATE_CHECK_TIMEOUT = SM_DERIVED_STATE_MIN + 7;
-
- /// @brief ST_CONFIGURED - Successful configuration
- ///
- /// The client has now been successfully configured, so now prepare it for
- /// renewing its configuration.
- static const int ST_CONFIGURED = SM_DERIVED_STATE_MIN + 8;
-
- /// @brief ST_START_RENEW - Start renewal process
- ///
- /// Send a RENEW message to the server from which we originally got our
- /// configuration and start all the relavnt timers associated with this
- /// process
- static const int ST_START_RENEW = SM_DERIVED_STATE_MIN + 9;
-
- /// @brief ST_RESEND_RENEW - Resend RENEW request
- static const int ST_RENEW_COMPLETE = SM_DERIVED_STATE_MIN + 10;
-
- /// @brief ST_RESEND_RENEW - Response to RENEW request received
- static const int ST_RENEW_COMPLETE = SM_DERIVED_STATE_MIN + 11;
-
- /// @brief ST_REBINDING - Handle rebinding
- ///
- /// The client was unable to renew its configuration, so move to the
- /// rebinding processing.
- static const int REBINDING = SM_DERIVED_STATE_MIN + 12;
-
- //@}
-
- //@{ Events
-
- /// @brief EVT_SEND_SOLICT - Trigger sending of SOLICIT message to server
- static const int EVT_SEND_SOLICIT = SM_DERIVED_EVENT_MIN + 1;
-
- /// @brief EVT_SOLICIT_RESPONSE_RECEIVED - Received response to SOLICT
- ///
- /// The server has responded with a message (that should be an ADVERTISE
- /// message).
- static const int EVT_SOLICIT_RESPONSE_RECEIVED = SM_DERIVED_EVENT_MIN + 2;
-
- /// @brief EVT_SOLICIT_TIMEOUT - No response to SOLICIT message
- static const int EVT_SOLICIT_TIMEOUT = SM_DERIVED_EVENT_MIN + 3;
-
- /// @brief - EVT_SEND_REQUEST - Initiate sending of REQUEST to server
- static const int EVT_SEND_REQUEST = SM_DERIVED_EVENT_MIN + 4;
-
- /// @brief EVT_REQUEST_RESPONSE_RECEIVED - Received response to REQUEST
- ///
- /// The server has responded to the client's REQUEST message with a response
- /// that should be a REPLY message.
- static const int EVT_REQUEST_RESPONSE_RECEIVED = SM_DERIVED_EVENT_MIN + 5;
-
- /// @brief EVT_REQUEST_RESPONSE_TIMEOUT - No response to REQUEST message
- static const int EVT_REQUEST_RESPONSE_TIMEOUT = SM_DERIVED_EVENT_MIN + 6;
-
- /// @brief EVT_DUPLICATE_TIMEOUT - Duplicate check timer has expired
- static const int EVT_DUPLICATE_TIMEOUT = SM_DERIVED_EVENT_MIN + 7;
-
- /// @brief EVT_T1_TIMEOUT - Timeout of T1 Timer
- static const int EVT_T1_TIMEOUT = SM_DERIVED_EVENT_MIN + 8;
-
- /// @brief EVT_RENEW_RESPONSE_RECEIVED - Received response to RENEW request
- static const int EVT_RENEW_RESPONSE_RECEIVED = SM_DERIVED_EVENT_MIN + 9;
-
- /// @brief EVT_RENEW_RESPONSE_TIMEOUT - RENEW response request timed out
- static const int EVT_RENEW_RESPONSE_TIMEOUT = SM_DERIVED_EVENT_MIN + 10;
-
- /// @brief EVT_T2_TIMEOUT - Timeout of T2 Timer
- static const int EVT_T2_TIMEOUT = SM_DERIVED_EVENT_MIN + 11;
-
- /// @brief EVT_RETRANSMISSION_TIMEOUT - Timeout of RETRANSMISSION Timer
- static const int EVT_RETRANSMISSION_TIMEOUT = SM_DERIVED_EVENT_MIN + 12;
-
- //@}
-
-
- /// @brief Constructor
- ///
- /// @param name Name of the interface
- /// @param index Index of the interface
- /// @param io_service Pointer to the IOService object used to keep track of
- /// all asynchronous operations.
- ClientInterface(const std::string& name, int ifindex,
- IOServicePtr& io_service);
-
- /// @brief Destructor
- virtual ~ClientInterface();
-
- /// @brief Adds events defined by ClientInterface to the event set.
- ///
- /// This method adds the events defined for this state machine to the set
- /// of defined events. It invokes the superclass's implementation
- /// first to maintain the hierarchical chain of event definition.
- ///
- /// @throw StateModelError if an event definition is invalid or a duplicate.
- virtual void defineEvents();
-
- /// @brief Validates the contents of the set of events.
- ///
- /// This method verifies that the events defined by both the superclass and
- /// this class are defined. As with defineEvents, this method calls the
- /// superclass's implementation first, to verify events defined by it and
- /// then this implementation to verify events defined by
- /// NameChangeTransaction.
- ///
- /// @throw StateModelError if an event value is undefined.
- virtual void verifyEvents();
-
- /// @brief Adds states defined by ClientInterface to the state set.
- ///
- /// This method adds the states associated with the ClientInterface to
- /// the dictionary of states. It invokes the superclass's implementation
- /// first to maintain the hierarchical chain of state definition.
- ///
- /// @throw StateModelError if an state definition is invalid or a duplicate.
- virtual void defineStates();
-
- /// @brief Validates the contents of the set of states.
- ///
- /// This method verifies that the states defined by both the superclass and
- /// this class are defined. As with defineStates, this method calls the
- /// superclass's implementation first, to verify states defined by it and
- /// then this implementation to verify states defined by ClientInterface.
- ///
- /// @throw StateModelError if an event value is undefined.
- virtual void verifyStates();
-
-
- //@{ State Methods
-
- /// @brief State handler for BEGIN
- ///
- /// Entered from:
- /// INIT_ST with next event of START_EVT
- ///
- /// BEGIN is the state the model transitions into when the method
- /// startTransaction is called, It is the entry point into the state
- /// machine. It performs all the initialization.
- ///
- /// Transitions to:
- /// - SERVER_DISCOVERY with the next event of EVT_SEND_SOLICIT. This is an
- /// unconditional transition.
- void beginHandler();
-
- /// @brief State handler for SERVER_DISCOVERY
- ///
- /// Entered from:
- /// BEGIN with next event of EVT_SEND_SOLICIT
- /// AWAITING_RECOGNITION with next event of EVT_SEND_SOLICIT
- /// SEND_REQUEST with next event of EVT_SEND_SOLICIT
- ///
- /// SERVER_DISCOVERY is the state that initiates the discovery of servers.
- /// It initializes the list of servers, then broadcasts the SOLICIT message.
- /// It then kicks off an asynchronous read, as well as a read timer.
- ///
- /// Transitions to:
- /// - AWAITING_RECOGNITION with next event of EVT_SOLICIT_RESPONSE RECEIVED
- /// - AWAITING_RECOGNITION with next event of EVT_SOLICIT_TIMEOUT
- void serverDiscoveryHandler();
-
- //@}
-
- /// @brief Asynchronous Operation Completion Handler
- ///
- /// Called when any asynchronous option completes, it causes the state
- /// machine to transition to the next state.
- ///
- /// @param ec System error code
- /// @param next_state State to which a transition should be made
- /// @param event Event that causes the transition
- void asynchCompletion(const boost::system::error_code& ec,
- int next_state, int event);
-
-
- /// @brief Fetches the IOService the transaction uses for IO processing.
- ///
- /// @return returns a const pointer to the IOService.
- const asiolink::IOServicePtr& getIOService() {
- return (io_service_);
- }
-
-private:
- /// @brief The IOService which should be used to for IO processing.
- asiolink::IOServicePtr io_service_;
-};
-
-/// @brief Defines a pointer to a ClientInterface
-typedef boost::shared_ptr<ClientInterface> ClientInterfacePtr;
-
-} // namespace isc::client
-} // namespace isc
-#endif
-SHTESTS =
# The test of dynamic reconfiguration based on signals will work only
# if we are using file based configuration approach.
-SHTESTS += clnt_process_tests.sh
-
-noinst_SCRIPTS = clnt_process_tests.sh
-
-EXTRA_DIST = clnt_process_tests.sh.in
-
-# test using command-line arguments, so use check-local target instead of TESTS
-check-local:
- for shtest in $(SHTESTS) ; do \
- echo Running test: $$shtest ; \
- export KEA_LOCKFILE_DIR=$(abs_top_builddir); \
- export KEA_PIDFILE_DIR=$(abs_top_builddir); \
- ${SHELL} $(abs_builddir)/$$shtest || exit ; \
- done
AM_CPPFLAGS = -I$(top_srcdir)/src/lib -I$(top_builddir)/src/lib
AM_CPPFLAGS += -I$(top_builddir)/src/bin # for generated spec_config.h header
AM_CPPFLAGS += -DINSTALL_PROG=\"$(abs_top_srcdir)/install-sh\"
AM_CPPFLAGS += -DCFG_EXAMPLES=\"$(abs_top_srcdir)/doc/examples/client\"
-DISTCLEANFILES = clnt_process_tests.sh
-
AM_CXXFLAGS = $(KEA_CXXFLAGS)
if USE_STATIC_LINK
TESTS =
if HAVE_GTEST
-TESTS += clnt_unittests
-
-clnt_unittests_SOURCES = clnt_unittests.cc
-
-clnt_unittests_CPPFLAGS = $(AM_CPPFLAGS) $(GTEST_INCLUDES)
-clnt_unittests_LDFLAGS = $(AM_LDFLAGS) $(CRYPTO_LDFLAGS)
-clnt_unittests_LDFLAGS += $(GTEST_LDFLAGS)
-
-clnt_unittests_LDADD = $(top_builddir)/src/bin/client/libclnt.la
-clnt_unittests_LDADD += $(top_builddir)/src/lib/process/testutils/libprocesstest.la
-clnt_unittests_LDADD += $(top_builddir)/src/lib/process/libkea-process.la
-clnt_unittests_LDADD += $(top_builddir)/src/lib/testutils/libkea-testutils.la
-clnt_unittests_LDADD += $(top_builddir)/src/lib/asiodns/libkea-asiodns.la
-clnt_unittests_LDADD += $(top_builddir)/src/lib/dhcp/libkea-dhcp++.la
-clnt_unittests_LDADD += $(top_builddir)/src/lib/asiolink/libkea-asiolink.la
-clnt_unittests_LDADD += $(top_builddir)/src/lib/cc/libkea-cc.la
-clnt_unittests_LDADD += $(top_builddir)/src/lib/hooks/libkea-hooks.la
-clnt_unittests_LDADD += $(top_builddir)/src/lib/util/threads/libkea-threads.la
-clnt_unittests_LDADD += $(top_builddir)/src/lib/util/libkea-util.la
-clnt_unittests_LDADD += $(top_builddir)/src/lib/exceptions/libkea-exceptions.la
-clnt_unittests_LDADD += $(LOG4CPLUS_LIBS) $(CRYPTO_LIBS)
-clnt_unittests_LDADD += $(BOOST_LIBS) $(GTEST_LDADD)
+TESTS += client_unittests
+
+client_unittests_SOURCES = client_unittests.cc
+client_unittests_SOURCES += state_machine_unittest.cc
+
+client_unittests_SOURCES += ../client_interface.cc
+
+client_unittests_CPPFLAGS = $(AM_CPPFLAGS) $(GTEST_INCLUDES)
+client_unittests_LDFLAGS = $(AM_LDFLAGS) $(CRYPTO_LDFLAGS)
+client_unittests_LDFLAGS += $(GTEST_LDFLAGS)
+
+#client_unittests_LDADD = $(top_builddir)/src/bin/client/libclient.la
+client_unittests_LDADD = $(top_builddir)/src/lib/process/testutils/libprocesstest.la
+client_unittests_LDADD += $(top_builddir)/src/lib/process/libkea-process.la
+client_unittests_LDADD += $(top_builddir)/src/lib/testutils/libkea-testutils.la
+client_unittests_LDADD += $(top_builddir)/src/lib/asiodns/libkea-asiodns.la
+client_unittests_LDADD += $(top_builddir)/src/lib/dhcp/libkea-dhcp++.la
+client_unittests_LDADD += $(top_builddir)/src/lib/asiolink/libkea-asiolink.la
+client_unittests_LDADD += $(top_builddir)/src/lib/cc/libkea-cc.la
+client_unittests_LDADD += $(top_builddir)/src/lib/hooks/libkea-hooks.la
+client_unittests_LDADD += $(top_builddir)/src/lib/util/threads/libkea-threads.la
+client_unittests_LDADD += $(top_builddir)/src/lib/util/libkea-util.la
+client_unittests_LDADD += $(top_builddir)/src/lib/exceptions/libkea-exceptions.la
+client_unittests_LDADD += $(LOG4CPLUS_LIBS) $(CRYPTO_LIBS)
+client_unittests_LDADD += $(BOOST_LIBS) $(GTEST_LDADD)
endif
--- /dev/null
+// Copyright (C) 2013-2017 Internet Systems Consortium, Inc. ("ISC")
+//
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+#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();
+
+ // Override --localstatedir value for PID files
+ setenv("KEA_PIDFILE_DIR", TEST_DATA_BUILDDIR, 1);
+
+ int result = RUN_ALL_TESTS();
+
+ return (result);
+}