Browse Source

[2377] Allow checking if there was an error

Michal 'vorner' Vaner 12 years ago
parent
commit
487503d57b
3 changed files with 46 additions and 10 deletions
  1. 23 10
      src/lib/dns/master_loader.cc
  2. 10 0
      src/lib/dns/master_loader.h
  3. 13 0
      src/lib/dns/tests/master_loader_unittest.cc

+ 23 - 10
src/lib/dns/master_loader.cc

@@ -47,12 +47,14 @@ public:
         initialized_(false),
         ok_(true),
         many_errors_((options & MANY_ERRORS) != 0),
-        complete_(false)
+        complete_(false),
+        seen_error_(false)
     {}
 
     void reportError(const std::string& filename, size_t line,
                      const std::string& reason)
     {
+        seen_error_ = true;
         callbacks_.error(filename, line, reason);
         if (!many_errors_) {
             // In case we don't have the lenient mode, every error is fatal
@@ -102,10 +104,13 @@ private:
     const std::string master_file_;
     std::string string_token_;
     bool initialized_;
-    bool ok_;
-    const bool many_errors_;
+    bool ok_;                   // Is it OK to continue loading?
+    const bool many_errors_;    // Are many errors allowed (or should we abort
+                                // on the first)
 public:
-    bool complete_;
+    bool complete_;             // All work done.
+    bool seen_error_;           // Was there at least one error during the
+                                // load?
 };
 
 bool
@@ -172,12 +177,15 @@ MasterLoader::MasterLoaderImpl::loadIncremental(size_t count_limit) {
 
                 // Good, we loaded another one
                 ++count;
-            } else if (!many_errors_) {
-                ok_ = false;
-                complete_ = true;
-                // We don't have the exact error here, but it was reported
-                // by the error callback.
-                isc_throw(MasterLoaderError, "Invalid RR data");
+            } else {
+                seen_error_ = true;
+                if (!many_errors_) {
+                    ok_ = false;
+                    complete_ = true;
+                    // We don't have the exact error here, but it was reported
+                    // by the error callback.
+                    isc_throw(MasterLoaderError, "Invalid RR data");
+                }
             }
         } catch (const MasterLoaderError&) {
             // This is a hack. We exclude the MasterLoaderError from the
@@ -257,5 +265,10 @@ MasterLoader::loadIncremental(size_t count_limit) {
     return (result);
 }
 
+bool
+MasterLoader::loadedSucessfully() const {
+    return (impl_->complete_ && !impl_->seen_error_);
+}
+
 } // end namespace dns
 } // end namespace isc

+ 10 - 0
src/lib/dns/master_loader.h

@@ -132,6 +132,16 @@ public:
         }
     }
 
+    /// \brief Was the loading successful?
+    ///
+    /// \return true if and only if the loading was complete (after a call of
+    ///     load or after loadIncremental returned true) and there was no
+    ///     error. In other cases, return false.
+    /// \note While this method works even before the loading is complete (by
+    ///     returning false in that case), it is meant to be called only after
+    ///     finishing the load.
+    bool loadedSucessfully() const;
+
 private:
     class MasterLoaderImpl;
     MasterLoaderImpl* impl_;

+ 13 - 0
src/lib/dns/tests/master_loader_unittest.cc

@@ -128,7 +128,9 @@ TEST_F(MasterLoaderTest, basicLoad) {
     setLoader(TEST_DATA_SRCDIR "/example.org", Name("example.org."),
               RRClass::IN(), MasterLoader::MANY_ERRORS);
 
+    EXPECT_FALSE(loader_->loadedSucessfully());
     loader_->load();
+    EXPECT_TRUE(loader_->loadedSucessfully());
 
     EXPECT_TRUE(errors_.empty());
     EXPECT_TRUE(warnings_.empty());
@@ -146,7 +148,9 @@ TEST_F(MasterLoaderTest, streamConstructor) {
     setLoader(zone_stream, Name("example.org."), RRClass::IN(),
               MasterLoader::MANY_ERRORS);
 
+    EXPECT_FALSE(loader_->loadedSucessfully());
     loader_->load();
+    EXPECT_TRUE(loader_->loadedSucessfully());
 
     EXPECT_TRUE(errors_.empty());
     EXPECT_TRUE(warnings_.empty());
@@ -160,7 +164,9 @@ TEST_F(MasterLoaderTest, incrementalLoad) {
     setLoader(TEST_DATA_SRCDIR "/example.org", Name("example.org."),
               RRClass::IN(), MasterLoader::MANY_ERRORS);
 
+    EXPECT_FALSE(loader_->loadedSucessfully());
     EXPECT_FALSE(loader_->loadIncremental(2));
+    EXPECT_FALSE(loader_->loadedSucessfully());
 
     EXPECT_TRUE(errors_.empty());
     EXPECT_TRUE(warnings_.empty());
@@ -175,6 +181,7 @@ TEST_F(MasterLoaderTest, incrementalLoad) {
 
     // Load the rest.
     EXPECT_TRUE(loader_->loadIncremental(20));
+    EXPECT_TRUE(loader_->loadedSucessfully());
 
     EXPECT_TRUE(errors_.empty());
     EXPECT_TRUE(warnings_.empty());
@@ -232,7 +239,9 @@ TEST_F(MasterLoaderTest, brokenZone) {
             stringstream zone_stream(zone);
             setLoader(zone_stream, Name("example.org."), RRClass::IN(),
                       MasterLoader::DEFAULT);
+            EXPECT_FALSE(loader_->loadedSucessfully());
             EXPECT_THROW(loader_->load(), MasterLoaderError);
+            EXPECT_FALSE(loader_->loadedSucessfully());
             EXPECT_EQ(1, errors_.size()) << errors_[0];
             EXPECT_TRUE(warnings_.empty());
 
@@ -249,7 +258,9 @@ TEST_F(MasterLoaderTest, brokenZone) {
             stringstream zone_stream(zone);
             setLoader(zone_stream, Name("example.org."), RRClass::IN(),
                       MasterLoader::MANY_ERRORS);
+            EXPECT_FALSE(loader_->loadedSucessfully());
             EXPECT_NO_THROW(loader_->load());
+            EXPECT_FALSE(loader_->loadedSucessfully());
             EXPECT_EQ(1, errors_.size());
             EXPECT_TRUE(warnings_.empty());
             checkRR("example.org", RRType::SOA(), "ns1.example.org. "
@@ -267,7 +278,9 @@ TEST_F(MasterLoaderTest, brokenZone) {
             stringstream zone_stream(zoneEOF);
             setLoader(zone_stream, Name("example.org."), RRClass::IN(),
                       MasterLoader::MANY_ERRORS);
+            EXPECT_FALSE(loader_->loadedSucessfully());
             EXPECT_NO_THROW(loader_->load());
+            EXPECT_FALSE(loader_->loadedSucessfully());
             EXPECT_EQ(1, errors_.size());
             // FIXME: The invalid rdata generates a warning.
             // And we may want to generate warning ourself here too.