From 27bfcc5e1a7a3aacd828475c1996e114e34055d2 Mon Sep 17 00:00:00 2001 From: csharptest Date: Thu, 2 Jun 2011 12:04:06 -0500 Subject: Slight refactoring of Extensions to support lookup by name, added compatibility tests for text and binary formats. --- src/ProtoGen/FieldGeneratorBase.cs | 2 +- .../CompatTests/BinaryCompatibilityTests.cs | 22 + .../CompatTests/CompatibilityTests.cs | 172 + .../CompatTests/TestResources.Designer.cs | 77 + .../CompatTests/TestResources.resx | 127 + .../CompatTests/TextCompatibilityTests.cs | 60 + .../CompatTests/google_message1.dat | Bin 0 -> 228 bytes .../CompatTests/google_message2.dat | Bin 0 -> 84570 bytes .../ProtocolBuffers.Test.csproj | 22 + .../TestProtos/UnitTestGoogleSizeProtoFile.cs | 4178 +++++++++++++ .../TestProtos/UnitTestGoogleSpeedProtoFile.cs | 6131 ++++++++++++++++++++ .../UnitTestXmlSerializerTestProtoFile.cs | 1680 ++++++ src/ProtocolBuffers.Test/TextFormatTest.cs | 4 +- src/ProtocolBuffers.sln | 312 +- src/ProtocolBuffers/ByteString.cs | 7 +- src/ProtocolBuffers/ExtensionInfo.cs | 2 +- src/ProtocolBuffers/ExtensionRegistry.cs | 57 +- src/ProtocolBuffers/ExtensionRegistryLite.cs | 57 +- src/ProtocolBuffers/FieldSet.cs | 1 + src/ProtocolBuffers/GeneratedExtensionLite.cs | 12 + src/ProtocolBuffers/TextFormat.cs | 14 +- src/ProtocolBuffers/WireFormat.cs | 6 +- src/ProtocolBuffers2008.sln | 22 +- .../TestProtos/UnitTestExtrasLiteProtoFile.cs | 42 +- 24 files changed, 12760 insertions(+), 247 deletions(-) create mode 100644 src/ProtocolBuffers.Test/CompatTests/BinaryCompatibilityTests.cs create mode 100644 src/ProtocolBuffers.Test/CompatTests/CompatibilityTests.cs create mode 100644 src/ProtocolBuffers.Test/CompatTests/TestResources.Designer.cs create mode 100644 src/ProtocolBuffers.Test/CompatTests/TestResources.resx create mode 100644 src/ProtocolBuffers.Test/CompatTests/TextCompatibilityTests.cs create mode 100644 src/ProtocolBuffers.Test/CompatTests/google_message1.dat create mode 100644 src/ProtocolBuffers.Test/CompatTests/google_message2.dat create mode 100644 src/ProtocolBuffers.Test/TestProtos/UnitTestGoogleSizeProtoFile.cs create mode 100644 src/ProtocolBuffers.Test/TestProtos/UnitTestGoogleSpeedProtoFile.cs create mode 100644 src/ProtocolBuffers.Test/TestProtos/UnitTestXmlSerializerTestProtoFile.cs (limited to 'src') diff --git a/src/ProtoGen/FieldGeneratorBase.cs b/src/ProtoGen/FieldGeneratorBase.cs index c4f5dbf4..4d2ec438 100644 --- a/src/ProtoGen/FieldGeneratorBase.cs +++ b/src/ProtoGen/FieldGeneratorBase.cs @@ -133,7 +133,7 @@ namespace Google.ProtocolBuffers.ProtoGen } if (UseLiteRuntime && Descriptor.DefaultValue is ByteString) { - string temp = Convert.ToBase64String(((ByteString) Descriptor.DefaultValue).ToByteArray()); + string temp = (((ByteString) Descriptor.DefaultValue).ToBase64()); return String.Format("ByteString.FromBase64(\"{0}\")", temp); } return string.Format("(pb::ByteString) {0}.Descriptor.Fields[{1}].DefaultValue", diff --git a/src/ProtocolBuffers.Test/CompatTests/BinaryCompatibilityTests.cs b/src/ProtocolBuffers.Test/CompatTests/BinaryCompatibilityTests.cs new file mode 100644 index 00000000..fe8a1e37 --- /dev/null +++ b/src/ProtocolBuffers.Test/CompatTests/BinaryCompatibilityTests.cs @@ -0,0 +1,22 @@ +using System; +using NUnit.Framework; + +namespace Google.ProtocolBuffers.CompatTests +{ + [TestFixture] + public class BinaryCompatibilityTests : CompatibilityTests + { + protected override string TestName { get { return "binary"; } } + + protected override object SerializeMessage(TMessage message) + { + byte[] bresult = message.ToByteArray(); + return bresult; + } + + protected override TBuilder DeerializeMessage(object message, TBuilder builder, ExtensionRegistry registry) + { + return builder.MergeFrom((byte[])message, registry); + } + } +} \ No newline at end of file diff --git a/src/ProtocolBuffers.Test/CompatTests/CompatibilityTests.cs b/src/ProtocolBuffers.Test/CompatTests/CompatibilityTests.cs new file mode 100644 index 00000000..e74f2b08 --- /dev/null +++ b/src/ProtocolBuffers.Test/CompatTests/CompatibilityTests.cs @@ -0,0 +1,172 @@ +using System; +using Google.ProtocolBuffers.TestProtos; +using NUnit.Framework; + +namespace Google.ProtocolBuffers.CompatTests +{ + public abstract class CompatibilityTests + { + protected abstract string TestName { get; } + protected abstract object SerializeMessage(TMessage message) + where TMessage : IMessageLite + where TBuilder : IBuilderLite; + + protected abstract TBuilder DeerializeMessage(object message, TBuilder builder, ExtensionRegistry registry) + where TMessage : IMessageLite + where TBuilder : IBuilderLite; + + #region RunBenchmark + + protected void RunBenchmark(byte[] buffer, bool write) + where TMessage : IMessageLite + where TBuilder : IBuilderLite, new() + { + TBuilder builder = new TBuilder(); + TMessage message = new TBuilder().MergeFrom(buffer).Build(); + System.Diagnostics.Stopwatch watch = new System.Diagnostics.Stopwatch(); + //simple warm-up + object content = SerializeMessage(message); + Assert.AreEqual(message, DeerializeMessage(content, new TBuilder(), ExtensionRegistry.Empty).Build()); + //timming + long time = 0, sample = 1; + while (time < 100) + { + sample *= 10; + watch.Reset(); + watch.Start(); + if (write) + { + for (int i = 0; i < sample; i++) + SerializeMessage(message); + } + else + { + for (int i = 0; i < sample; i++) + DeerializeMessage(content, builder, ExtensionRegistry.Empty); + } + watch.Stop(); + time = watch.ElapsedMilliseconds; + } + + ulong rounds = (ulong)((100.0 / watch.ElapsedMilliseconds) * sample); + //test + watch.Reset(); + watch.Start(); + + if (write) + { + for (ulong i = 0; i < rounds; i++) + SerializeMessage(message); + } + else + { + for (ulong i = 0; i < rounds; i++) + DeerializeMessage(content, builder, ExtensionRegistry.Empty); + } + + watch.Stop(); + System.Diagnostics.Trace.TraceInformation( + "\r\n{0} {4} {5} {3:n0} rps ({1:n0} rounds in {2:n0} ms)", typeof(TMessage).Name, rounds, + watch.ElapsedMilliseconds, (1000.0 / watch.ElapsedMilliseconds) * (double)rounds, TestName, write ? " write" : " read"); + GC.GetTotalMemory(true); + GC.WaitForPendingFinalizers(); + } + + [Test] + public virtual void Message1OptimizeSizeWriterPerf() + { + RunBenchmark(TestResources.google_message1, true); + } + [Test] + public virtual void Message1OptimizeSpeedWriterPerf() + { + RunBenchmark(TestResources.google_message1, true); + } + [Test] + public virtual void Message2OptimizeSizeWriterPerf() + { + RunBenchmark(TestResources.google_message2, true); + } + [Test] + public virtual void Message2OptimizeSpeedWriterPerf() + { + RunBenchmark(TestResources.google_message2, true); + } + + [Test] + public virtual void Message1OptimizeSizeReadPerf() + { + RunBenchmark(TestResources.google_message1, false); + } + [Test] + public virtual void Message1OptimizeSpeedReadPerf() + { + RunBenchmark(TestResources.google_message1, false); + } + [Test] + public virtual void Message2OptimizeSizeReadPerf() + { + RunBenchmark(TestResources.google_message2, false); + } + [Test] + public virtual void Message2OptimizeSpeedReadPerf() + { + RunBenchmark(TestResources.google_message2, false); + } + + #endregion + + [Test] + public virtual void RoundTripMessage1OptimizeSize() + { + SizeMessage1 msg = SizeMessage1.CreateBuilder().MergeFrom(TestResources.google_message1).Build(); + object content = SerializeMessage(msg); + + SizeMessage1 copy = DeerializeMessage(content, SizeMessage1.CreateBuilder(), ExtensionRegistry.Empty).Build(); + + Assert.AreEqual(msg, copy); + Assert.AreEqual(content, SerializeMessage(copy)); + Assert.AreEqual(TestResources.google_message1, copy.ToByteArray()); + } + + [Test] + public virtual void RoundTripMessage2OptimizeSize() + { + SizeMessage2 msg = SizeMessage2.CreateBuilder().MergeFrom(TestResources.google_message2).Build(); + object content = SerializeMessage(msg); + + SizeMessage2 copy = DeerializeMessage(content, SizeMessage2.CreateBuilder(), ExtensionRegistry.Empty).Build(); + + Assert.AreEqual(msg, copy); + Assert.AreEqual(content, SerializeMessage(copy)); + Assert.AreEqual(TestResources.google_message2, copy.ToByteArray()); + } + + [Test] + public virtual void RoundTripMessage1OptimizeSpeed() + { + SpeedMessage1 msg = SpeedMessage1.CreateBuilder().MergeFrom(TestResources.google_message1).Build(); + object content = SerializeMessage(msg); + + SpeedMessage1 copy = DeerializeMessage(content, SpeedMessage1.CreateBuilder(), ExtensionRegistry.Empty).Build(); + + Assert.AreEqual(msg, copy); + Assert.AreEqual(content, SerializeMessage(copy)); + Assert.AreEqual(TestResources.google_message1, copy.ToByteArray()); + } + + [Test] + public virtual void RoundTripMessage2OptimizeSpeed() + { + SpeedMessage2 msg = SpeedMessage2.CreateBuilder().MergeFrom(TestResources.google_message2).Build(); + object content = SerializeMessage(msg); + + SpeedMessage2 copy = DeerializeMessage(content, SpeedMessage2.CreateBuilder(), ExtensionRegistry.Empty).Build(); + + Assert.AreEqual(msg, copy); + Assert.AreEqual(content, SerializeMessage(copy)); + Assert.AreEqual(TestResources.google_message2, copy.ToByteArray()); + } + + } +} diff --git a/src/ProtocolBuffers.Test/CompatTests/TestResources.Designer.cs b/src/ProtocolBuffers.Test/CompatTests/TestResources.Designer.cs new file mode 100644 index 00000000..8565ee80 --- /dev/null +++ b/src/ProtocolBuffers.Test/CompatTests/TestResources.Designer.cs @@ -0,0 +1,77 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:2.0.50727.5444 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace Google.ProtocolBuffers.CompatTests { + using System; + + + /// + /// A strongly-typed resource class, for looking up localized strings, etc. + /// + // This class was auto-generated by the StronglyTypedResourceBuilder + // class via a tool like ResGen or Visual Studio. + // To add or remove a member, edit your .ResX file then rerun ResGen + // with the /str option, or rebuild your VS project. + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "2.0.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + internal class TestResources { + + private static global::System.Resources.ResourceManager resourceMan; + + private static global::System.Globalization.CultureInfo resourceCulture; + + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + internal TestResources() { + } + + /// + /// Returns the cached ResourceManager instance used by this class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Resources.ResourceManager ResourceManager { + get { + if (object.ReferenceEquals(resourceMan, null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Google.ProtocolBuffers.CompatTests.TestResources", typeof(TestResources).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// + /// Overrides the current thread's CurrentUICulture property for all + /// resource lookups using this strongly typed resource class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Globalization.CultureInfo Culture { + get { + return resourceCulture; + } + set { + resourceCulture = value; + } + } + + internal static byte[] google_message1 { + get { + object obj = ResourceManager.GetObject("google_message1", resourceCulture); + return ((byte[])(obj)); + } + } + + internal static byte[] google_message2 { + get { + object obj = ResourceManager.GetObject("google_message2", resourceCulture); + return ((byte[])(obj)); + } + } + } +} diff --git a/src/ProtocolBuffers.Test/CompatTests/TestResources.resx b/src/ProtocolBuffers.Test/CompatTests/TestResources.resx new file mode 100644 index 00000000..0481d388 --- /dev/null +++ b/src/ProtocolBuffers.Test/CompatTests/TestResources.resx @@ -0,0 +1,127 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + + google_message1.dat;System.Byte[], mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + google_message2.dat;System.Byte[], mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/src/ProtocolBuffers.Test/CompatTests/TextCompatibilityTests.cs b/src/ProtocolBuffers.Test/CompatTests/TextCompatibilityTests.cs new file mode 100644 index 00000000..5eba0d33 --- /dev/null +++ b/src/ProtocolBuffers.Test/CompatTests/TextCompatibilityTests.cs @@ -0,0 +1,60 @@ +using System.ComponentModel; +using System.IO; +using NUnit.Framework; + +namespace Google.ProtocolBuffers.CompatTests +{ + [TestFixture] + public class TextCompatibilityTests : CompatibilityTests + { + protected override string TestName { get { return "text"; } } + + protected override object SerializeMessage(TMessage message) + { + StringWriter text = new StringWriter(); + message.PrintTo(text); + return text.ToString(); + } + + protected override TBuilder DeerializeMessage(object message, TBuilder builder, ExtensionRegistry registry) + { + TextFormat.Merge(new StringReader((string)message), registry, (IBuilder)builder); + return builder; + } + + [Test, Explicit, Description("This test can take a very long time to run.")] + public override void Message2OptimizeSizeReadPerf() + { + base.Message2OptimizeSizeReadPerf(); + } + [Test, Explicit, Description("This test can take a very long time to run.")] + public override void Message2OptimizeSpeedReadPerf() + { + base.Message2OptimizeSpeedReadPerf(); + } + + [Test, Explicit, Description("This test can take a very long time to run.")] + public override void RoundTripMessage2OptimizeSize() + { + base.RoundTripMessage2OptimizeSize(); + } + + [Test, Explicit, Description("This test can take a very long time to run.")] + public override void RoundTripMessage2OptimizeSpeed() + { + base.RoundTripMessage2OptimizeSpeed(); + } + + [Test, Explicit, Description("This test can take a very long time to run.")] + public override void Message2OptimizeSizeWriterPerf() + { + base.Message2OptimizeSizeWriterPerf(); + } + [Test, Explicit, Description("This test can take a very long time to run.")] + public override void Message2OptimizeSpeedWriterPerf() + { + base.Message2OptimizeSpeedWriterPerf(); + } + + } +} \ No newline at end of file diff --git a/src/ProtocolBuffers.Test/CompatTests/google_message1.dat b/src/ProtocolBuffers.Test/CompatTests/google_message1.dat new file mode 100644 index 00000000..bc0f064c Binary files /dev/null and b/src/ProtocolBuffers.Test/CompatTests/google_message1.dat differ diff --git a/src/ProtocolBuffers.Test/CompatTests/google_message2.dat b/src/ProtocolBuffers.Test/CompatTests/google_message2.dat new file mode 100644 index 00000000..06c09441 Binary files /dev/null and b/src/ProtocolBuffers.Test/CompatTests/google_message2.dat differ diff --git a/src/ProtocolBuffers.Test/ProtocolBuffers.Test.csproj b/src/ProtocolBuffers.Test/ProtocolBuffers.Test.csproj index 4e07a89a..06dda010 100644 --- a/src/ProtocolBuffers.Test/ProtocolBuffers.Test.csproj +++ b/src/ProtocolBuffers.Test/ProtocolBuffers.Test.csproj @@ -34,6 +34,7 @@ false false true + false true @@ -74,6 +75,14 @@ + + + + True + True + TestResources.resx + + @@ -93,6 +102,8 @@ + + @@ -100,6 +111,7 @@ + @@ -129,6 +141,16 @@ true + + + + + + + ResXFileCodeGenerator + TestResources.Designer.cs + +