Parcourir la source

[2377] Test error detection

Generate several broken input and see all of them fail. Also check they
continue to parse or not according to parameters.
Michal 'vorner' Vaner il y a 12 ans
Parent
commit
0f6b84e552
1 fichiers modifiés avec 74 ajouts et 0 suppressions
  1. 74 0
      src/lib/dns/tests/master_loader_unittest.cc

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

@@ -26,11 +26,14 @@
 #include <string>
 #include <vector>
 #include <list>
+#include <fstream>
 
 using namespace isc::dns;
 using std::vector;
 using std::string;
 using std::list;
+using std::ofstream;
+using std::endl;
 
 class MasterLoaderTest : public ::testing::Test {
 public:
@@ -74,6 +77,23 @@ public:
                                        options));
     }
 
+    void prepareBrokenZone(const string& filename, const string& line) {
+        ofstream out(filename.c_str(),
+                     std::ios_base::out | std::ios_base::trunc);
+        ASSERT_FALSE(out.fail());
+        out << "example.org. 3600 IN SOA ns1.example.org.filename "
+            "admin.example.org.filename 1234 3600 1800 2419200 7200" << endl;
+        out << line << endl;
+        out << "correct 3600    IN  A 192.0.2.2" << endl;
+        out.close();
+    }
+
+    void clear() {
+        warnings_.clear();
+        errors_.clear();
+        rrsets_.clear();
+    }
+
     // Check the next RR in the ones produced by the loader
     // Other than passed arguments are checked to be the default for the tests
     void checkRR(const string& name, const RRType& type, const string& data) {
@@ -155,3 +175,57 @@ TEST_F(MasterLoaderTest, invalidFile) {
     EXPECT_EQ(0, errors_[0].find("Error opening the input source file: ")) <<
         "Different error: " << errors_[0];
 }
+
+struct ErrorCase {
+    const char* line;
+    const char* problem;
+} error_cases[] = {
+    { "www...   3600    IN  A   192.0.2.1", "Invalid name" },
+    { "www      FORTNIGHT   IN  A   192.0.2.1", "Invalid TTL" },
+    { "www      3600    XX  A   192.0.2.1", "Invalid class" },
+    { "www      3600    IN  A   bad_ip", "Invalid Rdata" },
+    { "www      3600    IN", "Unexpected EOLN" },
+    { "www      3600    CH  TXT nothing", "Class mismatch" },
+    { NULL, NULL }
+};
+
+// Test a broken zone is handled properly. We test several problems,
+// both in strict and lenient mode.
+TEST_F(MasterLoaderTest, brokenZone) {
+    const string filename(TEST_DATA_BUILDDIR "/broken.zone");
+    for (const ErrorCase* ec = error_cases; ec->line != NULL; ++ec) {
+        SCOPED_TRACE(ec->problem);
+        prepareBrokenZone(filename, ec->line);
+
+        {
+            SCOPED_TRACE("Strict mode");
+            clear();
+            setLoader(filename.c_str(), Name("example.org."), RRClass::IN(),
+                      MasterLoader::DEFAULT);
+            loader_->load();
+            EXPECT_EQ(1, errors_.size());
+            EXPECT_TRUE(warnings_.empty());
+
+            checkRR("example.org", RRType::SOA(), "ns1.example.org. "
+                    "admin.example.org. 1234 3600 1800 2419200 7200");
+            // In the strict mode, it is aborted. The last RR is not
+            // even attempted.
+            EXPECT_TRUE(rrsets_.empty());
+        }
+
+        {
+            SCOPED_TRACE("Lenient mode");
+            clear();
+            setLoader(filename.c_str(), Name("example.org."), RRClass::IN(),
+                      MasterLoader::MANY_ERRORS);
+            loader_->load();
+            EXPECT_EQ(1, errors_.size());
+            EXPECT_TRUE(warnings_.empty());
+            checkRR("example.org", RRType::SOA(), "ns1.example.org. "
+                    "admin.example.org. 1234 3600 1800 2419200 7200");
+            // This one is below the error one.
+            checkRR("correct.example.org", RRType::A(), "192.0.2.2");
+            EXPECT_TRUE(rrsets_.empty());
+        }
+    }
+}