Browse Source

[3400] Element::fromJSONFile() added.

Tomek Mrugalski 11 years ago
parent
commit
36519e4dcc
4 changed files with 133 additions and 2 deletions
  1. 15 1
      src/lib/cc/data.cc
  2. 10 1
      src/lib/cc/data.h
  3. 1 0
      src/lib/cc/tests/Makefile.am
  4. 107 0
      src/lib/cc/tests/data_file_unittests.cc

+ 15 - 1
src/lib/cc/data.cc

@@ -24,6 +24,7 @@
 #include <iostream>
 #include <iostream>
 #include <string>
 #include <string>
 #include <sstream>
 #include <sstream>
+#include <fstream>
 #include <cerrno>
 #include <cerrno>
 #include <climits>
 #include <climits>
 
 
@@ -688,7 +689,7 @@ Element::fromJSON(const std::string& in, bool preproc) {
     ss << in;
     ss << in;
 
 
     int line = 1, pos = 1;
     int line = 1, pos = 1;
-    ElementPtr result(fromJSON(preproc?preprocess(ss):ss, "<string>", 
+    ElementPtr result(fromJSON(preproc?preprocess(ss):ss, "<string>",
                                line, pos));
                                line, pos));
     skipChars(ss, WHITESPACE, line, pos);
     skipChars(ss, WHITESPACE, line, pos);
     // ss must now be at end
     // ss must now be at end
@@ -698,6 +699,19 @@ Element::fromJSON(const std::string& in, bool preproc) {
     return result;
     return result;
 }
 }
 
 
+ElementPtr
+Element::fromJSONFile(const std::string& file_name,
+                      bool preproc) {
+    std::ifstream infile(file_name.c_str(), std::ios::in | std::ios::binary);
+    if (!infile.is_open())
+    {
+        isc_throw(InvalidOperation, "Failed to read file " << file_name
+                  << ",error:" << errno);
+    }
+
+    return (fromJSON(infile, file_name, preproc));
+}
+
 // to JSON format
 // to JSON format
 
 
 void
 void

+ 10 - 1
src/lib/cc/data.h

@@ -406,7 +406,6 @@ public:
     static ElementPtr fromJSON(std::istream& in, bool preproc = false)
     static ElementPtr fromJSON(std::istream& in, bool preproc = false)
         throw(JSONError);
         throw(JSONError);
 
 
-
     /// Creates an Element from the given input stream containing JSON
     /// Creates an Element from the given input stream containing JSON
     /// formatted data.
     /// formatted data.
     ///
     ///
@@ -435,6 +434,16 @@ public:
     static ElementPtr fromJSON(std::istream& in, const std::string& file,
     static ElementPtr fromJSON(std::istream& in, const std::string& file,
                                int& line, int &pos)
                                int& line, int &pos)
         throw(JSONError);
         throw(JSONError);
+
+    /// Reads contents of specified file and interprets it as JSON.
+    ///
+    /// @param file_name name of the file to read
+    /// @param preproc specified whether preprocessing (e.g. comment removal)
+    ///                should be performed
+    /// @return An ElementPtr that contains the element(s) specified
+    /// if the given file.
+    static ElementPtr fromJSONFile(const std::string& file_name,
+                                   bool preproc = false);
     //@}
     //@}
 
 
     /// \name Type name conversion functions
     /// \name Type name conversion functions

+ 1 - 0
src/lib/cc/tests/Makefile.am

@@ -21,6 +21,7 @@ if HAVE_GTEST
 TESTS += run_unittests
 TESTS += run_unittests
 # (TODO: these need to be completed and moved to tests/)
 # (TODO: these need to be completed and moved to tests/)
 run_unittests_SOURCES = data_unittests.cc session_unittests.cc run_unittests.cc
 run_unittests_SOURCES = data_unittests.cc session_unittests.cc run_unittests.cc
