Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
Adam Osuchowski
Kea
Commits
dbe47722
Commit
dbe47722
authored
May 30, 2013
by
Thomas Markwalder
Browse files
[master] Merge branch 2955 which adds D2Process and DProcessBase
to bin/src/D2.
parents
72b428b6
ece829ff
Changes
9
Hide whitespace changes
Inline
Side-by-side
src/bin/d2/Makefile.am
View file @
dbe47722
...
...
@@ -48,12 +48,17 @@ pkglibexec_PROGRAMS = b10-d2
b10_d2_SOURCES
=
main.cc
b10_d2_SOURCES
+=
d2_log.cc d2_log.h
b10_d2_SOURCES
+=
d_process.h
b10_d2_SOURCES
+=
d2_process.cc d2_process.h
nodist_b10_d2_SOURCES
=
d2_messages.h d2_messages.cc
EXTRA_DIST
+=
d2_messages.mes
b10_d2_LDADD
=
$(top_builddir)
/src/lib/log/libb10-log.la
b10_d2_LDADD
+=
$(top_builddir)
/src/lib/exceptions/libb10-exceptions.la
b10_d2_LDADD
+=
$(top_builddir)
/src/lib/asiolink/libb10-asiolink.la
b10_d2_LDADD
+=
$(top_builddir)
/src/lib/cc/libb10-cc.la
b10_d2_LDADD
+=
$(top_builddir)
/src/lib/config/libb10-cfgclient.la
b10_d2dir
=
$(pkgdatadir)
b10_d2_DATA
=
d2.spec
src/bin/d2/d2_messages.mes
View file @
dbe47722
...
...
@@ -14,15 +14,35 @@
$NAMESPACE isc::d2
% D2_STARTING : process starting
This is a debug message issued during a D2 process startup.
% D2CTL_STARTING DHCP-DDNS controller starting, pid: %1
This is an informational message issued when controller for DHCP-DDNS
service first starts.
% D2_START_INFO pid: %1, verbose: %2, standalone: %3
This is a debug message issued during the D2 process startup.
It lists some information about the parameters with which the
process is running.
% D2CTL_STOPPING DHCP-DDNS controller is exiting
This is an informational message issued when the controller is exiting
following a shut down (normal or otherwise) of the DDHCP-DDNS process.
% D2_SHUTDOWN : process is performing a normal shutting down
This is a debug message issued when a D2 process shuts down
normally in response to command to stop.
% D2PRC_SHUTDOWN DHCP-DDNS process is performing a normal shut down
This is a debug message issued when the service process has been instructed
to shut down by the controller.
% D2PRC_RUN_ENTER process has entered the event loop
This is a debug message issued when the D2 process enters it's
run method.
% D2PRC_RUN_EXIT process is exiting the event loop
This is a debug message issued when the D2 process exits the
in event loop.
% D2PRC_FAILED process experienced a fatal error: %1
This is a debug message issued when the D2 process encounters an
unrecoverable error from within the event loop.
% D2PRC_CONFIGURE new configuration received: %1
This is a debug message issued when the D2 process configure method
has been invoked.
% D2PRC_COMMAND command directive received, command: %1 - args: %2
This is a debug message issued when the D2 process command method
has been invoked.
src/bin/d2/d2_process.cc
0 → 100644
View file @
dbe47722
// Copyright (C) 2013 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
<config/ccsession.h>
#include
<d2/d2_log.h>
#include
<d2/d2_process.h>
using
namespace
asio
;
namespace
isc
{
namespace
d2
{
D2Process
::
D2Process
(
const
char
*
name
,
IOServicePtr
io_service
)
:
DProcessBase
(
name
,
io_service
)
{
};
void
D2Process
::
init
()
{
};
int
D2Process
::
run
()
{
// Until shut down or an fatal error occurs, wait for and
// execute a single callback. This is a preliminary implementation
// that is likely to evolve as development progresses.
// To use run(), the "managing" layer must issue an io_service::stop
// or the call to run will continue to block, and shutdown will not
// occur.
LOG_DEBUG
(
d2_logger
,
DBGLVL_START_SHUT
,
D2PRC_RUN_ENTER
);
IOServicePtr
&
io_service
=
getIoService
();
while
(
!
shouldShutdown
())
{
try
{
io_service
->
run_one
();
}
catch
(
const
std
::
exception
&
ex
)
{
LOG_FATAL
(
d2_logger
,
D2PRC_FAILED
).
arg
(
ex
.
what
());
return
(
EXIT_FAILURE
);
}
}
LOG_DEBUG
(
d2_logger
,
DBGLVL_START_SHUT
,
D2PRC_RUN_EXIT
);
return
(
EXIT_SUCCESS
);
};
int
D2Process
::
shutdown
()
{
LOG_DEBUG
(
d2_logger
,
DBGLVL_START_SHUT
,
D2PRC_SHUTDOWN
);
setShutdownFlag
(
true
);
return
(
0
);
}
isc
::
data
::
ConstElementPtr
D2Process
::
configure
(
isc
::
data
::
ConstElementPtr
config_set
)
{
// @TODO This is the initial implementation which simply accepts
// any content in config_set as valid. This is sufficient to
// allow participation as a BIND10 module, while D2 configuration support
// is being developed.
LOG_DEBUG
(
d2_logger
,
DBGLVL_TRACE_BASIC
,
D2PRC_CONFIGURE
).
arg
(
config_set
->
str
());
return
(
isc
::
config
::
createAnswer
(
0
,
"Configuration accepted."
));
}
isc
::
data
::
ConstElementPtr
D2Process
::
command
(
const
std
::
string
&
command
,
isc
::
data
::
ConstElementPtr
args
){
// @TODO This is the initial implementation. If and when D2 is extended
// to support its own commands, this implementation must change. Otherwise
// it should reject all commands as it does now.
LOG_DEBUG
(
d2_logger
,
DBGLVL_TRACE_BASIC
,
D2PRC_COMMAND
).
arg
(
command
).
arg
(
args
->
str
());
return
(
isc
::
config
::
createAnswer
(
1
,
"Unrecognized command:"
+
command
));
}
D2Process
::~
D2Process
()
{
};
};
// namespace isc::d2
};
// namespace isc
src/bin/d2/d2_process.h
0 → 100644
View file @
dbe47722
// Copyright (C) 2013 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.
#ifndef D2_PROCESS_H
#define D2_PROCESS_H
#include
<d2/d_process.h>
namespace
isc
{
namespace
d2
{
/// @brief @TODO DHCP-DDNS Application Process
///
/// D2Process provides the top level application logic for DHCP-driven DDNS
/// update processing. It provides the asynchronous event processing required
/// to receive DNS mapping change requests and carry them out.
/// It implements the DProcessBase interface, which structures it such that it
/// is a managed "application", controlled by a management layer.
class
D2Process
:
public
DProcessBase
{
public:
/// @brief Constructor
///
/// @param name name is a text label for the process. Generally used
/// in log statements, but otherwise arbitrary.
/// @param io_service is the io_service used by the caller for
/// asynchronous event handling.
///
/// @throw DProcessBaseError is io_service is NULL.
D2Process
(
const
char
*
name
,
IOServicePtr
io_service
);
/// @brief Will be used after instantiation to perform initialization
/// unique to D2. This will likely include interactions with QueueMgr and
/// UpdateMgr, to prepare for request receipt and processing.
virtual
void
init
();
/// @brief Implements the process's event loop.
/// The initial implementation is quite basic, surrounding calls to
/// io_service->runOne() with a test of the shutdown flag.
/// Once invoked, the method will continue until the process itself is
/// exiting due to a request to shutdown or some anomaly forces an exit.
/// @return returns 0 upon a successful, "normal" termination, non
/// zero to indicate an abnormal termination.
virtual
int
run
();
// @TODO need brief
virtual
int
shutdown
();
// @TODO need brief
/// @brief Processes the given configuration.
///
/// This method may be called multiple times during the process lifetime.
/// Certainly once during process startup, and possibly later if the user
/// alters configuration. This method must not throw, it should catch any
/// processing errors and return a success or failure answer as described
/// below.
///
/// @param config_set a new configuration (JSON) for the process
/// @return an Element that contains the results of configuration composed
/// of an integer status value (0 means successful, non-zero means failure),
/// and a string explanation of the outcome.
virtual
isc
::
data
::
ConstElementPtr
configure
(
isc
::
data
::
ConstElementPtr
config_set
);
// @TODO need brief
/// @brief Processes the given command.
///
/// This method is called to execute any custom commands supported by the
/// process. This method must not throw, it should catch any processing
/// errors and return a success or failure answer as described below.
///
/// @param command is a string label representing the command to execute.
/// @param args is a set of arguments (if any) required for the given
/// command.
/// @return an Element that contains the results of command composed
/// of an integer status value (0 means successful, non-zero means failure),
/// and a string explanation of the outcome.
virtual
isc
::
data
::
ConstElementPtr
command
(
const
std
::
string
&
command
,
isc
::
data
::
ConstElementPtr
args
);
// @TODO need brief
virtual
~
D2Process
();
};
};
// namespace isc::d2
};
// namespace isc
#endif
src/bin/d2/d_process.h
0 → 100644
View file @
dbe47722
// Copyright (C) 2013 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.
#ifndef D_PROCESS_H
#define D_PROCESS_H
#include
<asiolink/asiolink.h>
#include
<cc/data.h>
#include
<boost/shared_ptr.hpp>
#include
<exceptions/exceptions.h>
typedef
boost
::
shared_ptr
<
isc
::
asiolink
::
IOService
>
IOServicePtr
;
namespace
isc
{
namespace
d2
{
/// @brief Exception thrown if the process encountered an operational error.
class
DProcessBaseError
:
public
isc
::
Exception
{
public:
DProcessBaseError
(
const
char
*
file
,
size_t
line
,
const
char
*
what
)
:
isc
::
Exception
(
file
,
line
,
what
)
{
};
};
/// @brief Application Process Interface
///
/// DProcessBase is an abstract class represents the primary "application"
/// level object in a "managed" asynchronous application. It provides a uniform
/// interface such that a managing layer can construct, intialize, and start
/// the application's event loop. The event processing is centered around the
/// use of isc::asiolink::io_service. The io_service is shared between the
/// the managing layer and the DProcessBase. This allows management layer IO
/// such as directives to be sensed and handled, as well as processing IO
/// activity specific to the application. In terms of management layer IO,
/// there are methods shutdown, configuration updates, and commands unique
/// to the application.
class
DProcessBase
{
public:
/// @brief Constructor
///
/// @param name name is a text label for the process. Generally used
/// in log statements, but otherwise arbitrary.
/// @param io_service is the io_service used by the caller for
/// asynchronous event handling.
///
/// @throw DProcessBaseError is io_service is NULL.
DProcessBase
(
const
char
*
name
,
IOServicePtr
io_service
)
:
name_
(
name
),
io_service_
(
io_service
),
shut_down_flag_
(
false
)
{
if
(
!
io_service_
)
{
isc_throw
(
DProcessBaseError
,
"IO Service cannot be null"
);
}
};
/// @brief May be used after instantiation to perform initialization unique
/// to application. It must be invoked prior to invoking run. This would
/// likely include the creation of additional IO sources and their
/// integration into the io_service.
virtual
void
init
()
=
0
;
/// @brief Implements the process's event loop. In its simplest form it
/// would an invocation io_service_->run(). This method should not exit
/// until the process itself is exiting due to a request to shutdown or
/// some anomaly is forcing an exit.
/// @return returns EXIT_SUCCESS upon a successful, normal termination,
/// and EXIT_FAILURE to indicate an abnormal termination.
virtual
int
run
()
=
0
;
/// @brief Implements the process's shutdown processing. When invoked, it
/// should ensure that the process gracefully exits the run method.
virtual
int
shutdown
()
=
0
;
/// @brief Processes the given configuration.
///
/// This method may be called multiple times during the process lifetime.
/// Certainly once during process startup, and possibly later if the user
/// alters configuration. This method must not throw, it should catch any
/// processing errors and return a success or failure answer as described
/// below.
///
/// @param config_set a new configuration (JSON) for the process
/// @return an Element that contains the results of configuration composed
/// of an integer status value (0 means successful, non-zero means failure),
/// and a string explanation of the outcome.
virtual
isc
::
data
::
ConstElementPtr
configure
(
isc
::
data
::
ConstElementPtr
config_set
)
=
0
;
/// @brief Processes the given command.
///
/// This method is called to execute any custom commands supported by the
/// process. This method must not throw, it should catch any processing
/// errors and return a success or failure answer as described below.
///
/// @param command is a string label representing the command to execute.
/// @param args is a set of arguments (if any) required for the given
/// command.
/// @return an Element that contains the results of command composed
/// of an integer status value (0 means successful, non-zero means failure),
/// and a string explanation of the outcome.
virtual
isc
::
data
::
ConstElementPtr
command
(
const
std
::
string
&
command
,
isc
::
data
::
ConstElementPtr
args
)
=
0
;
/// @brief Destructor
virtual
~
DProcessBase
(){};
bool
shouldShutdown
()
{
return
(
shut_down_flag_
);
}
void
setShutdownFlag
(
bool
value
)
{
shut_down_flag_
=
value
;
}
const
std
::
string
&
getName
()
const
{
return
(
name_
);
}
IOServicePtr
&
getIoService
()
{
return
(
io_service_
);
}
private:
/// @brief Text label for the process. Generally used in log statements,
/// but otherwise can be arbitrary.
std
::
string
name_
;
/// @brief The IOService to be used for asynchronous event handling.
IOServicePtr
io_service_
;
/// @brief Boolean flag set when shutdown has been requested.
bool
shut_down_flag_
;
};
/// @brief Defines a shared pointer to DProcessBase.
typedef
boost
::
shared_ptr
<
DProcessBase
>
DProcessBasePtr
;
};
// namespace isc::d2
};
// namespace isc
#endif
src/bin/d2/main.cc
View file @
dbe47722
...
...
@@ -82,16 +82,14 @@ main(int argc, char* argv[]) {
((
verbose_mode
&&
stand_alone
)
?
isc
::
log
::
DEBUG
:
isc
::
log
::
INFO
),
isc
::
log
::
MAX_DEBUG_LEVEL
,
NULL
,
!
stand_alone
);
LOG_INFO
(
d2_logger
,
D2_STARTING
);
LOG_DEBUG
(
d2_logger
,
DBGLVL_START_SHUT
,
D2_START_INFO
)
.
arg
(
getpid
()).
arg
(
verbose_mode
?
"yes"
:
"no"
)
.
arg
(
stand_alone
?
"yes"
:
"no"
);
LOG_INFO
(
d2_logger
,
D2CTL_STARTING
);
// For now we will sleep awhile to simulate doing something.
// Without at least a sleep, the process will start, exit and be
// restarted by Bind10/Init endlessley in a rapid succession.
sleep
(
1000
);
LOG_INFO
(
d2_logger
,
D2
_SHUTDOWN
);
LOG_INFO
(
d2_logger
,
D2
CTL_STOPPING
);
return
(
EXIT_SUCCESS
);
}
src/bin/d2/tests/Makefile.am
View file @
dbe47722
...
...
@@ -52,7 +52,10 @@ if HAVE_GTEST
TESTS
+=
d2_unittests
d2_unittests_SOURCES
=
../d2_log.h ../d2_log.cc
d2_unittests_SOURCES
+=
../d_process.h
d2_unittests_SOURCES
+=
../d2_process.cc ../d2_process.h
d2_unittests_SOURCES
+=
d2_unittests.cc
d2_unittests_SOURCES
+=
d2_process_unittests.cc
nodist_d2_unittests_SOURCES
=
../d2_messages.h ../d2_messages.cc
d2_unittests_CPPFLAGS
=
$(AM_CPPFLAGS)
$(GTEST_INCLUDES)
...
...
@@ -60,6 +63,9 @@ d2_unittests_LDFLAGS = $(AM_LDFLAGS) $(GTEST_LDFLAGS)
d2_unittests_LDADD
=
$(GTEST_LDADD)
d2_unittests_LDADD
+=
$(top_builddir)
/src/lib/exceptions/libb10-exceptions.la
d2_unittests_LDADD
+=
$(top_builddir)
/src/lib/log/libb10-log.la
d2_unittests_LDADD
+=
$(top_builddir)
/src/lib/asiolink/libb10-asiolink.la
d2_unittests_LDADD
+=
$(top_builddir)
/src/lib/cc/libb10-cc.la
d2_unittests_LDADD
+=
$(top_builddir)
/src/lib/config/libb10-cfgclient.la
endif
noinst_PROGRAMS
=
$(TESTS)
src/bin/d2/tests/d2_process_unittests.cc
0 → 100644
View file @
dbe47722
// Copyright (C) 2013 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
<config/ccsession.h>
#include
<d2/d2_process.h>
#include
<boost/date_time/posix_time/posix_time.hpp>
#include
<gtest/gtest.h>
#include
<config.h>
#include
<sstream>
using
namespace
std
;
using
namespace
isc
;
using
namespace
isc
::
config
;
using
namespace
isc
::
d2
;
using
namespace
boost
::
posix_time
;
namespace
{
/// @brief D2Process test fixture class
class
D2ProcessTest
:
public
::
testing
::
Test
{
public:
/// @brief Static instance accessible via test callbacks.
static
DProcessBasePtr
process_
;
/// @brief Constructor
D2ProcessTest
()
{
io_service_
.
reset
(
new
isc
::
asiolink
::
IOService
());
process_
.
reset
(
new
D2Process
(
"TestProcess"
,
io_service_
));
}
/// @brief Destructor
~
D2ProcessTest
()
{
io_service_
.
reset
();
process_
.
reset
();
}
/// @brief Callback that will invoke shutdown method.
static
void
genShutdownCallback
()
{
process_
->
shutdown
();
}
/// @brief Callback that throws an exception.
static
void
genFatalErrorCallback
()
{
isc_throw
(
DProcessBaseError
,
"simulated fatal error"
);
}
/// @brief IOService for event processing. Fills in for IOservice
/// supplied by management layer.
IOServicePtr
io_service_
;
};
// Define the static process instance
DProcessBasePtr
D2ProcessTest
::
process_
;
/// @brief Verifies D2Process constructor behavior.
/// 1. Verifies that constructor fails with an invalid IOService
/// 2. Verifies that constructor succeeds with a valid IOService
TEST
(
D2Process
,
construction
)
{
// Verify that the constructor will fail if given an empty
// io service.
IOServicePtr
lcl_io_service
;
EXPECT_THROW
(
D2Process
(
"TestProcess"
,
lcl_io_service
),
DProcessBaseError
);
// Verify that the constructor succeeds with a valid io_service
lcl_io_service
.
reset
(
new
isc
::
asiolink
::
IOService
());
ASSERT_NO_THROW
(
D2Process
(
"TestProcess"
,
lcl_io_service
));
}
/// @brief Verifies basic configure method behavior.
// @TODO This test is simplistic and will need to be augmented
// as configuration ability is implemented.
TEST_F
(
D2ProcessTest
,
configure
)
{
// Verify that given a configuration "set", configure returns
// a successful response.
int
rcode
=
-
1
;
string
config
=
"{
\"
test-value
\"
: 1000 } "
;
isc
::
data
::
ElementPtr
json
=
isc
::
data
::
Element
::
fromJSON
(
config
);
isc
::
data
::
ConstElementPtr
answer
=
process_
->
configure
(
json
);
isc
::
config
::
parseAnswer
(
rcode
,
answer
);
EXPECT_EQ
(
0
,
rcode
);
}
/// @brief Verifies basic command method behavior.
// @TODO IF the D2Process is extended to support extra commands
// this testing will need to augmented accordingly.
TEST_F
(
D2ProcessTest
,
command
)
{
// Verfiy that the process will process unsupported command and
// return a failure response.
int
rcode
=
-
1
;
string
args
=
"{
\"
arg1
\"
: 77 } "
;
isc
::
data
::
ElementPtr
json
=
isc
::
data
::
Element
::
fromJSON
(
args
);
isc
::
data
::
ConstElementPtr
answer
=
process_
->
command
(
"bogus_command"
,
json
);
parseAnswer
(
rcode
,
answer
);
EXPECT_EQ
(
1
,
rcode
);
}
/// @brief Verifies that an "external" call to shutdown causes
/// the run method to exit gracefully with a return value of EXIT_SUCCESS.
TEST_F
(
D2ProcessTest
,
normalShutdown
)
{
// Use an asiolink IntervalTimer and callback to generate the
// shutdown invocation. (Note IntervalTimer setup is in milliseconds).
isc
::
asiolink
::
IntervalTimer
timer
(
*
io_service_
);
timer
.
setup
(
genShutdownCallback
,
2
*
1000
);
// Record start time, and invoke run().
ptime
start
=
microsec_clock
::
universal_time
();
int
rcode
=
process_
->
run
();
// Record stop time.
ptime
stop
=
microsec_clock
::
universal_time
();
// Verify normal shutdown status.
EXPECT_EQ
(
EXIT_SUCCESS
,
rcode
);
// Verify that duration of the run invocation is the same as the
// timer duration. This demonstrates that the shutdown was driven
// by an io_service event and callback.
time_duration
elapsed
=
stop
-
start
;
EXPECT_TRUE
(
elapsed
.
total_milliseconds
()
>=
1900
&&
elapsed
.
total_milliseconds
()
<=
2100
);
}
/// @brief Verifies that an "uncaught" exception thrown during event loop
/// processing is treated as a fatal error.
TEST_F
(
D2ProcessTest
,
fatalErrorShutdown
)
{
// Use an asiolink IntervalTimer and callback to generate the
// the exception. (Note IntervalTimer setup is in milliseconds).
isc
::
asiolink
::
IntervalTimer
timer
(
*
io_service_
);
timer
.
setup
(
genFatalErrorCallback
,
2
*
1000
);
// Record start time, and invoke run().
ptime
start
=
microsec_clock
::
universal_time
();
int
rcode
=
process_
->
run
();
// Record stop time.
ptime
stop
=
microsec_clock
::
universal_time
();
// Verify failure status.
EXPECT_EQ
(
EXIT_FAILURE
,
rcode
);
// Verify that duration of the run invocation is the same as the
// timer duration. This demonstrates that the anomaly occurred
// during io callback processing.
time_duration
elapsed
=
stop
-
start
;
EXPECT_TRUE
(
elapsed
.
total_milliseconds
()
>=
1900
&&
elapsed
.
total_milliseconds
()
<=
2100
);
}
}
// end of anonymous namespace
src/bin/d2/tests/d2_test.py
View file @
dbe47722
...
...
@@ -161,7 +161,7 @@ class TestD2Daemon(unittest.TestCase):
# soon enough to catch it.
(
returncode
,
output
,
error
)
=
self
.
runCommand
([
"../b10-d2"
,
"-s"
])
output_text
=
str
(
output
)
+
str
(
error
)
self
.
assertEqual
(
output_text
.
count
(
"D2_STARTING"
),
1
)
self
.
assertEqual
(
output_text
.
count
(
"D2
CTL
_STARTING"
),
1
)
if
__name__
==
'__main__'
:
unittest
.
main
()
Write
Preview