summaryrefslogtreecommitdiffstats
path: root/src/lib
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib')
-rw-r--r--src/lib/config/module_spec.cc19
-rw-r--r--src/lib/config/tests/module_spec_unittests.cc4
-rw-r--r--src/lib/config/tests/testdata/data22_10.data11
-rw-r--r--src/lib/nsas/nameserver_address_store.cc13
-rw-r--r--src/lib/nsas/nameserver_address_store.h2
-rw-r--r--src/lib/nsas/nameserver_entry.cc6
-rw-r--r--src/lib/nsas/nameserver_entry.h4
-rw-r--r--src/lib/nsas/random_number_generator.h73
-rw-r--r--src/lib/nsas/tests/nameserver_address_store_unittest.cc40
-rw-r--r--src/lib/nsas/tests/nameserver_address_unittest.cc12
-rw-r--r--src/lib/nsas/tests/nameserver_entry_unittest.cc30
-rw-r--r--src/lib/nsas/tests/nsas_test.h20
-rw-r--r--src/lib/nsas/tests/random_number_generator_unittest.cc16
-rw-r--r--src/lib/nsas/tests/zone_entry_unittest.cc10
-rw-r--r--src/lib/nsas/zone_entry.cc2
-rw-r--r--src/lib/nsas/zone_entry.h5
-rw-r--r--src/lib/rbmsgq/lib/cc.rb60
-rw-r--r--src/lib/rbmsgq/lib/cc/message.rb324
-rw-r--r--src/lib/rbmsgq/lib/cc/session.rb214
-rw-r--r--src/lib/resolve/tests/recursive_query_unittest_2.cc17
20 files changed, 177 insertions, 705 deletions
diff --git a/src/lib/config/module_spec.cc b/src/lib/config/module_spec.cc
index fd07dde651..1621fe313f 100644
--- a/src/lib/config/module_spec.cc
+++ b/src/lib/config/module_spec.cc
@@ -372,15 +372,18 @@ ModuleSpec::validateSpecList(ConstElementPtr spec, ConstElementPtr data,
BOOST_FOREACH(maptype m, data->mapValue()) {
bool found = false;
- BOOST_FOREACH(ConstElementPtr cur_spec_el, spec->listValue()) {
- if (cur_spec_el->get("item_name")->stringValue().compare(m.first) == 0) {
- found = true;
+ // Ignore 'version' as a config element
+ if (m.first.compare("version") != 0) {
+ BOOST_FOREACH(ConstElementPtr cur_spec_el, spec->listValue()) {
+ if (cur_spec_el->get("item_name")->stringValue().compare(m.first) == 0) {
+ found = true;
+ }
}
- }
- if (!found) {
- validated = false;
- if (errors) {
- errors->add(Element::create("Unknown item " + m.first));
+ if (!found) {
+ validated = false;
+ if (errors) {
+ errors->add(Element::create("Unknown item " + m.first));
+ }
}
}
}
diff --git a/src/lib/config/tests/module_spec_unittests.cc b/src/lib/config/tests/module_spec_unittests.cc
index 59f54596f8..1b43350f6a 100644
--- a/src/lib/config/tests/module_spec_unittests.cc
+++ b/src/lib/config/tests/module_spec_unittests.cc
@@ -162,6 +162,10 @@ TEST(ModuleSpec, DataValidation) {
EXPECT_FALSE(dataTest(dd, "data22_8.data"));
EXPECT_FALSE(dataTest(dd, "data22_9.data"));
+ // Test if "version" is allowed in config data
+ // (same data as 22_7, but added "version")
+ EXPECT_TRUE(dataTest(dd, "data22_10.data"));
+
ElementPtr errors = Element::createList();
EXPECT_FALSE(dataTestWithErrors(dd, "data22_8.data", errors));
EXPECT_EQ("[ \"Type mismatch\" ]", errors->str());
diff --git a/src/lib/config/tests/testdata/data22_10.data b/src/lib/config/tests/testdata/data22_10.data
new file mode 100644
index 0000000000..fed4001143
--- /dev/null
+++ b/src/lib/config/tests/testdata/data22_10.data
@@ -0,0 +1,11 @@
+{
+ "version": 123,
+ "value1": 1,
+ "value2": 2.3,
+ "value3": true,
+ "value4": "foo",
+ "value5": [ 1, 2, 3 ],
+ "value6": { "v61": "bar", "v62": true },
+ "value8": [ { "a": "d" }, { "a": "e" } ],
+ "value9": { "v91": "hi", "v92": { "v92a": "Hi", "v92b": 3 } }
+}
diff --git a/src/lib/nsas/nameserver_address_store.cc b/src/lib/nsas/nameserver_address_store.cc
index ae543c34e5..e92c17742d 100644
--- a/src/lib/nsas/nameserver_address_store.cc
+++ b/src/lib/nsas/nameserver_address_store.cc
@@ -54,7 +54,7 @@ NameserverAddressStore::NameserverAddressStore(
new HashDeleter<ZoneEntry>(*zone_hash_))),
nameserver_lru_(new LruList<NameserverEntry>((3 * nshashsize),
new HashDeleter<NameserverEntry>(*nameserver_hash_))),
- resolver_(resolver)
+ resolver_(resolver.get())
{ }
namespace {
@@ -67,12 +67,12 @@ namespace {
*/
boost::shared_ptr<ZoneEntry>
newZone(
- const boost::shared_ptr<isc::resolve::ResolverInterface>* resolver,
+ isc::resolve::ResolverInterface* resolver,
const string* zone, const RRClass* class_code,
const boost::shared_ptr<HashTable<NameserverEntry> >* ns_hash,
const boost::shared_ptr<LruList<NameserverEntry> >* ns_lru)
{
- boost::shared_ptr<ZoneEntry> result(new ZoneEntry(*resolver, *zone, *class_code,
+ boost::shared_ptr<ZoneEntry> result(new ZoneEntry(resolver, *zone, *class_code,
*ns_hash, *ns_lru));
return (result);
}
@@ -84,9 +84,10 @@ NameserverAddressStore::lookup(const string& zone, const RRClass& class_code,
boost::shared_ptr<AddressRequestCallback> callback, AddressFamily family,
const GlueHints& glue_hints)
{
- pair<bool, boost::shared_ptr<ZoneEntry> > zone_obj(zone_hash_->getOrAdd(HashKey(
- zone, class_code), boost::bind(newZone, &resolver_, &zone, &class_code,
- &nameserver_hash_, &nameserver_lru_)));
+ pair<bool, boost::shared_ptr<ZoneEntry> > zone_obj(
+ zone_hash_->getOrAdd(HashKey(zone, class_code),
+ boost::bind(newZone, resolver_, &zone, &class_code,
+ &nameserver_hash_, &nameserver_lru_)));
if (zone_obj.first) {
zone_lru_->add(zone_obj.second);
} else {
diff --git a/src/lib/nsas/nameserver_address_store.h b/src/lib/nsas/nameserver_address_store.h
index 7cbf83190e..d54be848d7 100644
--- a/src/lib/nsas/nameserver_address_store.h
+++ b/src/lib/nsas/nameserver_address_store.h
@@ -116,7 +116,7 @@ protected:
boost::shared_ptr<LruList<NameserverEntry> > nameserver_lru_;
// The resolver we use
private:
- boost::shared_ptr<isc::resolve::ResolverInterface> resolver_;
+ isc::resolve::ResolverInterface* resolver_;
//}@
};
diff --git a/src/lib/nsas/nameserver_entry.cc b/src/lib/nsas/nameserver_entry.cc
index 5c7873ea0c..367ea0a76f 100644
--- a/src/lib/nsas/nameserver_entry.cc
+++ b/src/lib/nsas/nameserver_entry.cc
@@ -380,8 +380,7 @@ class NameserverEntry::ResolverCallback :
};
void
-NameserverEntry::askIP(
- boost::shared_ptr<isc::resolve::ResolverInterface> resolver,
+NameserverEntry::askIP(isc::resolve::ResolverInterface* resolver,
const RRType& type, AddressFamily family)
{
QuestionPtr question(new Question(Name(getName()), RRClass(getClass()),
@@ -392,8 +391,7 @@ NameserverEntry::askIP(
}
void
-NameserverEntry::askIP(
- boost::shared_ptr<isc::resolve::ResolverInterface> resolver,
+NameserverEntry::askIP(isc::resolve::ResolverInterface* resolver,
boost::shared_ptr<Callback> callback, AddressFamily family)
{
Lock lock(mutex_);
diff --git a/src/lib/nsas/nameserver_entry.h b/src/lib/nsas/nameserver_entry.h
index 77937d19dc..99d7ff512f 100644
--- a/src/lib/nsas/nameserver_entry.h
+++ b/src/lib/nsas/nameserver_entry.h
@@ -241,7 +241,7 @@ public:
* even when there are addresses, if there are no addresses for this
* family.
*/
- void askIP(boost::shared_ptr<isc::resolve::ResolverInterface> resolver,
+ void askIP(isc::resolve::ResolverInterface* resolver,
boost::shared_ptr<Callback> callback, AddressFamily family);
//@}
@@ -273,7 +273,7 @@ private:
/// \short Private version that does the actual asking of one address type
///
/// Call unlocked.
- void askIP(boost::shared_ptr<isc::resolve::ResolverInterface> resolver,
+ void askIP(isc::resolve::ResolverInterface* resolver,
const isc::dns::RRType&, AddressFamily);
};
diff --git a/src/lib/nsas/random_number_generator.h b/src/lib/nsas/random_number_generator.h
index e80ebcb18a..8884d0e7bd 100644
--- a/src/lib/nsas/random_number_generator.h
+++ b/src/lib/nsas/random_number_generator.h
@@ -15,8 +15,12 @@
#ifndef __NSAS_RANDOM_NUMBER_GENERATOR_H
#define __NSAS_RANDOM_NUMBER_GENERATOR_H
+#include <algorithm>
#include <cmath>
#include <numeric>
+
+#include <exceptions/exceptions.h>
+
#include <boost/random/mersenne_twister.hpp>
#include <boost/random/uniform_int.hpp>
#include <boost/random/uniform_real.hpp>
@@ -25,6 +29,26 @@
namespace isc {
namespace nsas {
+class InvalidLimits : public isc::BadValue {
+public:
+ InvalidLimits(const char* file, size_t line, const char* what) :
+ isc::BadValue(file, line, what) {}
+};
+
+class SumNotOne : public isc::BadValue {
+public:
+ SumNotOne(const char* file, size_t line, const char* what) :
+ isc::BadValue(file, line, what) {}
+};
+
+class InvalidProbValue : public isc::BadValue {
+public:
+ InvalidProbValue(const char* file, size_t line, const char* what) :
+ isc::BadValue(file, line, what) {}
+};
+
+
+
/// \brief Uniform random integer generator
///
/// Generate uniformly distributed integers in range of [min, max]
@@ -35,8 +59,17 @@ public:
/// \param min The minimum number in the range
/// \param max The maximum number in the range
UniformRandomIntegerGenerator(int min, int max):
- min_(min), max_(max), dist_(min, max), generator_(rng_, dist_)
+ min_(std::min(min, max)), max_(std::max(min, max)),
+ dist_(min_, max_), generator_(rng_, dist_)
{
+ // To preserve the restriction of the underlying uniform_int class (and
+ // to retain compatibility with earlier versions of the class), we will
+ // abort if the minimum and maximum given are the wrong way round.
+ if (min > max) {
+ isc_throw(InvalidLimits, "minimum limit is greater than maximum "
+ "when initializing UniformRandomIntegerGenerator");
+ }
+
// Init with the current time
rng_.seed(time(NULL));
}
@@ -73,8 +106,10 @@ public:
size_t min = 0):
dist_(0, 1.0), uniform_real_gen_(rng_, dist_), min_(min)
{
- // The probabilities must be valid
- assert(isProbabilitiesValid(probabilities));
+ // The probabilities must be valid. Checking is quite an expensive
+ // operation, so is only done in a debug build.
+ assert(areProbabilitiesValid(probabilities));
+
// Calculate the partial sum of probabilities
std::partial_sum(probabilities.begin(), probabilities.end(),
std::back_inserter(cumulative_));
@@ -96,8 +131,8 @@ public:
/// \param min The minimum integer that generated
void reset(const std::vector<double>& probabilities, size_t min = 0)
{
- // The probabilities must be valid
- assert(isProbabilitiesValid(probabilities));
+ // The probabilities must be valid.
+ assert(areProbabilitiesValid(probabilities));
// Reset the cumulative sum
cumulative_.clear();
@@ -120,16 +155,24 @@ public:
private:
/// \brief Check the validation of probabilities vector
///
- /// The probability must be in range of [0, 1.0] and the sum must be equal to 1.0
- /// Empty probabilities is also valid.
- bool isProbabilitiesValid(const std::vector<double>& probabilities) const
+ /// The probability must be in range of [0, 1.0] and the sum must be equal
+ /// to 1.0. Empty probabilities are also valid.
+ ///
+ /// Checking the probabilities is quite an expensive operation, so it is
+ /// only done during a debug build (via a call through assert()). However,
+ /// instead of letting assert() call abort(), if this method encounters an
+ /// error, an exception is thrown. This makes unit testing somewhat easier.
+ ///
+ /// \param probabilities Vector of probabilities.
+ bool areProbabilitiesValid(const std::vector<double>& probabilities) const
{
typedef std::vector<double>::const_iterator Iterator;
double sum = probabilities.empty() ? 1.0 : 0.0;
for(Iterator it = probabilities.begin(); it != probabilities.end(); ++it){
//The probability must be in [0, 1.0]
if(*it < 0.0 || *it > 1.0) {
- return false;
+ isc_throw(InvalidProbValue,
+ "probability must be in the range 0..1");
}
sum += *it;
@@ -137,12 +180,16 @@ private:
double epsilon = 0.0001;
// The sum must be equal to 1
- return std::fabs(sum - 1.0) < epsilon;
+ if (std::fabs(sum - 1.0) >= epsilon) {
+ isc_throw(SumNotOne, "Sum of probabilities is not equal to 1");
+ }
+
+ return true;
}
- std::vector<double> cumulative_; ///< The partial sum of the probabilities
- boost::mt19937 rng_; ///< Mersenne Twister: A 623-dimensionally equidistributed uniform pseudo-random number generator
- boost::uniform_real<> dist_; ///< Uniformly distributed real numbers
+ std::vector<double> cumulative_; ///< Partial sum of the probabilities
+ boost::mt19937 rng_; ///< Mersenne Twister: A 623-dimensionally equidistributed uniform pseudo-random number generator
+ boost::uniform_real<> dist_; ///< Uniformly distributed real numbers
// Shortcut typedef
// This typedef is placed directly before its use, as the sunstudio
diff --git a/src/lib/nsas/tests/nameserver_address_store_unittest.cc b/src/lib/nsas/tests/nameserver_address_store_unittest.cc
index 95b46a858c..9133daf170 100644
--- a/src/lib/nsas/tests/nameserver_address_store_unittest.cc
+++ b/src/lib/nsas/tests/nameserver_address_store_unittest.cc
@@ -131,7 +131,7 @@ protected:
for (int i = 1; i <= 9; ++i) {
std::string name = "zone" + boost::lexical_cast<std::string>(i);
zones_.push_back(boost::shared_ptr<ZoneEntry>(new ZoneEntry(
- resolver_, name, RRClass(40 + i),
+ resolver_.get(), name, RRClass(40 + i),
boost::shared_ptr<HashTable<NameserverEntry> >(),
boost::shared_ptr<LruList<NameserverEntry> >())));
}
@@ -232,11 +232,9 @@ TEST_F(NameserverAddressStoreTest, NameserverDeletionCheck) {
EXPECT_EQ(1, nameservers_[1].use_count());
}
-/**
- * \short Try lookup on empty store.
- *
- * Check if it asks correct questions and it keeps correct internal state.
- */
+/// \brief Try lookup on empty store.
+///
+/// Check if it asks correct questions and it keeps correct internal state.
TEST_F(NameserverAddressStoreTest, emptyLookup) {
DerivedNsas nsas(resolver_, 10, 10);
// Ask it a question
@@ -268,11 +266,9 @@ TEST_F(NameserverAddressStoreTest, emptyLookup) {
}
}
-/**
- * \short Try looking up a zone that does not have any nameservers.
- *
- * It should not ask anything and say it is unreachable right away.
- */
+/// \brief Try looking up a zone that does not have any nameservers.
+///
+/// It should not ask anything and say it is unreachable right away.
TEST_F(NameserverAddressStoreTest, zoneWithoutNameservers) {
DerivedNsas nsas(resolver_, 10, 10);
// Ask it a question
@@ -285,13 +281,11 @@ TEST_F(NameserverAddressStoreTest, zoneWithoutNameservers) {
EXPECT_FALSE(NSASCallback::results[0].first);
}
-/**
- * \short Try looking up a zone that has only an unreachable nameserver.
- *
- * It should be unreachable. Furthermore, subsequent questions for that zone
- * or other zone with the same nameserver should be unreachable right away,
- * without further asking.
- */
+/// \brief Try looking up a zone that has only an unreachable nameserver.
+///
+/// It should be unreachable. Furthermore, subsequent questions for that zone
+/// or other zone with the same nameserver should be unreachable right away,
+/// without further asking.
TEST_F(NameserverAddressStoreTest, unreachableNS) {
DerivedNsas nsas(resolver_, 10, 10);
// Ask it a question
@@ -326,12 +320,10 @@ TEST_F(NameserverAddressStoreTest, unreachableNS) {
}
}
-/**
- * \short Try to stress it little bit by having multiple zones and nameservers.
- *
- * Does some asking, on a set of zones that share some nameservers, with
- * slower answering, evicting data, etc.
- */
+/// \short Try to stress it little bit by having multiple zones and nameservers.
+///
+/// Does some asking, on a set of zones that share some nameservers, with
+/// slower answering, evicting data, etc.
TEST_F(NameserverAddressStoreTest, CombinedTest) {
// Create small caches, so we get some evictions
DerivedNsas nsas(resolver_, 1, 1);
diff --git a/src/lib/nsas/tests/nameserver_address_unittest.cc b/src/lib/nsas/tests/nameserver_address_unittest.cc
index 1f924b38d2..457e61c5c0 100644
--- a/src/lib/nsas/tests/nameserver_address_unittest.cc
+++ b/src/lib/nsas/tests/nameserver_address_unittest.cc
@@ -39,7 +39,9 @@ class NameserverEntrySample {
public:
NameserverEntrySample():
name_("example.org"),
- rrv4_(new RRset(name_, RRClass::IN(), RRType::A(), RRTTL(1200)))
+ rrv4_(new RRset(name_, RRClass::IN(), RRType::A(), RRTTL(1200))),
+ ns_(new NameserverEntry(name_.toText(), RRClass::IN())),
+ resolver_(new TestResolver())
{
// Add some sample A records
rrv4_->addRdata(ConstRdataPtr(new RdataTest<A>("1.2.3.4")));
@@ -47,10 +49,9 @@ public:
rrv4_->addRdata(ConstRdataPtr(new RdataTest<A>("9.10.11.12")));
ns_.reset(new NameserverEntry(name_.toText(), RRClass::IN()));
- boost::shared_ptr<TestResolver> resolver(new TestResolver);
- ns_->askIP(resolver, boost::shared_ptr<Callback>(new Callback), ANY_OK);
- resolver->asksIPs(name_, 0, 1);
- resolver->requests[0].second->success(createResponseMessage(rrv4_));
+ ns_->askIP(resolver_.get(), boost::shared_ptr<Callback>(new Callback), ANY_OK);
+ resolver_->asksIPs(name_, 0, 1);
+ resolver_->requests[0].second->success(createResponseMessage(rrv4_));
}
// Return the sample NameserverEntry
@@ -75,6 +76,7 @@ private:
Name name_; ///< Name of the sample
RRsetPtr rrv4_; ///< Standard RRSet - IN, A, lowercase name
boost::shared_ptr<NameserverEntry> ns_; ///< Shared_ptr that points to a NameserverEntry object
+ boost::shared_ptr<TestResolver> resolver_;
class Callback : public NameserverEntry::Callback {
public:
diff --git a/src/lib/nsas/tests/nameserver_entry_unittest.cc b/src/lib/nsas/tests/nameserver_entry_unittest.cc
index 398c568277..4225e871ef 100644
--- a/src/lib/nsas/tests/nameserver_entry_unittest.cc
+++ b/src/lib/nsas/tests/nameserver_entry_unittest.cc
@@ -86,7 +86,7 @@ protected:
boost::shared_ptr<TestResolver> resolver(new TestResolver);
boost::shared_ptr<Callback> callback(new Callback);
// Let it ask for data
- entry->askIP(resolver, callback, ANY_OK);
+ entry->askIP(resolver.get(), callback, ANY_OK);
// Check it really asked and sort the queries
EXPECT_TRUE(resolver->asksIPs(Name(entry->getName()), 0, 1));
// Respond with answers
@@ -266,7 +266,7 @@ TEST_F(NameserverEntryTest, IPCallbacks) {
boost::shared_ptr<Callback> callback(new Callback);
boost::shared_ptr<TestResolver> resolver(new TestResolver);
- entry->askIP(resolver, callback, ANY_OK);
+ entry->askIP(resolver.get(), callback, ANY_OK);
// Ensure it becomes IN_PROGRESS
EXPECT_EQ(Fetchable::IN_PROGRESS, entry->getState());
// Now, there should be two queries in the resolver
@@ -274,12 +274,12 @@ TEST_F(NameserverEntryTest, IPCallbacks) {
ASSERT_TRUE(resolver->asksIPs(Name(EXAMPLE_CO_UK), 0, 1));
// Another one might ask
- entry->askIP(resolver, callback, V4_ONLY);
+ entry->askIP(resolver.get(), callback, V4_ONLY);
// There should still be only two queries in the resolver
ASSERT_EQ(2, resolver->requests.size());
// Another one, with need of IPv6 address
- entry->askIP(resolver, callback, V6_ONLY);
+ entry->askIP(resolver.get(), callback, V6_ONLY);
// Answer one and see that the callbacks are called
resolver->answer(0, Name(EXAMPLE_CO_UK), RRType::A(),
@@ -316,7 +316,7 @@ TEST_F(NameserverEntryTest, IPCallbacksUnreachable) {
boost::shared_ptr<TestResolver> resolver(new TestResolver);
// Ask for its IP
- entry->askIP(resolver, callback, ANY_OK);
+ entry->askIP(resolver.get(), callback, ANY_OK);
// Check it asks the resolver
EXPECT_EQ(2, resolver->requests.size());
ASSERT_TRUE(resolver->asksIPs(Name(EXAMPLE_CO_UK), 0, 1));
@@ -352,7 +352,7 @@ TEST_F(NameserverEntryTest, DirectAnswer) {
RRType::AAAA()), RRsetPtr());
// A successfull test first
- entry->askIP(resolver, callback, ANY_OK);
+ entry->askIP(resolver.get(), callback, ANY_OK);
EXPECT_EQ(0, resolver->requests.size());
EXPECT_EQ(1, callback->count);
NameserverEntry::AddressVector addresses;
@@ -362,7 +362,7 @@ TEST_F(NameserverEntryTest, DirectAnswer) {
// An unsuccessfull test
callback->count = 0;
entry.reset(new NameserverEntry(EXAMPLE_NET, RRClass::IN()));
- entry->askIP(resolver, callback, ANY_OK);
+ entry->askIP(resolver.get(), callback, ANY_OK);
EXPECT_EQ(0, resolver->requests.size());
EXPECT_EQ(1, callback->count);
addresses.clear();
@@ -381,8 +381,8 @@ TEST_F(NameserverEntryTest, ChangedExpired) {
boost::shared_ptr<TestResolver> resolver(new TestResolver);
// Ask the first time
- entry->askIP(resolver, callback, V4_ONLY);
- entry->askIP(resolver, callback, V6_ONLY);
+ entry->askIP(resolver.get(), callback, V4_ONLY);
+ entry->askIP(resolver.get(), callback, V6_ONLY);
EXPECT_TRUE(resolver->asksIPs(Name(EXAMPLE_CO_UK), 0, 1));
EXPECT_EQ(Fetchable::IN_PROGRESS, entry->getState());
resolver->answer(0, Name(EXAMPLE_CO_UK), RRType::A(),
@@ -402,8 +402,8 @@ TEST_F(NameserverEntryTest, ChangedExpired) {
// Ask the second time. The callbacks should not fire right away and it
// should request the addresses again
- entry->askIP(resolver, callback, V4_ONLY);
- entry->askIP(resolver, callback, V6_ONLY);
+ entry->askIP(resolver.get(), callback, V4_ONLY);
+ entry->askIP(resolver.get(), callback, V6_ONLY);
EXPECT_EQ(2, callback->count);
EXPECT_TRUE(resolver->asksIPs(Name(EXAMPLE_CO_UK), 2, 3));
EXPECT_EQ(Fetchable::IN_PROGRESS, entry->getState());
@@ -431,8 +431,8 @@ TEST_F(NameserverEntryTest, KeepRTT) {
boost::shared_ptr<TestResolver> resolver(new TestResolver);
// Ask the first time
- entry->askIP(resolver, callback, V4_ONLY);
- entry->askIP(resolver, callback, V6_ONLY);
+ entry->askIP(resolver.get(), callback, V4_ONLY);
+ entry->askIP(resolver.get(), callback, V6_ONLY);
EXPECT_TRUE(resolver->asksIPs(Name(EXAMPLE_CO_UK), 0, 1));
EXPECT_EQ(Fetchable::IN_PROGRESS, entry->getState());
resolver->answer(0, Name(EXAMPLE_CO_UK), RRType::A(),
@@ -455,8 +455,8 @@ TEST_F(NameserverEntryTest, KeepRTT) {
// Ask the second time. The callbacks should not fire right away and it
// should request the addresses again
- entry->askIP(resolver, callback, V4_ONLY);
- entry->askIP(resolver, callback, V6_ONLY);
+ entry->askIP(resolver.get(), callback, V4_ONLY);
+ entry->askIP(resolver.get(), callback, V6_ONLY);
EXPECT_EQ(2, callback->count);
EXPECT_TRUE(resolver->asksIPs(Name(EXAMPLE_CO_UK), 2, 3));
EXPECT_EQ(Fetchable::IN_PROGRESS, entry->getState());
diff --git a/src/lib/nsas/tests/nsas_test.h b/src/lib/nsas/tests/nsas_test.h
index 926e85916c..7500fc7792 100644
--- a/src/lib/nsas/tests/nsas_test.h
+++ b/src/lib/nsas/tests/nsas_test.h
@@ -222,11 +222,6 @@ private:
static const uint32_t HASHTABLE_DEFAULT_SIZE = 1009; ///< First prime above 1000
-} // namespace nsas
-} // namespace isc
-
-namespace {
-
using namespace std;
/*
@@ -245,6 +240,18 @@ class TestResolver : public isc::resolve::ResolverInterface {
public:
typedef pair<QuestionPtr, CallbackPtr> Request;
vector<Request> requests;
+
+ /// \brief Destructor
+ ///
+ /// This is important. All callbacks in the requests vector must be
+ /// called to remove them from internal loops. Without this, destroying
+ /// the NSAS object will leave memory assigned.
+ ~TestResolver() {
+ for (size_t i = 0; i < requests.size(); ++i) {
+ requests[i].second->failure();
+ }
+ }
+
virtual void resolve(const QuestionPtr& q, const CallbackPtr& c) {
PresetAnswers::iterator it(answers_.find(*q));
if (it == answers_.end()) {
@@ -420,6 +427,7 @@ protected:
Name ns_name_; ///< Nameserver name of ns.example.net
};
-} // Empty namespace
+} // namespace nsas
+} // namespace isc
#endif // __NSAS_TEST_H
diff --git a/src/lib/nsas/tests/random_number_generator_unittest.cc b/src/lib/nsas/tests/random_number_generator_unittest.cc
index c306b09784..85cbcbf757 100644
--- a/src/lib/nsas/tests/random_number_generator_unittest.cc
+++ b/src/lib/nsas/tests/random_number_generator_unittest.cc
@@ -59,11 +59,11 @@ private:
// non-debug environment.
// Note: the death test is not supported by all platforms. We need to
// compile tests using it selectively.
-#if !defined(NDEBUG) && defined(GTEST_HAS_DEATH_TEST)
+#if !defined(NDEBUG)
// Test of the constructor
TEST_F(UniformRandomIntegerGeneratorTest, Constructor) {
// The range must be min<=max
- ASSERT_DEATH(UniformRandomIntegerGenerator(3, 2), "");
+ ASSERT_THROW(UniformRandomIntegerGenerator(3, 2), InvalidLimits);
}
#endif
@@ -109,30 +109,32 @@ TEST_F(WeightedRandomIntegerGeneratorTest, Constructor) {
/// the tests will be failed since assert() is non-op in non-debug version.
/// The "#ifndef NDEBUG" is added to make the tests be performed only in
/// non-debug environment.
-#if !defined(NDEBUG) && defined(GTEST_HAS_DEATH_TEST)
+#if !defined(NDEBUG)
//The probability must be >= 0
probabilities.push_back(-0.1);
probabilities.push_back(1.1);
- ASSERT_DEATH(WeightedRandomIntegerGenerator gen2(probabilities), "");
+ ASSERT_THROW(WeightedRandomIntegerGenerator gen2(probabilities),
+ InvalidProbValue);
//The probability must be <= 1.0
probabilities.clear();
probabilities.push_back(0.1);
probabilities.push_back(1.1);
- ASSERT_DEATH(WeightedRandomIntegerGenerator gen3(probabilities), "");
+ ASSERT_THROW(WeightedRandomIntegerGenerator gen3(probabilities),
+ InvalidProbValue);
//The sum must be equal to 1.0
probabilities.clear();
probabilities.push_back(0.2);
probabilities.push_back(0.9);
- ASSERT_DEATH(WeightedRandomIntegerGenerator gen4(probabilities), "");
+ ASSERT_THROW(WeightedRandomIntegerGenerator gen4(probabilities), SumNotOne);
//The sum must be equal to 1.0
probabilities.clear();
probabilities.push_back(0.3);
probabilities.push_back(0.2);
probabilities.push_back(0.1);
- ASSERT_DEATH(WeightedRandomIntegerGenerator gen5(probabilities), "");
+ ASSERT_THROW(WeightedRandomIntegerGenerator gen5(probabilities), SumNotOne);
#endif
}
diff --git a/src/lib/nsas/tests/zone_entry_unittest.cc b/src/lib/nsas/tests/zone_entry_unittest.cc
index d10f12d21f..34f995c03c 100644
--- a/src/lib/nsas/tests/zone_entry_unittest.cc
+++ b/src/lib/nsas/tests/zone_entry_unittest.cc
@@ -47,7 +47,7 @@ class InheritedZoneEntry : public ZoneEntry {
const std::string& name, const RRClass& class_code,
boost::shared_ptr<HashTable<NameserverEntry> > nameserver_table,
boost::shared_ptr<LruList<NameserverEntry> > nameserver_lru) :
- ZoneEntry(resolver, name, class_code, nameserver_table,
+ ZoneEntry(resolver.get(), name, class_code, nameserver_table,
nameserver_lru)
{ }
NameserverVector& nameservers() { return nameservers_; }
@@ -569,7 +569,7 @@ TEST_F(ZoneEntryTest, NameserverEntryReady) {
// Inject the entry
boost::shared_ptr<NameserverEntry> nse(injectEntry());
// Fill it with data
- nse->askIP(resolver_, nseCallback(), ANY_OK);
+ nse->askIP(resolver_.get(), nseCallback(), ANY_OK);
EXPECT_EQ(Fetchable::IN_PROGRESS, nse->getState());
EXPECT_TRUE(resolver_->asksIPs(ns_name_, 0, 1));
EXPECT_NO_THROW(resolver_->answer(0, ns_name_, RRType::A(),
@@ -594,7 +594,7 @@ TEST_F(ZoneEntryTest, NameserverEntryNotAsked) {
TEST_F(ZoneEntryTest, NameserverEntryInProgress) {
// Prepare the nameserver entry
boost::shared_ptr<NameserverEntry> nse(injectEntry());
- nse->askIP(resolver_, nseCallback(), ANY_OK);
+ nse->askIP(resolver_.get(), nseCallback(), ANY_OK);
EXPECT_EQ(Fetchable::IN_PROGRESS, nse->getState());
EXPECT_TRUE(resolver_->asksIPs(ns_name_, 0, 1));
@@ -604,7 +604,7 @@ TEST_F(ZoneEntryTest, NameserverEntryInProgress) {
/// \short Check Zone's reaction to found expired nameserver
TEST_F(ZoneEntryTest, NameserverEntryExpired) {
boost::shared_ptr<NameserverEntry> nse(injectEntry());
- nse->askIP(resolver_, nseCallback(), ANY_OK);
+ nse->askIP(resolver_.get(), nseCallback(), ANY_OK);
EXPECT_EQ(Fetchable::IN_PROGRESS, nse->getState());
EXPECT_TRUE(resolver_->asksIPs(ns_name_, 0, 1));
EXPECT_NO_THROW(resolver_->answer(0, ns_name_, RRType::A(),
@@ -623,7 +623,7 @@ TEST_F(ZoneEntryTest, NameserverEntryExpired) {
/// \short Check how it reacts to an unreachable zone already in the table
TEST_F(ZoneEntryTest, NameserverEntryUnreachable) {
boost::shared_ptr<NameserverEntry> nse(injectEntry());
- nse->askIP(resolver_, nseCallback(), ANY_OK);
+ nse->askIP(resolver_.get(), nseCallback(), ANY_OK);
ASSERT_EQ(2, resolver_->requests.size());
resolver_->requests[0].second->failure();
resolver_->requests[1].second->failure();
diff --git a/src/lib/nsas/zone_entry.cc b/src/lib/nsas/zone_entry.cc
index 6d9c3971b4..35cb79aa38 100644
--- a/src/lib/nsas/zone_entry.cc
+++ b/src/lib/nsas/zone_entry.cc
@@ -36,7 +36,7 @@ using namespace dns;
namespace nsas {
ZoneEntry::ZoneEntry(
- boost::shared_ptr<isc::resolve::ResolverInterface> resolver,
+ isc::resolve::ResolverInterface* resolver,
const std::string& name, const isc::dns::RRClass& class_code,
boost::shared_ptr<HashTable<NameserverEntry> > nameserver_table,
boost::shared_ptr<LruList<NameserverEntry> > nameserver_lru) :
diff --git a/src/lib/nsas/zone_entry.h b/src/lib/nsas/zone_entry.h
index 7d8651f5c2..92ac75ac37 100644
--- a/src/lib/nsas/zone_entry.h
+++ b/src/lib/nsas/zone_entry.h
@@ -69,8 +69,7 @@ public:
* \todo Move to cc file, include the lookup (if NSAS uses resolver for
* everything)
*/
- ZoneEntry(
- boost::shared_ptr<isc::resolve::ResolverInterface> resolver,
+ ZoneEntry(isc::resolve::ResolverInterface* resolver,
const std::string& name, const isc::dns::RRClass& class_code,
boost::shared_ptr<HashTable<NameserverEntry> > nameserver_table,
boost::shared_ptr<LruList<NameserverEntry> > nameserver_lru);
@@ -158,7 +157,7 @@ private:
void process(AddressFamily family,
const boost::shared_ptr<NameserverEntry>& nameserver);
// Resolver we use
- boost::shared_ptr<isc::resolve::ResolverInterface> resolver_;
+ isc::resolve::ResolverInterface* resolver_;
// We store the nameserver table and lru, so we can look up when there's
// update
boost::shared_ptr<HashTable<NameserverEntry> > nameserver_table_;
diff --git a/src/lib/rbmsgq/lib/cc.rb b/src/lib/rbmsgq/lib/cc.rb
deleted file mode 100644
index b16f1ac389..0000000000
--- a/src/lib/rbmsgq/lib/cc.rb
+++ /dev/null
@@ -1,60 +0,0 @@
-# Copyright (C) 2009 Internet Systems Consortium.
-#
-# Permission to use, copy, modify, and 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 INTERNET SYSTEMS CONSORTIUM
-# DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
-# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
-# INTERNET SYSTEMS CONSORTIUM 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.
-
-unless respond_to?('relative_feature') # nodoc
- def require_relative(relative_feature)
- c = caller.first
- fail "Can't parse #{c}" unless c.rindex(/:\d+(:in `.*')?$/)
- file = $`
- if /\A\((.*)\)/ =~ file # eval, etc.
- raise LoadError, "require_relative is called in #{$1}"
- end
- absolute = File.expand_path(relative_feature, File.dirname(file))
- require absolute
- end
-end
-
-class CC
- def self.set_utf8(str) #nodoc
- if str.respond_to?('force_encoding')
- str.force_encoding(Encoding::UTF_8)
- end
- end
-
- def self.set_binary(str) #nodoc
- if str.respond_to?('force_encoding')
- str.force_encoding(Encoding::BINARY)
- end
- end
-end
-
-require_relative 'cc/message'
-require_relative 'cc/session'
-
-if $0 == __FILE__
- cc = CC::Session.new
-
- puts "Our local name: #{cc.lname}"
-
- cc.group_subscribe("test")
-
- counter = 0
-
- while counter < 10000 do
- cc.group_sendmsg({ :counter => counter }, "test", "foo")
- routing, data = cc.group_recvmsg(false)
- counter += 1
- end
-end
diff --git a/src/lib/rbmsgq/lib/cc/message.rb b/src/lib/rbmsgq/lib/cc/message.rb
deleted file mode 100644
index 254caf0c36..0000000000
--- a/src/lib/rbmsgq/lib/cc/message.rb
+++ /dev/null
@@ -1,324 +0,0 @@
-# Copyright (C) 2009 Internet Systems Consortium.
-#
-# Permission to use, copy, modify, and 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 INTERNET SYSTEMS CONSORTIUM
-# DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
-# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
-# INTERNET SYSTEMS CONSORTIUM 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.
-
-class CC
- class DecodeError < Exception ; end
-end
-
-class CC
-class Message
- PROTOCOL_VERSION = 0x536b616e
-
- ITEM_BLOB = 0x01
- ITEM_HASH = 0x02
- ITEM_LIST = 0x03
- ITEM_NULL = 0x04
- ITEM_BOOL = 0x05
- ITEM_INT = 0x06
- ITEM_UTF8 = 0x08
- ITEM_MASK = 0x0f
-
- ITEM_LENGTH_32 = 0x00
- ITEM_LENGTH_16 = 0x10
- ITEM_LENGTH_8 = 0x20
- ITEM_LENGTH_MASK = 0x30
-
- def initialize(msg = nil)
- @data = [PROTOCOL_VERSION].pack("N")
- if msg.is_a?(Hash)
- @data += CC::Message::encode_hash(msg)
- elsif msg.is_a?(String)
- @data = msg
- else
- raise ArgumentError, "initializer is not a Hash or String"
- end
- end
-
- def to_wire
- CC::set_binary(@data)
- @data
- end
-
- #
- # Encode a message. The item passed in should be a hash, and can contain
- # any number of items of any type afterwards. All keys in the hash must
- # be of type String or Symbol, and the values may be of any type. If
- # the value is a Hash or Array, it will be encoded as a message type
- # HASH or LIST. If it is nil, it will be encoded as NULL, and if it is
- # any other type, its to_s method will be called on it and it will be
- # encoded as a UTF8 item.
- #
- def self.to_wire(msg)
- encoded = [PROTOCOL_VERSION].pack("N")
- encoded += encode_hash(msg)
- encoded.force_encoding('binary')
- encoded
- end
-
- #
- # Decode a wire format message.
- #
- def self.from_wire(msg)
- if msg.length < 4
- raise CC::DecodeError, "Data is too short to decode"
- end
- msg.force_encoding('binary')
- version, msg = msg.unpack("N a*")
- unless version == PROTOCOL_VERSION
- raise CC::DecodeError, "Incorrect protocol version"
- end
- decode_hash(msg)
- end
-
- private
- # encode a simple string with a length prefix
- def self.encode_tag(tag)
- tag = tag.to_s
- [tag.length, tag].pack("C/a*")
- end
-
- def self.encode_length_and_type(data, type)
- if data.nil?
- [ITEM_NULL].pack("C")
- else
- len = data.length
- if len < 0x00000100
- [type | ITEM_LENGTH_8, len, data].pack("C C/a*")
- elsif len < 0x00010000
- [type | ITEM_LENGTH_16, len, data].pack("C n/a*")
- else
- [type | ITEM_LENGTH_32, len, data].pack("C N/a*")
- end
- end
- end
-
- # pack a string, including its type and length.
- def self.pack_utf8(str)
- encode_length_and_type(str.to_s.encode('binary'), ITEM_UTF8)
- end
-
- def self.pack_bool(bool)
- encode_length_and_type(encode_bool(bool), ITEM_BOOL)
- end
-
- def self.pack_int(int)
- encode_length_and_type(encode_int(int), ITEM_INT)
- end
-
- def self.pack_blob(str)
- encode_length_and_type(str.to_s, ITEM_BLOB)
- end
-
- def self.pack_array(arr)
- encode_length_and_type(encode_array(arr), ITEM_LIST)
- end
-
- def self.pack_hash(hash)
- encode_length_and_type(encode_hash(hash), ITEM_HASH)
- end
-
- def self.encode_data(data)
- str.to_s
- end
-
- def self.encode_utf8(str)
- str.to_s.encode('binary')
- end
-
- def self.pack_nil
- encode_length_and_type(nil, ITEM_NULL)
- end
-
- def self.encode_item(item)
- case item
- when nil
- ret = pack_nil
- when Hash
- ret = pack_hash(item)
- when Array
- ret = pack_array(item)
- when String
- if item.encoding == 'utf-8'
- ret = pack_utf8(item)
- else
- ret = pack_blob(item)
- end
- when FalseClass
- ret = pack_bool(item)
- when TrueClass
- ret = pack_bool(item)
- when Integer
- ret = pack_int(item)
- else
- ret = pack_blob(item.to_s)
- end
-
- ret
- end
-
- def self.encode_hash(msg)
- unless msg.is_a?Hash
- raise ArgumentError, "Should be a hash"
- end
- buffer = ""
- msg.each do |key, value|
- buffer += encode_tag(key)
- buffer += encode_item(value)
- end
- buffer
- end
-
- def self.encode_bool(msg)
- unless msg.class == FalseClass or msg.class == TrueClass
- raise ArgumentError, "Should be true or false"
- end
- if msg
- [0x01].pack("C")
- else
- [0x00].pack("C")
- end
- end
-
- def self.encode_int(int)
- int.to_s.encode('binary')
- end
-
- def self.encode_array(msg)
- unless msg.is_a?Array
- raise ArgumentError, "Should be an array"
- end
- buffer = ""
- msg.each do |value|
- buffer += encode_item(value)
- end
- buffer
- end
-
- def self.decode_tag(str)
- if str.length < 1
- raise CC::DecodeError, "Data underrun while decoding"
- end
- length = str.unpack("C")[0]
- if str.length - 1 < length
- raise CC::DecodeError, "Data underrun while decoding"
- end
- tag, remainder = str.unpack("x a#{length} a*")
- [ tag.encode('utf-8'), remainder ]
- end
-
- def self.decode_item(msg)
- if msg.length < 1
- raise CC::DecodeError, "Data underrun while decoding"
- end
- type_and_length_format = msg.unpack("C")[0]
- type = type_and_length_format & ITEM_MASK
- length_format = type_and_length_format & ITEM_LENGTH_MASK
-
- if type == ITEM_NULL
- msg = msg.unpack("x a*")[0]
- else
- if length_format == ITEM_LENGTH_8
- if msg.length - 1 < 1
- raise CC::DecodeError, "Data underrun while decoding"
- end
- length, msg = msg.unpack("x C a*")
- elsif length_format == ITEM_LENGTH_16
- if msg.length - 1 < 2
- raise CC::DecodeError, "Data underrun while decoding"
- end
- length, msg = msg.unpack("x n a*")
- elsif length_format == ITEM_LENGTH_32
- if msg.length - 1 < 4
- raise CC::DecodeError, "Data underrun while decoding"
- end
- length, msg = msg.unpack("x N a*")
- end
- if msg.length < length
- raise CC::DecodeError, "Data underrun while decoding"
- end
- item, msg = msg.unpack("a#{length} a*")
- end
-
- # unpack item based on type
- case type
- when ITEM_BLOB
- value = item
- when ITEM_UTF8
- value = item.encode('utf-8')
- when ITEM_BOOL
- value = decode_bool(item)
- when ITEM_INT
- value = decode_int(item)
- when ITEM_HASH
- value = decode_hash(item)
- when ITEM_LIST
- value = decode_array(item)
- when ITEM_NULL
- value = nil
- else
- raise CC::DecodeError, "Unknown item type in decode: #{type}"
- end
-
- [value, msg]
- end
-
- def self.decode_bool(msg)
- return msg == [0x01].pack("C")
- end
-
- def self.decode_int(msg)
- return Integer(msg.encode('utf-8'))
- end
-
- def self.decode_hash(msg)
- ret = {}
- while msg.length > 0
- tag, msg = decode_tag(msg)
- value, msg = decode_item(msg)
- ret[tag] = value
- end
-
- ret
- end
-
- def self.decode_array(msg)
- ret = []
- while msg.length > 0
- value, msg = decode_item(msg)
- ret << value
- end
-
- ret
- end
-
-end # class Message
-end # class CC
-
-if $0 == __FILE__
- target = {
- "from" => "sender@host",
- "to" => "recipient@host",
- "seq" => 1234,
- "data" => {
- "list" => [ 1, 2, nil, true, false, "this" ],
- "description" => "Fun for all",
- },
- }
-
- wire = CC::Message.to_wire(target)
- puts wire.inspect
-
- puts CC::Message.from_wire(wire).inspect
-end
diff --git a/src/lib/rbmsgq/lib/cc/session.rb b/src/lib/rbmsgq/lib/cc/session.rb
deleted file mode 100644
index 1d9cef5128..0000000000
--- a/src/lib/rbmsgq/lib/cc/session.rb
+++ /dev/null
@@ -1,214 +0,0 @@
-# Copyright (C) 2009 Internet Systems Consortium.
-#
-# Permission to use, copy, modify, and 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 INTERNET SYSTEMS CONSORTIUM
-# DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
-# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
-# INTERNET SYSTEMS CONSORTIUM 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.
-
-require 'socket'
-
-class CC
-class ProtocolError < Exception ; end
-end
-
-class CC
-class Session
- attr_reader :socket
- attr_reader :lname
-
- #
- # :host => host to connect to (defaults to "127.0.0.1")
- # :port => port to connect to (defaults to 9913)
- #
- def initialize(args = {})
- @socket = nil # TCP socket.
- @lname = nil # local name, or nil if not connected.
- @recvbuffer = "" # data buffer for partial reads.
- @recvlength = nil # if non-nil, we have a length to fill buffer to.
- @sendbuffer = "" # pending output data.
- @sequence = "a" # per message sequence id, always unique
-
- options = {
- :host => "127.0.0.1",
- :port => 9912
- }.merge(args)
-
- @socket = TCPSocket.new(options[:host], options[:port])
-
- #
- # Get our local name.
- #
- sendmsg({ :type => :getlname })
- msg = recvmsg(false)
- @lname = msg["lname"]
- if @lname.nil?
- raise CC::ProtocolError, "Could not get local name"
- end
- CC::set_utf8(@lname)
- end
-
- #
- # Send a message to the controller. The item to send can either be a
- # CC::Message object, or a Hash. If a Hash, it will be internally
- # converted to a CC::Message before transmitting.
- #
- # A return value of true means the entire message was not
- # transmitted, and a call to send_pending will have to be
- # made to send remaining data. This should only happen when
- # the socket is in non-blocking mode.
- #
- def sendmsg(msg)
- if msg.is_a?(Hash)
- msg = CC::Message.new(msg)
- end
-
- unless msg.is_a?(CC::Message)
- raise ArgumentError, "msg is not a CC::Message or a Hash"
- end
-
- wire = msg.to_wire
- @sendbuffer << [wire.length].pack("N")
- @sendbuffer << wire
-
- send_pending
- end
-
- #
- # Send as much data as we can.
- def send_pending
- return false if @sendbuffer.length == 0
- sent = @socket.send(@sendbuffer, 0)
- @sendbuffer = @sendbuffer[sent .. -1]
- @sendbuffer.length == 0 ? true : false
- end
-
- def recvmsg(nonblock = true)
- data = receive_full_buffer(nonblock)
- if data
- CC::Message::from_wire(data)
- else
- nil
- end
- end
-
- def group_subscribe(group, instance = "*", subtype = "normal")
- sendmsg({ :type => "subscribe",
- :group => group,
- :instance => instance,
- :subtype => subtype,
- })
- end
-
- def group_unsubscribe(group, instance = "*")
- sendmsg({ :type => "unsubscribe",
- :group => group,
- :instance => instance,
- })
- end
-
- def group_sendmsg(msg, group, instance = "*", to = "*")
- seq = next_sequence
- sendmsg({ :type => "send",
- :from => @lname,
- :to => to,
- :group => group,
- :instance => instance,
- :seq => seq,
- :msg => CC::Message.to_wire(msg),
- })
- seq
- end
-
- def group_replymsg(routing, msg)
- seq = next_sequence
- sendmsg({ :type => "send",
- :from => @lname,
- :to => routing["from"],
- :group => routing["group"],
- :instance => routing["instance"],
- :seq => seq,
- :reply => routing["seq"],
- :msg => CC::Message.to_wire(msg),
- })
- seq
- end
-
- def group_recvmsg(nonblock = true)
- msg = recvmsg(nonblock)
- return nil if msg.nil?
- data = CC::Message::from_wire(msg["msg"])
- msg.delete("msg")
- return [data, msg]
- end
-
- private
-
- def next_sequence
- @sequence.next!
- end
-
- #
- # A rather tricky function. If we have something waiting in our buffer,
- # and it will satisfy the current request, we will read it all in. If
- # not, we will read only what we need to satisfy a single message.
- #
- def receive_full_buffer(nonblock)
- # read the length prefix if we need it still.
- if @recvlength.nil?
- length = 4
- length -= @recvbuffer.length
- data = nil
- begin
- if nonblock
- data = @socket.recv_nonblock(length)
- else
- data = @socket.recv(length)
- end
- rescue Errno::EINPROGRESS
- rescue Errno::EAGAIN
- end
- return nil if data == nil
- @recvbuffer += data
- return nil if @recvbuffer.length < 4
- @recvlength = @recvbuffer.unpack('N')[0]
- @recvbuffer = ""
- CC::set_binary(@recvbuffer)
- end
-
- #
- # we have a length target. Loop reading data until we get enough to
- # fill our buffer.
- #
- length = @recvlength - @recvbuffer.length
- while (length > 0) do
- data = nil
- begin
- if nonblock
- data = @socket.recv_nonblock(length)
- else
- data = @socket.recv(length)
- end
- rescue Errno::EINPROGRESS
- rescue Errno::EAGAIN
- end
- return nil if data == 0 # blocking I/O
- @recvbuffer += data
- length -= data.length
- end
-
- data = @recvbuffer
- @recvbuffer = ""
- @recvlength = nil
- data
- end
-
-end # class Session
-end # class CC
diff --git a/src/lib/resolve/tests/recursive_query_unittest_2.cc b/src/lib/resolve/tests/recursive_query_unittest_2.cc
index ce960c0b7c..643c5a3aa2 100644
--- a/src/lib/resolve/tests/recursive_query_unittest_2.cc
+++ b/src/lib/resolve/tests/recursive_query_unittest_2.cc
@@ -84,9 +84,12 @@ const char* WWW_EXAMPLE_ORG = "192.0.2.254"; ///< Address of www.example.org
const bool DEBUG_PRINT = false;
class MockResolver : public isc::resolve::ResolverInterface {
- void resolve(const QuestionPtr& question,
+public:
+ virtual void resolve(const QuestionPtr& question,
const ResolverInterface::CallbackPtr& callback) {
}
+
+ virtual ~MockResolver() {}
};
@@ -118,8 +121,9 @@ public:
QueryStatus last_; ///< What was the last state
QueryStatus expected_; ///< Expected next state
OutputBufferPtr question_buffer_; ///< Question we expect to receive
- isc::nsas::NameserverAddressStore* nsas_;
- isc::cache::ResolverCache cache_;
+ boost::shared_ptr<MockResolver> resolver_; ///< Mock resolver
+ isc::nsas::NameserverAddressStore* nsas_; ///< Nameserver address store
+ isc::cache::ResolverCache cache_; ///< Resolver cache
// Data for TCP Server
size_t tcp_cumulative_; ///< Cumulative TCP data received
@@ -145,6 +149,8 @@ public:
last_(NONE),
expected_(NONE),
question_buffer_(new OutputBuffer(BUFFER_SIZE)),
+ resolver_(new MockResolver()),
+ nsas_(new isc::nsas::NameserverAddressStore(resolver_)),
tcp_cumulative_(0),
tcp_endpoint_(asio::ip::address::from_string(TEST_ADDRESS), TEST_PORT),
tcp_length_(0),
@@ -157,8 +163,6 @@ public:
udp_send_buffer_(new OutputBuffer(BUFFER_SIZE)),
udp_socket_(service_.get_io_service(), udp::v4())
{
- boost::shared_ptr<MockResolver>mock_resolver(new MockResolver());
- nsas_ = new isc::nsas::NameserverAddressStore(mock_resolver);
}
/// \brief Set Common Message Bits
@@ -652,8 +656,7 @@ TEST_F(RecursiveQueryTest2, Resolve) {
upstream, upstream_root);
query.setTestServer(TEST_ADDRESS, TEST_PORT);
- // Set up callback for the tor eceive notification that the query has
- // completed.
+ // Set up callback to receive notification that the query has completed.
isc::resolve::ResolverInterface::CallbackPtr
resolver_callback(new ResolverCallback(service_));