+run_unittests_SOURCES += data_file_unittests.cc
 run_unittests_CPPFLAGS = $(AM_CPPFLAGS) $(GTEST_INCLUDES)
 run_unittests_CPPFLAGS = $(AM_CPPFLAGS) $(GTEST_INCLUDES)
 run_unittests_LDFLAGS = $(AM_LDFLAGS) $(GTEST_LDFLAGS)
 run_unittests_LDFLAGS = $(AM_LDFLAGS) $(GTEST_LDFLAGS)
 
 

+ 107 - 0
src/lib/cc/tests/data_file_unittests.cc

@@ -0,0 +1,107 @@
+// Copyright (C) 2014 Internet Systems Consortium, Inc. ("ISC")
+//
+// Permission to use, copy, modify, and/or 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 ISC DISCLAIMS ALL WARRANTIES WITH
+// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+// AND FITNESS.  IN NO EVENT SHALL ISC 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.
+
+#include <config.h>
+#include <exceptions/exceptions.h>
+#include <dhcpsrv/daemon.h>
+#include <gtest/gtest.h>
+#include <cc/data.h>
+#include <fstream>
+
+using namespace isc;
+using namespace isc::data;
+
+namespace {
+
+/// @brief Test class for testing Deamon class
+class DataFileTest : public ::testing::Test {
+public:
+
+    /// @brief writes specified text to a file
+    ///
+    /// That is an auxilliary funtion used in fileRead() tests.
+    ///
+    /// @param content text to be written to disk
+    void writeFile(const std::string& content) {
+        // Write sample content to disk
+        unlink(TEMP_FILE);
+        std::ofstream write_me(TEMP_FILE);
+        EXPECT_TRUE(write_me.is_open());
+        write_me << content;
+        write_me.close();
+    }
+
+    /// destructor
+    ~DataFileTest() {
+        static_cast<void>(unlink(TEMP_FILE));
+    }
+
+    /// Name of the temporary file
+    static const char* TEMP_FILE;
+};
+
+/// Temporary file name used in some tests
+const char* DataFileTest::TEMP_FILE="temp-file.json";
+
+// Test checks whether a text file can be read from disk.
+TEST_F(DataFileTest, readFileMultiline) {
+
+    const char* no_endline = "{ \"abc\": 123 }";
+    const char* with_endline = "{\n \"abc\":\n 123\n }\n";
+
+    // That's what we expect
+    ElementPtr exp = Element::fromJSON(no_endline);
+
+    // Write sample content to disk
+    writeFile(no_endline);
+
+    // Check that the read content is correct
+    EXPECT_TRUE(exp->equals(*Element::fromJSONFile(TEMP_FILE)));
+
+    // Write sample content to disk
+    writeFile(with_endline);
+
+    // Check that the read content is correct
+    EXPECT_TRUE(exp->equals(*Element::fromJSONFile(TEMP_FILE)));
+}
+
+// Test checks whether comments in file are ignored as expected.
+TEST_F(DataFileTest, readFileComments) {
+    const char* commented_content = "# This is a comment\n"
+        "{ \"abc\":\n"
+        "# a comment comment\n"
+        "1 }\n";
+
+    // That's what we expect
+    ElementPtr exp = Element::fromJSON("{ \"abc\": 1 }");
+
+    // Write sample content to disk
+    writeFile(commented_content);
+
+    // Check that the read will fail (without comment elimination)
+//    EXPECT_THROW(Element::fromJSONFile(TEMP_FILE), JSONError);
+
+    // Check that the read content is correct (with comment elimination)
+    EXPECT_NO_THROW(Element::fromJSONFile(TEMP_FILE, true));
+    //EXPECT_TRUE(exp->equals(*Element::fromJSONFile(TEMP_FILE, true)));
+}
+
+// This test checks that missing file will generate an exception.
+TEST_F(DataFileTest, readFileError) {
+
+    // Check that the read content is correct
+    EXPECT_THROW(Element::fromJSONFile("no-such-file.txt"), isc::InvalidOperation);
+}
+
+};