Browse Source

[trac980] Tests for abbreviated forms

Michal 'vorner' Vaner 14 years ago
parent
commit
1ab0f2e844
2 changed files with 62 additions and 9 deletions
  1. 13 0
      src/lib/acl/loader.h
  2. 49 9
      src/lib/acl/tests/loader_test.cc

+ 13 - 0
src/lib/acl/loader.h

@@ -401,4 +401,17 @@ private:
 }
 }
 }
 }
 
 
+/*
+ * This include at the end of the file is unusual. But we need to include it,
+ * we use template classes from there. However, they need to be present only
+ * at instantiation of our class, which will happen below this header.
+ *
+ * The problem is, the header uses us as well, therefore there's a circular
+ * dependency. If we loaded it at the beginning and someone loaded us first,
+ * the logic_check header wouldn't have our definitions. This way, no matter
+ * in which order they are loaded, the definitions from this header will be
+ * above the ones from logic_check.
+ */
+#include "logic_check.h"
+
 #endif
 #endif

+ 49 - 9
src/lib/acl/tests/loader_test.cc

@@ -76,16 +76,21 @@ public:
         EXPECT_NO_THROW(loader_.registerCreator(
         EXPECT_NO_THROW(loader_.registerCreator(
             namedCreator(name, abbreviatedList)));
             namedCreator(name, abbreviatedList)));
     }
     }
-    // Load a check and convert it to named check to examine it
-    shared_ptr<NamedCheck> loadCheck(const string& definition) {
+    template<class Result> shared_ptr<Result> loadCheckAny(const string&
+                                                               definition)
+    {
         SCOPED_TRACE("Loading check " + definition);
         SCOPED_TRACE("Loading check " + definition);
         shared_ptr<Check<Log> > loaded;
         shared_ptr<Check<Log> > loaded;
         EXPECT_NO_THROW(loaded = loader_.loadCheck(el(definition)));
         EXPECT_NO_THROW(loaded = loader_.loadCheck(el(definition)));
-        shared_ptr<NamedCheck> result(dynamic_pointer_cast<NamedCheck>(
+        shared_ptr<Result> result(dynamic_pointer_cast<Result>(
             loaded));
             loaded));
         EXPECT_TRUE(result);
         EXPECT_TRUE(result);
         return (result);
         return (result);
     }
     }
+    // Load a check and convert it to named check to examine it
+    shared_ptr<NamedCheck> loadCheck(const string& definition) {
+        return (loadCheckAny<NamedCheck>(definition));
+    }
     // The loadCheck throws an exception
     // The loadCheck throws an exception
     void checkException(const string& JSON) {
     void checkException(const string& JSON) {
         SCOPED_TRACE("Loading check exception: " + JSON);
         SCOPED_TRACE("Loading check exception: " + JSON);
@@ -133,6 +138,21 @@ public:
         aclSetup();
         aclSetup();
         EXPECT_THROW(loader_.load(el(JSON)), LoaderError);
         EXPECT_THROW(loader_.load(el(JSON)), LoaderError);
     }
     }
+    // Check that the subexpression is NamedCheck with correct data
+    void isSubexprNamed(const shared_ptr<CompoundCheck<Log> >& compound,
+                        size_t index, const string& name,
+                        ConstElementPtr data)
+    {
+        if (index < compound->getSubexpressions().size()) {
+            const NamedCheck*
+                check(dynamic_cast<const NamedCheck*>(compound->
+                                                      getSubexpressions()
+                                                      [index]));
+            ASSERT_TRUE(check) << "The subexpression is of different type";
+            EXPECT_EQ(name, check->name_);
+            EXPECT_TRUE(data->equals(*check->data_));
+        }
+    }
 };
 };
 
 
 // Test that it does not accept duplicate creator
 // Test that it does not accept duplicate creator
@@ -209,19 +229,39 @@ TEST_F(LoaderTest, CheckPropagate) {
     EXPECT_THROW(loader_.loadCheck(el("{\"throw\": null}")), TestCreatorError);
     EXPECT_THROW(loader_.loadCheck(el("{\"throw\": null}")), TestCreatorError);
 }
 }
 
 
-// The abbreviated form is not yet implemented
-// (we need the operators to be implemented)
+// The abbreviated form of check
 TEST_F(LoaderTest, AndAbbrev) {
 TEST_F(LoaderTest, AndAbbrev) {
     addNamed("name1");
     addNamed("name1");
     addNamed("name2");
     addNamed("name2");
-    EXPECT_THROW(loader_.loadCheck(el("{\"name1\": 1, \"name2\": 2}")),
-                 LoaderError);
+    shared_ptr<LogicOperator<AllOfSpec, Log> > oper(
+        loadCheckAny<LogicOperator<AllOfSpec, Log> >("{\"name1\": 1, \"name2\": 2}"));
+    // If we don't have anything loaded, the rest would crash. It is already
+    // reported from within loadCheckAny if it isn't loaded.
+    if (oper) {
+        // The subexpressions are correct
+        EXPECT_EQ(2, oper->getSubexpressions().size());
+        // Note: this test relies on the ordering in which map returns it's
+        // elements, which is in the lexicographical order of the strings.
+        // This is not required from our interface, but is easier to write
+        // the test.
+        isSubexprNamed(oper, 0, "name1", el("1"));
+        isSubexprNamed(oper, 1, "name2", el("2"));
+    }
 }
 }
 
 
+// The abbreviated form of parameters
 TEST_F(LoaderTest, OrAbbrev) {
 TEST_F(LoaderTest, OrAbbrev) {
     addNamed("name1");
     addNamed("name1");
-    EXPECT_THROW(loader_.loadCheck(el("{\"name1\": [1, 2]}")),
-                 LoaderError);
+    shared_ptr<LogicOperator<AnyOfSpec, Log> > oper(
+        loadCheckAny<LogicOperator<AnyOfSpec, Log> >("{\"name1\": [1, 2]}"));
+    // If we don't have anything loaded, the rest would crash. It is already
+    // reported from within loadCheckAny if it isn't loaded.
+    if (oper) {
+        // The subexpressions are correct
+        EXPECT_EQ(2, oper->getSubexpressions().size());
+        isSubexprNamed(oper, 0, "name1", el("1"));
+        isSubexprNamed(oper, 1, "name1", el("2"));
+    }
 }
 }
 
 
 // But this is not abbreviated form, this should be passed directly to the
 // But this is not abbreviated form, this should be passed directly to the