// 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.Text; using System.Threading.Tasks; using KellermanSoftware.CompareNetObjects; using Microsoft.VisualStudio.TestTools.UnitTesting; using Thrift.Protocol; using Thrift.Protocol.Entities; using Thrift.Transport; using Thrift.Transport.Client; #pragma warning disable IDE0063 // using namespace Thrift.IntegrationTests.Protocols { [TestClass] public class ProtocolsOperationsTests { private readonly CompareLogic _compareLogic = new(); private static readonly TConfiguration Configuration = new(); [DataTestMethod] [DataRow(typeof(TBinaryProtocol), TMessageType.Call)] [DataRow(typeof(TBinaryProtocol), TMessageType.Exception)] [DataRow(typeof(TBinaryProtocol), TMessageType.Oneway)] [DataRow(typeof(TBinaryProtocol), TMessageType.Reply)] [DataRow(typeof(TCompactProtocol), TMessageType.Call)] [DataRow(typeof(TCompactProtocol), TMessageType.Exception)] [DataRow(typeof(TCompactProtocol), TMessageType.Oneway)] [DataRow(typeof(TCompactProtocol), TMessageType.Reply)] [DataRow(typeof(TJsonProtocol), TMessageType.Call)] [DataRow(typeof(TJsonProtocol), TMessageType.Exception)] [DataRow(typeof(TJsonProtocol), TMessageType.Oneway)] [DataRow(typeof(TJsonProtocol), TMessageType.Reply)] public async Task WriteReadMessage_Test(Type protocolType, TMessageType messageType) { var expected = new TMessage(nameof(TMessage), messageType, 1); try { var tuple = GetProtocolInstance(protocolType); using (var stream = tuple.Stream) { var protocol = tuple.Protocol; await protocol.WriteMessageBeginAsync(expected, default); await protocol.WriteMessageEndAsync(default); await tuple.Transport.FlushAsync(default); stream.Seek(0, SeekOrigin.Begin); var actualMessage = await protocol.ReadMessageBeginAsync(default); await protocol.ReadMessageEndAsync(default); var result = _compareLogic.Compare(expected, actualMessage); Assert.IsTrue(result.AreEqual, result.DifferencesString); } } catch (Exception e) { throw new Exception($"Exception during testing of protocol: {protocolType.FullName}", e); } } [DataTestMethod] [DataRow(typeof(TBinaryProtocol))] [DataRow(typeof(TCompactProtocol))] [DataRow(typeof(TJsonProtocol))] [ExpectedException(typeof(Exception))] public async Task WriteReadStruct_Test(Type protocolType) { var expected = new TStruct(nameof(TStruct)); try { var tuple = GetProtocolInstance(protocolType); using (var stream = tuple.Stream) { var protocol = tuple.Protocol; await protocol.WriteStructBeginAsync(expected, default); await protocol.WriteStructEndAsync(default); await tuple.Transport.FlushAsync(default); stream?.Seek(0, SeekOrigin.Begin); var actual = await protocol.ReadStructBeginAsync(default); await protocol.ReadStructEndAsync(default); var result = _compareLogic.Compare(expected, actual); Assert.IsTrue(result.AreEqual, result.DifferencesString); } } catch (Exception e) { throw new Exception($"Exception during testing of protocol: {protocolType.FullName}", e); } } [DataTestMethod] [DataRow(typeof(TBinaryProtocol))] [DataRow(typeof(TCompactProtocol))] [DataRow(typeof(TJsonProtocol))] [ExpectedException(typeof(Exception))] public async Task WriteReadField_Test(Type protocolType) { var expected = new TField(nameof(TField), TType.String, 1); try { var tuple = GetProtocolInstance(protocolType); using (var stream = tuple.Stream) { var protocol = tuple.Protocol; await protocol.WriteFieldBeginAsync(expected, default); await protocol.WriteFieldEndAsync(default); await tuple.Transport.FlushAsync(default); stream?.Seek(0, SeekOrigin.Begin); var actual = await protocol.ReadFieldBeginAsync(default); await protocol.ReadFieldEndAsync(default); var result = _compareLogic.Compare(expected, actual); Assert.IsTrue(result.AreEqual, result.DifferencesString); } } catch (Exception e) { throw new Exception($"Exception during testing of protocol: {protocolType.FullName}", e); } } [DataTestMethod] [DataRow(typeof(TBinaryProtocol))] [DataRow(typeof(TCompactProtocol))] [DataRow(typeof(TJsonProtocol))] public async Task WriteReadMap_Test(Type protocolType) { var expected = new TMap(TType.String, TType.String, 1); try { var tuple = GetProtocolInstance(protocolType); using (var stream = tuple.Stream) { var protocol = tuple.Protocol; await protocol.WriteMapBeginAsync(expected, default); await protocol.WriteMapEndAsync(default); await tuple.Transport.FlushAsync(default); stream?.Seek(0, SeekOrigin.Begin); var actual = await protocol.ReadMapBeginAsync(default); await protocol.ReadMapEndAsync(default); var result = _compareLogic.Compare(expected, actual); Assert.IsTrue(result.AreEqual, result.DifferencesString); } } catch (Exception e) { throw new Exception($"Exception during testing of protocol: {protocolType.FullName}", e); } } [DataTestMethod] [DataRow(typeof(TBinaryProtocol))] [DataRow(typeof(TCompactProtocol))] [DataRow(typeof(TJsonProtocol))] public async Task WriteReadList_Test(Type protocolType) { var expected = new TList(TType.String, 1); try { var tuple = GetProtocolInstance(protocolType); using (var stream = tuple.Stream) { var protocol = tuple.Protocol; await protocol.WriteListBeginAsync(expected, default); await protocol.WriteListEndAsync(default); await tuple.Transport.FlushAsync(default); stream?.Seek(0, SeekOrigin.Begin); var actual = await protocol.ReadListBeginAsync(default); await protocol.ReadListEndAsync(default); var result = _compareLogic.Compare(expected, actual); Assert.IsTrue(result.AreEqual, result.DifferencesString); } } catch (Exception e) { throw new Exception($"Exception during testing of protocol: {protocolType.FullName}", e); } } [DataTestMethod] [DataRow(typeof(TBinaryProtocol))] [DataRow(typeof(TCompactProtocol))] [DataRow(typeof(TJsonProtocol))] public async Task WriteReadSet_Test(Type protocolType) { var expected = new TSet(TType.String, 1); try { var tuple = GetProtocolInstance(protocolType); using (var stream = tuple.Stream) { var protocol = tuple.Protocol; await protocol.WriteSetBeginAsync(expected, default); await protocol.WriteSetEndAsync(default); await tuple.Transport.FlushAsync(default); stream?.Seek(0, SeekOrigin.Begin); var actual = await protocol.ReadSetBeginAsync(default); await protocol.ReadSetEndAsync(default); var result = _compareLogic.Compare(expected, actual); Assert.IsTrue(result.AreEqual, result.DifferencesString); } } catch (Exception e) { throw new Exception($"Exception during testing of protocol: {protocolType.FullName}", e); } } [DataTestMethod] [DataRow(typeof(TBinaryProtocol))] [DataRow(typeof(TCompactProtocol))] [DataRow(typeof(TJsonProtocol))] public async Task WriteReadBool_Test(Type protocolType) { var expected = true; try { var tuple = GetProtocolInstance(protocolType); using (var stream = tuple.Stream) { var protocol = tuple.Protocol; await protocol.WriteBoolAsync(expected, default); await tuple.Transport.FlushAsync(default); stream?.Seek(0, SeekOrigin.Begin); var actual = await protocol.ReadBoolAsync(default); var result = _compareLogic.Compare(expected, actual); Assert.IsTrue(result.AreEqual, result.DifferencesString); } } catch (Exception e) { throw new Exception($"Exception during testing of protocol: {protocolType.FullName}", e); } } [DataTestMethod] [DataRow(typeof(TBinaryProtocol))] [DataRow(typeof(TCompactProtocol))] [DataRow(typeof(TJsonProtocol))] public async Task WriteReadByte_Test(Type protocolType) { var expected = sbyte.MaxValue; try { var tuple = GetProtocolInstance(protocolType); using (var stream = tuple.Stream) { var protocol = tuple.Protocol; await protocol.WriteByteAsync(expected, default); await tuple.Transport.FlushAsync(default); stream?.Seek(0, SeekOrigin.Begin); var actual = await protocol.ReadByteAsync(default); var result = _compareLogic.Compare(expected, actual); Assert.IsTrue(result.AreEqual, result.DifferencesString); } } catch (Exception e) { throw new Exception($"Exception during testing of protocol: {protocolType.FullName}", e); } } [DataTestMethod] [DataRow(typeof(TBinaryProtocol))] [DataRow(typeof(TCompactProtocol))] [DataRow(typeof(TJsonProtocol))] public async Task WriteReadI16_Test(Type protocolType) { var expected = short.MaxValue; try { var tuple = GetProtocolInstance(protocolType); using (var stream = tuple.Stream) { var protocol = tuple.Protocol; await protocol.WriteI16Async(expected, default); await tuple.Transport.FlushAsync(default); stream?.Seek(0, SeekOrigin.Begin); var actual = await protocol.ReadI16Async(default); var result = _compareLogic.Compare(expected, actual); Assert.IsTrue(result.AreEqual, result.DifferencesString); } } catch (Exception e) { throw new Exception($"Exception during testing of protocol: {protocolType.FullName}", e); } } [DataTestMethod] [DataRow(typeof(TBinaryProtocol))] [DataRow(typeof(TCompactProtocol))] [DataRow(typeof(TJsonProtocol))] public async Task WriteReadI32_Test(Type protocolType) { var expected = int.MaxValue; try { var tuple = GetProtocolInstance(protocolType); using (var stream = tuple.Stream) { var protocol = tuple.Protocol; await protocol.WriteI32Async(expected, default); await tuple.Transport.FlushAsync(default); stream?.Seek(0, SeekOrigin.Begin); var actual = await protocol.ReadI32Async(default); var result = _compareLogic.Compare(expected, actual); Assert.IsTrue(result.AreEqual, result.DifferencesString); } } catch (Exception e) { throw new Exception($"Exception during testing of protocol: {protocolType.FullName}", e); } } [DataTestMethod] [DataRow(typeof(TBinaryProtocol))] [DataRow(typeof(TCompactProtocol))] [DataRow(typeof(TJsonProtocol))] public async Task WriteReadI64_Test(Type protocolType) { var expected = long.MaxValue; try { var tuple = GetProtocolInstance(protocolType); using (var stream = tuple.Stream) { var protocol = tuple.Protocol; await protocol.WriteI64Async(expected, default); await tuple.Transport.FlushAsync(default); stream?.Seek(0, SeekOrigin.Begin); var actual = await protocol.ReadI64Async(default); var result = _compareLogic.Compare(expected, actual); Assert.IsTrue(result.AreEqual, result.DifferencesString); } } catch (Exception e) { throw new Exception($"Exception during testing of protocol: {protocolType.FullName}", e); } } [DataTestMethod] [DataRow(typeof(TBinaryProtocol))] [DataRow(typeof(TCompactProtocol))] [DataRow(typeof(TJsonProtocol))] public async Task WriteReadDouble_Test(Type protocolType) { var expected = double.MaxValue; try { var tuple = GetProtocolInstance(protocolType); using (var stream = tuple.Stream) { var protocol = tuple.Protocol; await protocol.WriteDoubleAsync(expected, default); await tuple.Transport.FlushAsync(default); stream?.Seek(0, SeekOrigin.Begin); var actual = await protocol.ReadDoubleAsync(default); var result = _compareLogic.Compare(expected, actual); Assert.IsTrue(result.AreEqual, result.DifferencesString); } } catch (Exception e) { throw new Exception($"Exception during testing of protocol: {protocolType.FullName}", e); } } [DataTestMethod] [DataRow(typeof(TBinaryProtocol))] [DataRow(typeof(TCompactProtocol))] [DataRow(typeof(TJsonProtocol))] public async Task WriteReadString_Test(Type protocolType) { var expected = nameof(String); try { var tuple = GetProtocolInstance(protocolType); using (var stream = tuple.Stream) { var protocol = tuple.Protocol; await protocol.WriteStringAsync(expected, default); await tuple.Transport.FlushAsync(default); stream?.Seek(0, SeekOrigin.Begin); var actual = await protocol.ReadStringAsync(default); var result = _compareLogic.Compare(expected, actual); Assert.IsTrue(result.AreEqual, result.DifferencesString); } } catch (Exception e) { throw new Exception($"Exception during testing of protocol: {protocolType.FullName}", e); } } [DataTestMethod] [DataRow(typeof(TBinaryProtocol))] [DataRow(typeof(TCompactProtocol))] [DataRow(typeof(TJsonProtocol))] public async Task WriteReadBinary_Test(Type protocolType) { var expected = Encoding.UTF8.GetBytes(nameof(String)); try { var tuple = GetProtocolInstance(protocolType); using (var stream = tuple.Stream) { var protocol = tuple.Protocol; await protocol.WriteBinaryAsync(expected, default); await tuple.Transport.FlushAsync(default); stream?.Seek(0, SeekOrigin.Begin); var actual = await protocol.ReadBinaryAsync(default); var result = _compareLogic.Compare(expected, actual); Assert.IsTrue(result.AreEqual, result.DifferencesString); } } catch (Exception e) { throw new Exception($"Exception during testing of protocol: {protocolType.FullName}", e); } } private record struct ProtocolTransportStack(Stream Stream, TTransport Transport, TProtocol Protocol); private static ProtocolTransportStack GetProtocolInstance(Type protocolType) { var memoryStream = new MemoryStream(); var streamClientTransport = new TStreamTransport(memoryStream, memoryStream,Configuration); if( Activator.CreateInstance(protocolType, streamClientTransport) is TProtocol protocol) return new ProtocolTransportStack(memoryStream, streamClientTransport, protocol); throw new Exception("Unexpected"); } } }