blob: 6246bde6d3303d753caf0d6ea780503ca1ca3346 [file] [log] [blame]
// 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 Microsoft.Hadoop.Avro;
using Org.Apache.REEF.Examples.Tasks.HelloTask;
using Org.Apache.REEF.Tang.Examples;
using Org.Apache.REEF.Tang.Implementations.ClassHierarchy;
using Org.Apache.REEF.Tang.Implementations.ClassHierarchy.AvroDataContract;
using Org.Apache.REEF.Tang.Implementations.Tang;
using Org.Apache.REEF.Tang.Interface;
using Org.Apache.REEF.Tang.Types;
using Xunit;
namespace Org.Apache.REEF.Tang.Tests.ClassHierarchy
{
public class TestAvroSerialization
{
private AvroClassHierarchySerializer _serializer =
(AvroClassHierarchySerializer)TangFactory.GetTang().NewInjector().GetInstance<IClassHierarchySerializer>();
/// <summary>
/// This test is to convert an ClassHierarchy into AvroNode object, and then convert it back to an
/// AvroClassHierarchy.
/// </summary>
[Fact]
public void TestToFromAvroNode()
{
Type timerType = typeof(Timer);
Type secondType = typeof(Timer.Seconds);
Type simpleConstructorType = typeof(SimpleConstructors);
IClassHierarchy ns = TangFactory.GetTang().GetClassHierarchy(
new string[] { typeof(Timer).Assembly.GetName().Name, typeof(SimpleConstructors).Assembly.GetName().Name });
IClassNode timerClassNode = (IClassNode)ns.GetNode(timerType.AssemblyQualifiedName);
INode secondNode = ns.GetNode(secondType.AssemblyQualifiedName);
IClassNode simpleConstructorsClassNode = (IClassNode)ns.GetNode(simpleConstructorType.AssemblyQualifiedName);
AvroNode n = _serializer.ToAvroNode(ns);
IClassHierarchy ns2 = _serializer.FromAvroNode(n);
IClassNode timerClassNode2 = (IClassNode)ns2.GetNode(timerType.AssemblyQualifiedName);
INode secondNode2 = ns2.GetNode(secondType.AssemblyQualifiedName);
IClassNode simpleConstructorsClassNode2 = (IClassNode)ns2.GetNode(simpleConstructorType.AssemblyQualifiedName);
Assert.Equal(timerClassNode, timerClassNode2);
Assert.Equal(secondNode, secondNode2);
Assert.Equal(simpleConstructorsClassNode, simpleConstructorsClassNode2);
}
/// <summary>
/// This is to test AvroSerializer.Create<AvroNode>()
/// Manually changing return type from object into strong type like AvroClassNode in AvroNode class will result in GetSchema() fail.
/// I have manually synced all the IList into List in auto generated code. Otherwise AvroSerializer.Create<AvroNode>() will throw the following error
/// "Could not find any matching known type for 'System.Collections.Generic.IList`1[Org.Apache.REEF.Tang.Implementations.ClassHierarchy.AvroDataContract.AvroConstructorDef]'."
/// </summary>
[Fact]
public void TestGetSchema()
{
var serializer = AvroSerializer.Create<AvroNode>();
var s = serializer.WriterSchema.ToString();
Assert.NotNull(s);
}
/// <summary>
/// This test is to merge two AvroClassHierarchies
/// </summary>
[Fact]
public void TestAvroClassHierarchyMerge()
{
IClassHierarchy ns = TangFactory.GetTang().GetClassHierarchy(
new string[] { typeof(Timer).Assembly.GetName().Name });
IClassNode timerClassNode = (IClassNode)ns.GetNode(typeof(Timer).AssemblyQualifiedName);
AvroNode n = _serializer.ToAvroNode(ns);
IClassHierarchy ns2 = _serializer.FromAvroNode(n);
IClassHierarchy ns3 = TangFactory.GetTang().GetClassHierarchy(
new string[] { typeof(AvroNode).Assembly.GetName().Name });
IClassNode avroNodeClassNode = (IClassNode)ns3.GetNode(typeof(AvroNode).AssemblyQualifiedName);
AvroNode n2 = _serializer.ToAvroNode(ns3);
IClassHierarchy ns4 = _serializer.FromAvroNode(n2);
var ns5 = ns2.Merge(ns4);
IClassNode timerClassNode2 = (IClassNode)ns5.GetNode(typeof(Timer).AssemblyQualifiedName);
IClassNode avroNodeClassNode2 = (IClassNode)ns5.GetNode(typeof(AvroNode).AssemblyQualifiedName);
Assert.Equal(timerClassNode, timerClassNode2);
Assert.Equal(avroNodeClassNode, avroNodeClassNode2);
}
/// <summary>
/// Test serialize a class hierarchy into a test file
/// </summary>
[Fact]
public void TestToTextFileForTask()
{
IClassHierarchy ns = TangFactory.GetTang().GetClassHierarchy(new string[] { typeof(HelloTask).Assembly.GetName().Name });
_serializer.ToTextFile(ns, "avroTask.bin");
Assert.True(File.Exists("avroTask.bin"));
}
/// <summary>
/// Test serialize a class hierarchy into a JSon string
/// </summary>
[Fact]
public void TestToString()
{
IClassHierarchy ns = TangFactory.GetTang().GetClassHierarchy(new string[] { typeof(HelloTask).Assembly.GetName().Name });
string s = _serializer.ToString(ns);
Assert.NotNull(s);
}
/// <summary>
/// Test serialize a class hierarchy to a Json string then deserialize it
/// In deserialization, in ParseSubHierarchy(), exception is thrown:
/// Unable to cast object of type 'Newtonsoft.Json.Linq.JObject' to type 'Org.Apache.REEF.Tang.Implementations.ClassHierarchy.AvroDataContract.AvroClassNode'.
/// This is because auto generated code use object as return type instead of AvroClassNode
/// </summary>
[Fact(Skip = "TODO: after Avro fix the issue, enable the test")]
public void TestToFromJsonString()
{
Type timerType = typeof(Timer);
Type secondType = typeof(Timer.Seconds);
Type simpleConstructorType = typeof(SimpleConstructors);
IClassHierarchy ns = TangFactory.GetTang().GetClassHierarchy(
new string[] { typeof(Timer).Assembly.GetName().Name, typeof(SimpleConstructors).Assembly.GetName().Name });
IClassNode timerClassNode = (IClassNode)ns.GetNode(timerType.AssemblyQualifiedName);
INode secondNode = ns.GetNode(secondType.AssemblyQualifiedName);
IClassNode simpleConstructorsClassNode = (IClassNode)ns.GetNode(simpleConstructorType.AssemblyQualifiedName);
string s = _serializer.ToString(ns);
IClassHierarchy ns2 = _serializer.FromString(s);
IClassNode timerClassNode2 = (IClassNode)ns2.GetNode(timerType.AssemblyQualifiedName);
INode secondNode2 = ns2.GetNode(secondType.AssemblyQualifiedName);
IClassNode simpleConstructorsClassNode2 = (IClassNode)ns2.GetNode(simpleConstructorType.AssemblyQualifiedName);
Assert.Equal(timerClassNode, timerClassNode2);
Assert.Equal(secondNode, secondNode2);
Assert.Equal(simpleConstructorsClassNode, simpleConstructorsClassNode2);
}
/// <summary>
/// Test serialize a class hierarchy to a text file then deserialize it
/// In deserialization, in ParseSubHierarchy(), exception is thrown:
/// Unable to cast object of type 'Newtonsoft.Json.Linq.JObject' to type 'Org.Apache.REEF.Tang.Implementations.ClassHierarchy.AvroDataContract.AvroClassNode'.
/// This is because auto generated code use object as return type instead of AvroClassNode
/// </summary>
[Fact(Skip = "TODO: after Avro fix the issue, enable the test")]
public void TestToFromTextFile()
{
Type timerType = typeof(Timer);
Type secondType = typeof(Timer.Seconds);
Type simpleConstructorType = typeof(SimpleConstructors);
IClassHierarchy ns = TangFactory.GetTang().GetClassHierarchy(
new string[] { typeof(Timer).Assembly.GetName().Name, typeof(SimpleConstructors).Assembly.GetName().Name });
IClassNode timerClassNode = (IClassNode)ns.GetNode(timerType.AssemblyQualifiedName);
INode secondNode = ns.GetNode(secondType.AssemblyQualifiedName);
IClassNode simpleConstructorsClassNode = (IClassNode)ns.GetNode(simpleConstructorType.AssemblyQualifiedName);
_serializer.ToTextFile(ns, "avroEven.txt");
IClassHierarchy ns2 = _serializer.FromTextFile("avroEven.txt");
IClassNode timerClassNode2 = (IClassNode)ns2.GetNode(timerType.AssemblyQualifiedName);
INode secondNode2 = ns2.GetNode(secondType.AssemblyQualifiedName);
IClassNode simpleConstructorsClassNode2 = (IClassNode)ns2.GetNode(simpleConstructorType.AssemblyQualifiedName);
Assert.Equal(timerClassNode, timerClassNode2);
Assert.Equal(secondNode, secondNode2);
Assert.Equal(simpleConstructorsClassNode, simpleConstructorsClassNode2);
}
/// <summary>
/// Test serialize a class hierarchy to a file and deserialize from the file
/// Currently, in ToFile() method, writer.Write(avroNodeData) throw exception "Value cannot be null.\r\nParameter name: value".
/// </summary>
[Fact(Skip = "TODO: after Avro fix the issue, enable the test")]
public void TestToFromFile()
{
Type timerType = typeof(Timer);
Type secondType = typeof(Timer.Seconds);
Type simpleConstructorType = typeof(SimpleConstructors);
IClassHierarchy ns = TangFactory.GetTang().GetClassHierarchy(
new string[] { typeof(Timer).Assembly.GetName().Name, typeof(SimpleConstructors).Assembly.GetName().Name });
IClassNode timerClassNode = (IClassNode)ns.GetNode(timerType.AssemblyQualifiedName);
INode secondNode = ns.GetNode(secondType.AssemblyQualifiedName);
IClassNode simpleConstructorsClassNode = (IClassNode)ns.GetNode(simpleConstructorType.AssemblyQualifiedName);
_serializer.ToFile(ns, "avroEven.bin");
IClassHierarchy ns2 = _serializer.FromFile("avroEven.bin");
IClassNode timerClassNode2 = (IClassNode)ns2.GetNode(timerType.AssemblyQualifiedName);
INode secondNode2 = ns2.GetNode(secondType.AssemblyQualifiedName);
IClassNode simpleConstructorsClassNode2 = (IClassNode)ns2.GetNode(simpleConstructorType.AssemblyQualifiedName);
Assert.Equal(timerClassNode, timerClassNode2);
Assert.Equal(secondNode, secondNode2);
Assert.Equal(simpleConstructorsClassNode, simpleConstructorsClassNode2);
}
/// <summary>
/// Test serialize class hierarchy to byte array and deserializa back to class hierarchy
/// AvroSerializer.Serialize(stream, obj) doesn't allow any null values in the obj to be serialized even if it is nullable
/// </summary>
[Fact(Skip = "TODO: after Avro fix the issue, enable the test")]
public void TestToFromByteArray()
{
Type timerType = typeof(Timer);
Type secondType = typeof(Timer.Seconds);
Type simpleConstructorType = typeof(SimpleConstructors);
IClassHierarchy ns = TangFactory.GetTang().GetClassHierarchy(
new string[] { typeof(Timer).Assembly.GetName().Name, typeof(SimpleConstructors).Assembly.GetName().Name });
IClassNode timerClassNode = (IClassNode)ns.GetNode(timerType.AssemblyQualifiedName);
INode secondNode = ns.GetNode(secondType.AssemblyQualifiedName);
IClassNode simpleConstructorsClassNode = (IClassNode)ns.GetNode(simpleConstructorType.AssemblyQualifiedName);
byte[] b = _serializer.ToByteArray(ns);
IClassHierarchy ns2 = _serializer.FromByteArray(b);
IClassNode timerClassNode2 = (IClassNode)ns2.GetNode(timerType.AssemblyQualifiedName);
INode secondNode2 = ns2.GetNode(secondType.AssemblyQualifiedName);
IClassNode simpleConstructorsClassNode2 = (IClassNode)ns2.GetNode(simpleConstructorType.AssemblyQualifiedName);
Assert.Equal(timerClassNode, timerClassNode2);
Assert.Equal(secondNode, secondNode2);
Assert.Equal(simpleConstructorsClassNode, simpleConstructorsClassNode2);
}
}
}