You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@avro.apache.org by to...@apache.org on 2016/09/27 14:51:48 UTC

avro git commit: AVRO-1849: C++: printJson fails on record with no fields. Contributed by Simon Woodford.

Repository: avro
Updated Branches:
  refs/heads/master ab25bf203 -> 1296ce923


AVRO-1849: C++: printJson fails on record with no fields. Contributed by Simon Woodford.


Project: http://git-wip-us.apache.org/repos/asf/avro/repo
Commit: http://git-wip-us.apache.org/repos/asf/avro/commit/1296ce92
Tree: http://git-wip-us.apache.org/repos/asf/avro/tree/1296ce92
Diff: http://git-wip-us.apache.org/repos/asf/avro/diff/1296ce92

Branch: refs/heads/master
Commit: 1296ce9238a315b4323db351483dc66ec1a1afe3
Parents: ab25bf2
Author: Tom White <to...@cloudera.com>
Authored: Tue Sep 27 15:50:56 2016 +0100
Committer: Tom White <to...@cloudera.com>
Committed: Tue Sep 27 15:50:56 2016 +0100

----------------------------------------------------------------------
 CHANGES.txt                  |  3 ++
 lang/c++/build.sh            |  3 +-
 lang/c++/impl/NodeImpl.cc    | 11 +++----
 lang/c++/test/SchemaTests.cc | 68 +++++++++++++++++++++++++++++++++++++--
 4 files changed, 76 insertions(+), 9 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/avro/blob/1296ce92/CHANGES.txt
----------------------------------------------------------------------
diff --git a/CHANGES.txt b/CHANGES.txt
index eb5c3b2..d9b72ed 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -65,6 +65,9 @@ Trunk (not yet released)
     AVRO-1901: Record named "Exception" generated bad code.
     (Radai Rosenblatt via Niels Basjes)
 
+    AVRO-1849: C++: printJson fails on record with no fields.
+    (Simon Woodford vai tomwhite)
+
 Avro 1.8.1 (14 May 2016)
 
   INCOMPATIBLE CHANGES

http://git-wip-us.apache.org/repos/asf/avro/blob/1296ce92/lang/c++/build.sh
----------------------------------------------------------------------
diff --git a/lang/c++/build.sh b/lang/c++/build.sh
index 2c98885..c8281b4 100755
--- a/lang/c++/build.sh
+++ b/lang/c++/build.sh
@@ -83,7 +83,8 @@ case "$target" in
       && ./build/StreamTests \
       && ./build/SpecificTests \
       && ./build/AvrogencppTests \
-      && ./build/DataFileTests)
+      && ./build/DataFileTests   \
+      && ./build/SchemaTests)
     ;;
 
   dist)

http://git-wip-us.apache.org/repos/asf/avro/blob/1296ce92/lang/c++/impl/NodeImpl.cc
----------------------------------------------------------------------
diff --git a/lang/c++/impl/NodeImpl.cc b/lang/c++/impl/NodeImpl.cc
index aba2a73..606cd20 100644
--- a/lang/c++/impl/NodeImpl.cc
+++ b/lang/c++/impl/NodeImpl.cc
@@ -189,23 +189,22 @@ NodeRecord::printJson(std::ostream &os, int depth) const
     os << "{\n";
     os << indent(++depth) << "\"type\": \"record\",\n";
     printName(os, nameAttribute_.get(), depth);
-    os << indent(depth) << "\"fields\": [\n";
+    os << indent(depth) << "\"fields\": [";
 
     int fields = leafAttributes_.size();
     ++depth;
     for(int i = 0; i < fields; ++i) {
         if(i > 0) {
-            os << indent(depth) << "},\n";
+            os << ',';
         }
-        os << indent(depth) << "{\n";
+        os << '\n' << indent(depth) << "{\n";
         os << indent(++depth) << "\"name\": \"" << leafNameAttributes_.get(i) << "\",\n";
         os << indent(depth) << "\"type\": ";
         leafAttributes_.get(i)->printJson(os, depth);
         os << '\n';
-        --depth;
+        os << indent(--depth) << '}';
     }
-    os << indent(depth) << "}\n";
-    os << indent(--depth) << "]\n";
+    os << '\n' << indent(--depth) << "]\n";
     os << indent(--depth) << '}';
 }
 

http://git-wip-us.apache.org/repos/asf/avro/blob/1296ce92/lang/c++/test/SchemaTests.cc
----------------------------------------------------------------------
diff --git a/lang/c++/test/SchemaTests.cc b/lang/c++/test/SchemaTests.cc
index 7dce735..8ecde7a 100644
--- a/lang/c++/test/SchemaTests.cc
+++ b/lang/c++/test/SchemaTests.cc
@@ -23,7 +23,6 @@
 #include <boost/test/unit_test.hpp>
 #include <boost/test/parameterized_test.hpp>
 
