#include "container.h"
#include "client.h"
+#include "factory.h"
#include <memory>
#include <boost/foreach.hpp>
return (*candidate);
}
+// NOTE: This function is not tested, it would be complicated. However, the
+// purpose of the function is to provide a very thin wrapper to be able to
+// replace the call to DataSourceClientContainer constructor in tests.
+ConfigurableContainer::DataSourcePair
+ConfigurableContainer::getDataSource(const string& type,
+ const ::ConstElementPtr& configuration)
+{
+ DataSourceClientContainerPtr
+ container(new DataSourceClientContainer(type, configuration));
+ return (DataSourcePair(&container->getInstance(), container));
+}
+
}
}
typedef boost::shared_ptr<ZoneFinder> ZoneFinderPtr;
class DataSourceClient;
typedef boost::shared_ptr<DataSourceClient> DataSourceClientPtr;
+class DataSourceClientContainer;
+typedef boost::shared_ptr<DataSourceClientContainer>
+ DataSourceClientContainerPtr;
/// \brief The container of data sources.
///
///
/// It simply fills in the member variables according to the
/// parameters. See the member descriptions for their meaning.
- SearchResult(const DataSourceClientPtr& datasrc,
+ SearchResult(DataSourceClient* datasrc,
const ZoneFinderPtr& finder,
uint8_t matched_labels, bool exact_match) :
datasrc_(datasrc),
/// This conscructs a result for negative answer. Both pointers are
/// NULL, matched_labels_ is 0 and exact_match_ is false.
SearchResult() :
+ datasrc_(NULL),
matched_labels_(0),
exact_match_(false)
{ }
///
/// The data source containing the best matching zone. If no such
/// data source exists, this is NULL pointer.
- const DataSourceClientPtr datasrc_;
+ DataSourceClient* const datasrc_;
/// \brief The finder for the requested zone.
///
/// This is the finder corresponding to the best matching zone.
///
/// \todo The content yet to be defined.
struct DataSourceInfo {
- DataSourceClientPtr data_src_;
+ DataSourceClient* data_src_;
+ DataSourceClientContainerPtr container_;
};
/// \brief The collection of data sources.
typedef std::vector<DataSourceInfo> DataSources;
/// All our data sources are stored here. It is protected to let the
/// tests in.
DataSources data_sources_;
+ /// \brief Convenience type alias.
+ ///
+ /// \see getDataSource
+ typedef std::pair<DataSourceClient*, DataSourceClientContainerPtr>
+ DataSourcePair;
+ /// \brief Create a data source of given type and configuration.
+ ///
+ /// This is a thin wrapper around the DataSourceClientContainer
+ /// constructor. The function is here to make it possible for tests
+ /// to replace the DataSourceClientContainer with something else.
+ /// Also, derived classes might want to create the data sources
+ /// in a different way.
+ ///
+ /// The parameters are the same as of the constructor.
+ /// \return Pair containing both the data source and the container.
+ /// The container might be NULL in the derived class, it is
+ /// only stored so the data source is properly destroyed when
+ /// not needed. However, in such case, it is the caller's
+ /// responsibility to ensure the data source is deleted when
+ /// needed.
+ virtual DataSourcePair getDataSource(const std::string& type,
+ const data::ConstElementPtr&
+ configuration);
public:
/// \brief Access to the data sources.
///
namespace {
-// The test version is the same as the normal version. We, however, add
-// some methods to dig directly in the internals, for the tests.
-class TestedContainer : public ConfigurableContainer {
-public:
- TestedContainer(const ConstElementPtr& configuration,
- bool allow_cache) :
- ConfigurableContainer(configuration, allow_cache)
- { }
- DataSources& dataSources() { return (data_sources_); }
-};
-
// A test data source. It pretends it has some zones.
class TestDS : public DataSourceClient {
public:
private:
Name origin_;
};
+ // Constructor from a list of zones.
TestDS(const char* zone_names[]) {
for (const char** zone(zone_names); *zone; ++ zone) {
zones.insert(Name(*zone));
}
}
+ // Constructor from configuration. The list of zones will be empty, but
+ // it will keep the configuration inside for further inspection.
+ TestDS(const string& type, const ConstElementPtr& configuration) :
+ type_(type),
+ configuration_(configuration)
+ { }
virtual FindResult findZone(const Name& name) const {
if (zones.empty()) {
return (FindResult(result::NOTFOUND, ZoneFinderPtr()));
{
isc_throw(isc::NotImplemented, "Not implemented");
}
+ const string type_;
+ const ConstElementPtr configuration_;
private:
set<Name> zones;
};
+
+// The test version is the same as the normal version. We, however, add
+// some methods to dig directly in the internals, for the tests.
+class TestedContainer : public ConfigurableContainer {
+public:
+ TestedContainer(const ConstElementPtr& configuration,
+ bool allow_cache) :
+ ConfigurableContainer(configuration, allow_cache)
+ { }
+ DataSources& dataSources() { return (data_sources_); }
+ // Overwrite the containers method to get a data source with given type
+ // and configuration. We mock the data source and don't create the
+ // container. This is just to avoid some complexity in the tests.
+ virtual DataSourcePair getDataSource(const string& type,
+ const ConstElementPtr& configuration)
+ {
+ shared_ptr<TestDS> ds(new TestDS(type, configuration));
+ // Make sure it is deleted when the test container is deleted.
+ to_delete_.push_back(ds);
+ return (DataSourcePair(ds.get(), DataSourceClientContainerPtr()));
+ }
+private:
+ // Hold list of data sources created internally, so they are preserved
+ // until the end of the test and then deleted.
+ vector<shared_ptr<TestDS> > to_delete_;
+};
const size_t ds_count = 4;
const char* ds_zones[ds_count][3] = {
for (size_t i(0); i < ds_count; ++ i) {
shared_ptr<TestDS> ds(new TestDS(ds_zones[i]));
ConfigurableContainer::DataSourceInfo info;
- info.data_src_ = ds;
+ info.data_src_ = ds.get();
ds_.push_back(ds);
ds_info_.push_back(info);
}
const char* test)
{
SCOPED_TRACE(test);
- EXPECT_EQ(dsrc, result.datasrc_);
+ EXPECT_EQ(dsrc.get(), result.datasrc_);
ASSERT_NE(ZoneFinderPtr(), result.finder_);
EXPECT_EQ(name, result.finder_->getOrigin());
EXPECT_EQ(name.getLabelCount(), result.matched_labels_);