Added: avro/trunk/lang/csharp/src/apache/test/Schema/SchemaTests.cs URL: http://svn.apache.org/viewvc/avro/trunk/lang/csharp/src/apache/test/Schema/SchemaTests.cs?rev=1087439&view=auto ============================================================================== --- avro/trunk/lang/csharp/src/apache/test/Schema/SchemaTests.cs (added) +++ avro/trunk/lang/csharp/src/apache/test/Schema/SchemaTests.cs Thu Mar 31 21:16:28 2011 @@ -0,0 +1,276 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +using System; +using System.Collections.Generic; +using System.Text; +using NUnit.Framework; +using Avro; + +namespace Avro.Test +{ + [TestFixture] + public class SchemaTests + { + // Primitive types - shorthand + [TestCase("null")] + [TestCase("boolean")] + [TestCase("int")] + [TestCase("long")] + [TestCase("float")] + [TestCase("double")] + [TestCase("bytes")] + [TestCase("string")] + + [TestCase("\"null\"")] + [TestCase("\"boolean\"")] + [TestCase("\"int\"")] + [TestCase("\"long\"")] + [TestCase("\"float\"")] + [TestCase("\"double\"")] + [TestCase("\"bytes\"")] + [TestCase("\"string\"")] + + // Primitive types - longer + [TestCase("{ \"type\": \"null\" }")] + [TestCase("{ \"type\": \"boolean\" }")] + [TestCase("{ \"type\": \"int\" }")] + [TestCase("{ \"type\": \"long\" }")] + [TestCase("{ \"type\": \"float\" }")] + [TestCase("{ \"type\": \"double\" }")] + [TestCase("{ \"type\": \"bytes\" }")] + [TestCase("{ \"type\": \"string\" }")] + // Record + [TestCase("{\"type\": \"record\",\"name\": \"Test\",\"fields\": [{\"name\": \"f\",\"type\": \"long\"}]}")] + [TestCase("{\"type\": \"record\",\"name\": \"Test\",\"fields\": " + + "[{\"name\": \"f1\",\"type\": \"long\"},{\"name\": \"f2\", \"type\": \"int\"}]}")] + [TestCase("{\"type\": \"error\",\"name\": \"Test\",\"fields\": " + + "[{\"name\": \"f1\",\"type\": \"long\"},{\"name\": \"f2\", \"type\": \"int\"}]}")] + [TestCase("{\"type\":\"record\",\"name\":\"LongList\"," + + "\"fields\":[{\"name\":\"value\",\"type\":\"long\"},{\"name\":\"next\",\"type\":[\"LongList\",\"null\"]}]}")] // Recursive. + [TestCase("{\"type\":\"record\",\"name\":\"LongList\"," + + "\"fields\":[{\"name\":\"value\",\"type\":\"long\"},{\"name\":\"next\",\"type\":[\"LongListA\",\"null\"]}]}", + Description = "Unknown name", ExpectedException = typeof(SchemaParseException))] + [TestCase("{\"type\":\"record\",\"name\":\"LongList\"}", + Description = "No fields", ExpectedException = typeof(SchemaParseException))] + [TestCase("{\"type\":\"record\",\"name\":\"LongList\", \"fields\": \"hi\"}", + Description = "Fields not an array", ExpectedException = typeof(SchemaParseException))] + + // Enum + [TestCase("{\"type\": \"enum\", \"name\": \"Test\", \"symbols\": [\"A\", \"B\"]}")] + [TestCase("{\"type\": \"enum\", \"name\": \"Status\", \"symbols\": \"Normal Caution Critical\"}", + Description = "Symbols not an array", ExpectedException = typeof(SchemaParseException))] + [TestCase("{\"type\": \"enum\", \"name\": [ 0, 1, 1, 2, 3, 5, 8 ], \"symbols\": [\"Golden\", \"Mean\"]}", + Description = "Name not a string", ExpectedException = typeof(SchemaParseException))] + [TestCase("{\"type\": \"enum\", \"symbols\" : [\"I\", \"will\", \"fail\", \"no\", \"name\"]}", + Description = "No name", ExpectedException = typeof(SchemaParseException))] + [TestCase("{\"type\": \"enum\", \"name\": \"Test\", \"symbols\" : [\"AA\", \"AA\"]}", + Description = "Duplicate symbol", ExpectedException = typeof(SchemaParseException))] + + // Array + [TestCase("{\"type\": \"array\", \"items\": \"long\"}")] + [TestCase("{\"type\": \"array\",\"items\": {\"type\": \"enum\", \"name\": \"Test\", \"symbols\": [\"A\", \"B\"]}}")] + + // Map + [TestCase("{\"type\": \"map\", \"values\": \"long\"}")] + [TestCase("{\"type\": \"map\",\"values\": {\"type\": \"enum\", \"name\": \"Test\", \"symbols\": [\"A\", \"B\"]}}")] + + // Union + [TestCase("[\"string\", \"null\", \"long\"]")] + [TestCase("[\"string\", \"long\", \"long\"]", + Description = "Duplicate type", ExpectedException = typeof(SchemaParseException))] + [TestCase("[{\"type\": \"array\", \"items\": \"long\"}, {\"type\": \"array\", \"items\": \"string\"}]", + Description = "Duplicate type", ExpectedException = typeof(SchemaParseException))] + [TestCase("{\"type\":[\"string\", \"null\", \"long\"]}")] + + // Fixed + [TestCase("{ \"type\": \"fixed\", \"name\": \"Test\", \"size\": 1}")] + [TestCase("{\"type\": \"fixed\", \"name\": \"MyFixed\", \"namespace\": \"org.apache.hadoop.avro\", \"size\": 1}")] + [TestCase("{ \"type\": \"fixed\", \"name\": \"Test\", \"size\": 1}")] + [TestCase("{ \"type\": \"fixed\", \"name\": \"Test\", \"size\": 1}")] + [TestCase("{\"type\": \"fixed\", \"name\": \"Missing size\"}", ExpectedException = typeof(SchemaParseException))] + [TestCase("{\"type\": \"fixed\", \"size\": 314}", + Description = "No name", ExpectedException = typeof(SchemaParseException))] + public void TestBasic(string s) + { + Schema.Parse(s); + } + + [TestCase("null", Schema.Type.Null)] + [TestCase("boolean", Schema.Type.Boolean)] + [TestCase("int", Schema.Type.Int)] + [TestCase("long", Schema.Type.Long)] + [TestCase("float", Schema.Type.Float)] + [TestCase("double", Schema.Type.Double)] + [TestCase("bytes", Schema.Type.Bytes)] + [TestCase("string", Schema.Type.String)] + + [TestCase("{ \"type\": \"null\" }", Schema.Type.Null)] + [TestCase("{ \"type\": \"boolean\" }", Schema.Type.Boolean)] + [TestCase("{ \"type\": \"int\" }", Schema.Type.Int)] + [TestCase("{ \"type\": \"long\" }", Schema.Type.Long)] + [TestCase("{ \"type\": \"float\" }", Schema.Type.Float)] + [TestCase("{ \"type\": \"double\" }", Schema.Type.Double)] + [TestCase("{ \"type\": \"bytes\" }", Schema.Type.Bytes)] + [TestCase("{ \"type\": \"string\" }", Schema.Type.String)] + public void TestPrimitive(string s, Schema.Type type) + { + Schema sc = Schema.Parse(s); + Assert.IsTrue(sc is PrimitiveSchema); + Assert.AreEqual(type, sc.Tag); + + testEquality(s, sc); + testToString(sc); + } + + private static void testEquality(string s, Schema sc) + { + Assert.IsTrue(sc.Equals(sc)); + Schema sc2 = Schema.Parse(s); + Assert.IsTrue(sc.Equals(sc2)); + Assert.AreEqual(sc.GetHashCode(), sc2.GetHashCode()); + } + + private static void testToString(Schema sc) + { + try + { + Assert.AreEqual(sc, Schema.Parse(sc.ToString())); + } + catch (Exception e) + { + throw new AvroException(e.ToString() + ": " + sc.ToString()); + } + } + + [TestCase("{\"type\":\"record\",\"name\":\"LongList\"," + + "\"fields\":[{\"name\":\"f1\",\"type\":\"long\"}," + + "{\"name\":\"f2\",\"type\": \"int\"}]}", + new string[] { "f1", "long", "100", "f2", "int", "10" })] + [TestCase("{\"type\":\"record\",\"name\":\"LongList\"," + + "\"fields\":[{\"name\":\"f1\",\"type\":\"long\", \"default\": \"100\"}," + + "{\"name\":\"f2\",\"type\": \"int\"}]}", + new string[] { "f1", "long", "100", "f2", "int", "10" })] + [TestCase("{\"type\":\"record\",\"name\":\"LongList\"," + + "\"fields\":[{\"name\":\"value\",\"type\":\"long\", \"default\": \"100\"}," + + "{\"name\":\"next\",\"type\":[\"LongList\",\"null\"]}]}", + new string[] { "value", "long", "100", "next", "union", null })] + public void TestRecord(string s, string[] kv) + { + Schema sc = Schema.Parse(s); + Assert.AreEqual(Schema.Type.Record, sc.Tag); + RecordSchema rs = sc as RecordSchema; + Assert.AreEqual(kv.Length / 3, rs.Count); + for (int i = 0; i < kv.Length; i += 3) + { + Field f = rs[kv[i]]; + Assert.AreEqual(kv[i + 1], f.Schema.Name); + /* + if (kv[i + 2] != null) + { + Assert.IsNotNull(f.DefaultValue); + Assert.AreEqual(kv[i + 2], f.DefaultValue); + } + else + { + Assert.IsNull(f.DefaultValue); + } + */ + } + testEquality(s, sc); + testToString(sc); + } + + [TestCase("{\"type\": \"enum\", \"name\": \"Test\", \"symbols\": [\"A\", \"B\"]}", + new string[] { "A", "B" })] + public void TestEnum(string s, string[] symbols) + { + Schema sc = Schema.Parse(s); + Assert.AreEqual(Schema.Type.Enumeration, sc.Tag); + EnumSchema es = sc as EnumSchema; + Assert.AreEqual(symbols.Length, es.Count); + + int i = 0; + foreach (String str in es) + { + Assert.AreEqual(symbols[i++], str); + } + + testEquality(s, sc); + testToString(sc); + } + + [TestCase("{\"type\": \"array\", \"items\": \"long\"}", "long")] + public void TestArray(string s, string item) + { + Schema sc = Schema.Parse(s); + Assert.AreEqual(Schema.Type.Array, sc.Tag); + ArraySchema ars = sc as ArraySchema; + Assert.AreEqual(item, ars.ItemSchema.Name); + + testEquality(s, sc); + testToString(sc); + } + + [TestCase("{\"type\": \"map\", \"values\": \"long\"}", "long")] + public void TestMap(string s, string value) + { + Schema sc = Schema.Parse(s); + Assert.AreEqual(Schema.Type.Map, sc.Tag); + MapSchema ms = sc as MapSchema; + Assert.AreEqual(value, ms.ValueSchema.Name); + + testEquality(s, sc); + testToString(sc); + } + + [TestCase("[\"string\", \"null\", \"long\"]", new string[] { "string", "null", "long" })] + public void TestUnion(string s, string[] types) + { + Schema sc = Schema.Parse(s); + Assert.AreEqual(Schema.Type.Union, sc.Tag); + UnionSchema us = sc as UnionSchema; + Assert.AreEqual(types.Length, us.Count); + + for (int i = 0; i < us.Count; i++) + { + Assert.AreEqual(types[i], us[i].Name); + } + testEquality(s, sc); + testToString(sc); + } + + [TestCase("{ \"type\": \"fixed\", \"name\": \"Test\", \"size\": 1}", 1)] + public void TestFixed(string s, int size) + { + Schema sc = Schema.Parse(s); + Assert.AreEqual(Schema.Type.Fixed, sc.Tag); + FixedSchema fs = sc as FixedSchema; + Assert.AreEqual(size, fs.Size); + testEquality(s, sc); + testToString(sc); + } + + [TestCase("a", "o.a.h", Result = "o.a.h.a")] + public string testFullname(string s1, string s2) + { + var name = new SchemaName(s1, s2, null); + return name.Fullname; + } + + } +}
Added: avro/trunk/lang/csharp/src/apache/test/Specific/SpecificTests.cs URL: http://svn.apache.org/viewvc/avro/trunk/lang/csharp/src/apache/test/Specific/SpecificTests.cs?rev=1087439&view=auto ============================================================================== --- avro/trunk/lang/csharp/src/apache/test/Specific/SpecificTests.cs (added) +++ avro/trunk/lang/csharp/src/apache/test/Specific/SpecificTests.cs Thu Mar 31 21:16:28 2011 @@ -0,0 +1,186 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +using System; +using System.IO; +using System.Collections.Generic; +using NUnit.Framework; +using Avro; +using Avro.Generic; +using Avro.IO; +using System.CodeDom; +using System.CodeDom.Compiler; +using Microsoft.CSharp; +using Avro.Specific; +using System.Reflection; + +namespace Avro.Test +{ + [TestFixture] + class SpecificTests + { + [TestCase(@"{ + ""protocol"" : ""MyProtocol"", + ""namespace"" : ""com.foo"", + ""types"" : [ + { + ""type"" : ""record"", + ""name"" : ""A"", + ""fields"" : [ { ""name"" : ""f1"", ""type"" : ""long"" } ] + }, + { + ""type"" : ""enum"", + ""name"" : ""MyEnum"", + ""symbols"" : [ ""A"", ""B"", ""C"" ] + }, + { + ""type"": ""fixed"", + ""size"": 16, + ""name"": ""MyFixed"" + }, + { + ""type"" : ""record"", + ""name"" : ""Z"", + ""fields"" : + [ + { ""name"" : ""myUInt"", ""type"" : [ ""int"", ""null"" ] }, + { ""name"" : ""myULong"", ""type"" : [ ""long"", ""null"" ] }, + { ""name"" : ""myUBool"", ""type"" : [ ""boolean"", ""null"" ] }, + { ""name"" : ""myUDouble"", ""type"" : [ ""double"", ""null"" ] }, + { ""name"" : ""myUFloat"", ""type"" : [ ""float"", ""null"" ] }, + { ""name"" : ""myUBytes"", ""type"" : [ ""bytes"", ""null"" ] }, + { ""name"" : ""myUString"", ""type"" : [ ""string"", ""null"" ] }, + + { ""name"" : ""myInt"", ""type"" : ""int"" }, + { ""name"" : ""myLong"", ""type"" : ""long"" }, + { ""name"" : ""myBool"", ""type"" : ""boolean"" }, + { ""name"" : ""myDouble"", ""type"" : ""double"" }, + { ""name"" : ""myFloat"", ""type"" : ""float"" }, + { ""name"" : ""myBytes"", ""type"" : ""bytes"" }, + { ""name"" : ""myString"", ""type"" : ""string"" }, + { ""name"" : ""myNull"", ""type"" : ""null"" }, + + { ""name"" : ""myFixed"", ""type"" : ""MyFixed"" }, + { ""name"" : ""myA"", ""type"" : ""A"" }, + { ""name"" : ""myE"", ""type"" : ""MyEnum"" }, + { ""name"" : ""myArray"", ""type"" : { ""type"" : ""array"", ""items"" : ""bytes"" } }, + { ""name"" : ""myArray2"", ""type"" : { ""type"" : ""array"", ""items"" : { ""type"" : ""record"", ""name"" : ""newRec"", ""fields"" : [ { ""name"" : ""f1"", ""type"" : ""long""} ] } } }, + { ""name"" : ""myMap"", ""type"" : { ""type"" : ""map"", ""values"" : ""string"" } }, + { ""name"" : ""myMap2"", ""type"" : { ""type"" : ""map"", ""values"" : ""newRec"" } }, + { ""name"" : ""myObject"", ""type"" : [ ""MyEnum"", ""A"", ""null"" ] } + ] + } + ] +}" +, new object[] {3, // index of the schema to serialize + "com.foo.Z", // name of the schema to serialize +@" + Console.WriteLine(""Constructing com.foo.Z...""); + string bytes = ""bytes sample text""; + System.Text.UTF8Encoding encoding = new System.Text.UTF8Encoding(); + + myUInt=1; + myULong=2; + myUBool=true; + myUDouble=(double)3; + myUFloat=(float)4.5; + myUBytes = encoding.GetBytes(bytes); + myUString=""Hello""; + + myInt=1; + myLong=2; + myBool=true; + myDouble=(double)3; + myFloat=(float)4.5; + myBytes=encoding.GetBytes(bytes); + myString=""Hello""; + myNull=null; + + string fixedstr = ""My fixed record0""; + myFixed=new MyFixed(); myFixed.Value = encoding.GetBytes(fixedstr); + myA=new A(); myA.f1 = 10; + myE=com.foo.MyEnum.C; + + myArray=new List<byte[]>(); + myArray.Add(encoding.GetBytes(""a"")); + + myArray2 = new List<com.foo.newRec>(); + com.foo.newRec rec = new com.foo.newRec(); + rec.f1 = 50; + myArray2.Add(rec); + + myMap = new Dictionary<string, string>(); + myMap.Add(""key"", ""value""); + myMap2 = new Dictionary<string, com.foo.newRec>(); + com.foo.newRec newrec = new com.foo.newRec(); + newrec.f1 = 1200; + myMap2.Add(""A"", newrec); + myObject = com.foo.MyEnum.B; +"} +)] + public static void TestSpecific(string str, object[] result) + { + Protocol protocol = Protocol.Parse(str); + var codegen = new CodeGen(); + codegen.AddProtocol(protocol); + var compileUnit = codegen.GenerateCode(); + + // add a constructor to the main class using the passed assignment statements + CodeTypeDeclaration ctd = compileUnit.Namespaces[0].Types[(int)result[0]]; + CodeConstructor constructor = new CodeConstructor(); + constructor.Attributes = MemberAttributes.Public; + CodeSnippetExpression snippet = new CodeSnippetExpression((string)result[2]); + constructor.Statements.Add(snippet); + ctd.Members.Add(constructor); + + // compile + var comparam = new CompilerParameters(new string[] { "mscorlib.dll" }); + comparam.ReferencedAssemblies.Add("System.dll"); + comparam.ReferencedAssemblies.Add("System.Core.dll"); + comparam.ReferencedAssemblies.Add(Type.GetType("Mono.Runtime") != null ? "Mono.CSharp.dll" : "Microsoft.CSharp.dll"); + comparam.ReferencedAssemblies.Add("Avro.dll"); + comparam.GenerateInMemory = true; + var ccp = new Microsoft.CSharp.CSharpCodeProvider(); + var units = new CodeCompileUnit[] { compileUnit }; + var compres = ccp.CompileAssemblyFromDom(comparam, units); + if (compres == null || compres.Errors.Count > 0) + { + for (int i = 0; i < compres.Errors.Count; i++) + Console.WriteLine(compres.Errors[i]); + } + if (null != compres) + Assert.IsTrue(compres.Errors.Count == 0); + + // create record + SpecificRecord rec = compres.CompiledAssembly.CreateInstance((string)result[1]) as SpecificRecord; + Assert.IsFalse(rec == null); + + // serialize + var stream = new MemoryStream(); + var binEncoder = new BinaryEncoder(stream); + var writer = new SpecificDefaultWriter(rec.Schema); + writer.Write(rec.Schema, rec, binEncoder); + + // deserialize + stream.Position = 0; + var decoder = new BinaryDecoder(stream); + var reader = new SpecificDefaultReader(rec.Schema, rec.Schema); + var rec2 = (SpecificRecord)reader.Read(null, rec.Schema, rec.Schema, decoder); + Assert.IsFalse(rec2 == null); + } + } +} Modified: avro/trunk/share/rat-excludes.txt URL: http://svn.apache.org/viewvc/avro/trunk/share/rat-excludes.txt?rev=1087439&r1=1087438&r2=1087439&view=diff ============================================================================== --- avro/trunk/share/rat-excludes.txt (original) +++ avro/trunk/share/rat-excludes.txt Thu Mar 31 21:16:28 2011 @@ -32,6 +32,8 @@ lang/c/jansson/** lang/c/src/queue.h lang/c/src/st.h lang/c/src/st.c +lang/csharp/Avro.sln +lang/csharp/Avro.nunit lang/java/ipc/src/main/java/org/apache/avro/ipc/stats/static/*.js lang/java/ipc/src/main/java/org/apache/avro/ipc/stats/static/*.css share/test/data/test.avro12