-
 namespace avro {
 namespace schema {
 
@@ -48,6 +47,7 @@ const char* basicSchemas[] = {
     "{ \"type\": \"string\" }",
 
     // Record
+    "{\"type\": \"record\",\"name\": \"Test\",\"fields\": []}",
     "{\"type\": \"record\",\"name\": \"Test\",\"fields\": "
         "[{\"name\": \"f\",\"type\": \"long\"}]}",
     "{\"type\": \"record\",\"name\": \"Test\",\"fields\": "
@@ -136,6 +136,57 @@ const char* basicSchemaErrors[] = {
     "{\"type\": \"fixed\", \"size\": 314}",
 };
 
+const char* roundTripSchemas[] = {
+    "\"null\"",
+    "\"boolean\"",
+    "\"int\"",
+    "\"long\"",
+    "\"float\"",
+    "\"double\"",
+    "\"bytes\"",
+    "\"string\"",
+    // Record
+    "{\"type\":\"record\",\"name\":\"Test\",\"fields\":[]}",
+    "{\"type\":\"record\",\"name\":\"Test\",\"fields\":"
+        "[{\"name\":\"f\",\"type\":\"long\"}]}",
+    "{\"type\":\"record\",\"name\":\"Test\",\"fields\":"
+        "[{\"name\":\"f1\",\"type\":\"long\"},"
+        "{\"name\":\"f2\",\"type\":\"int\"}]}",
+/* Avro-C++ cannot do a round-trip on error schemas. 
+ * "{\"type\":\"error\",\"name\":\"Test\",\"fields\":"
+ *       "[{\"name\":\"f1\",\"type\":\"long\"},"
+ *       "{\"name\":\"f2\",\"type\":\"int\"}]}"
+ */
+    // Recursive.
+    "{\"type\":\"record\",\"name\":\"LongList\","
+        "\"fields\":[{\"name\":\"value\",\"type\":\"long\"},"
+        "{\"name\":\"next\",\"type\":[\"LongList\",\"null\"]}]}",
+    // Enum
+    "{\"type\":\"enum\",\"name\":\"Test\",\"symbols\":[\"A\",\"B\"]}",
+
+    // Array
+    "{\"type\":\"array\",\"items\":\"long\"}",
+    "{\"type\":\"array\",\"items\":{\"type\":\"enum\","
+        "\"name\":\"Test\",\"symbols\":[\"A\",\"B\"]}}",
+
+    // Map
+    "{\"type\":\"map\",\"values\":\"long\"}",
+    "{\"type\":\"map\",\"values\":{\"type\":\"enum\","
+        "\"name\":\"Test\",\"symbols\":[\"A\",\"B\"]}}",
+
+    // Union
+    "[\"string\",\"null\",\"long\"]",
+
+    // Fixed
+    "{\"type\":\"fixed\",\"name\":\"Test\",\"size\":1}",
+    "{\"type\":\"fixed\",\"namespace\":\"org.apache.hadoop.avro\","
+          "\"name\":\"MyFixed\",\"size\":1}",
+    "{\"type\":\"fixed\",\"name\":\"Test\",\"size\":1}",
+    "{\"type\":\"fixed\",\"name\":\"Test\",\"size\":1}"
+};
+
+
+
 static void testBasic(const char* schema)
 {
     BOOST_TEST_CHECKPOINT(schema);
@@ -154,6 +205,19 @@ static void testCompile(const char* schema)
     compileJsonSchemaFromString(std::string(schema));
 }
 
+// Test that the JSON output from a valid schema matches the JSON that was 
+// used to construct it, apart from whitespace changes.
+static void testRoundTrip(const char* schema)
+{
+    BOOST_TEST_CHECKPOINT(schema);
+    avro::ValidSchema compiledSchema = compileJsonSchemaFromString(std::string(schema));
+    std::ostringstream os;
+    compiledSchema.toJson(os);
+    std::string result = os.str();
+    result.erase(std::remove_if(result.begin(), result.end(), ::isspace), result.end()); // Remove whitespace
+    BOOST_CHECK(result == std::string(schema));
+}
+
 }
 }
 
@@ -173,6 +237,6 @@ init_unit_test_suite(int argc, char* argv[])
     ADD_PARAM_TEST(ts, avro::schema::testBasic_fail,
         avro::schema::basicSchemaErrors);
     ADD_PARAM_TEST(ts, avro::schema::testCompile, avro::schema::basicSchemas);
-
+    ADD_PARAM_TEST(ts, avro::schema::testRoundTrip, avro::schema::roundTripSchemas);
     return ts;
 }