< Summary - CoreWCF Coverage — PR #1766

Information
Class: CoreWCF.Dispatcher.ProxyOperationRuntime
Assembly: CoreWCF.Primitives
File(s): /home/runner/work/CoreWCF/CoreWCF/src/CoreWCF.Primitives/src/CoreWCF/Dispatcher/ProxyOperationRuntime.cs
Line coverage
51%
Covered lines: 71
Uncovered lines: 66
Coverable lines: 137
Total lines: 375
Line coverage: 51.8%
Branch coverage
42%
Covered branches: 34
Total branches: 80
Branch coverage: 42.5%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Cyclomatic complexity NPath complexity Sequence coverage
.cctor()100%110%
.ctor(...)43.75%161676.47%
AfterReply(...)50%161647.82%
BeforeRequest(...)14.28%141427.77%
GetDefaultParameterValue(...)75%44100%
IsSyncCall(...)50%2266.66%
IsBeginCall(...)0%220%
IsTaskCall(...)50%2266.66%
MapSyncInputs(...)50%4466.66%
MapAsyncBeginInputs(...)0%440%
MapAsyncEndInputs(...)100%110%
MapSyncOutputs(...)100%11100%
MapAsyncOutputs(...)100%110%
MapOutputs(...)50%101040%
IsValidAction(...)83.33%6685.71%

File(s)

/home/runner/work/CoreWCF/CoreWCF/src/CoreWCF.Primitives/src/CoreWCF/Dispatcher/ProxyOperationRuntime.cs

#LineLine coverage
 1// Licensed to the .NET Foundation under one or more agreements.
 2// The .NET Foundation licenses this file to you under the MIT license.
 3
 4using System;
 5using System.Collections.ObjectModel;
 6using System.Diagnostics.Contracts;
 7using System.Reflection;
 8using CoreWCF.Channels;
 9using CoreWCF.Description;
 10using CoreWCF.Runtime;
 11
 12namespace CoreWCF.Dispatcher
 13{
 14    internal class ProxyOperationRuntime
 15    {
 016        internal static readonly ParameterInfo[] NoParams = Array.Empty<ParameterInfo>();
 017        internal static readonly object[] EmptyArray = Array.Empty<object>();
 18        private readonly IClientMessageFormatter _formatter;
 19        private readonly IParameterInspector[] _parameterInspectors;
 20        private readonly MethodInfo _beginMethod;
 21        private readonly MethodInfo _syncMethod;
 22        private readonly MethodInfo _taskMethod;
 23        private readonly ParameterInfo[] _inParams;
 24        private readonly ParameterInfo[] _outParams;
 25        private readonly ParameterInfo[] _endOutParams;
 26        private readonly ParameterInfo _returnParam;
 27
 228        internal ProxyOperationRuntime(ClientOperation operation, ImmutableClientRuntime parent)
 29        {
 230            if (operation == null)
 31            {
 032                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull(nameof(operation));
 33            }
 34
 235            Parent = parent ?? throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull(nameof(parent));
 236            _formatter = operation.Formatter;
 237            IsInitiating = operation.IsInitiating;
 238            IsOneWay = operation.IsOneWay;
 239            IsTerminating = operation.IsTerminating;
 240            IsSessionOpenNotificationEnabled = operation.IsSessionOpenNotificationEnabled;
 241            Name = operation.Name;
 242            _parameterInspectors = EmptyArray<IParameterInspector>.ToArray(operation.ParameterInspectors);
 243            FaultFormatter = operation.FaultFormatter;
 244            SerializeRequest = operation.SerializeRequest;
 245            DeserializeReply = operation.DeserializeReply;
 246            Action = operation.Action;
 247            ReplyAction = operation.ReplyAction;
 248            _beginMethod = operation.BeginMethod;
 249            _syncMethod = operation.SyncMethod;
 250            _taskMethod = operation.TaskMethod;
 251            TaskTResult = operation.TaskTResult;
 52
 253            if (_beginMethod != null)
 54            {
 055                _inParams = ServiceReflector.GetInputParameters(_beginMethod, true);
 056                if (_syncMethod != null)
 57                {
 058                    _outParams = ServiceReflector.GetOutputParameters(_syncMethod, false);
 59                }
 60                else
 61                {
 062                    _outParams = NoParams;
 63                }
 064                _endOutParams = ServiceReflector.GetOutputParameters(operation.EndMethod, true);
 065                _returnParam = operation.EndMethod.ReturnParameter;
 66            }
 267            else if (_syncMethod != null)
 68            {
 169                _inParams = ServiceReflector.GetInputParameters(_syncMethod, false);
 170                _outParams = ServiceReflector.GetOutputParameters(_syncMethod, false);
 171                _returnParam = _syncMethod.ReturnParameter;
 72            }
 73
 274            if (_formatter == null && (SerializeRequest || DeserializeReply))
 75            {
 076                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.Format(SR.Cli
 77            }
 278        }
 79
 180        internal string Action { get; }
 81
 082        internal IClientFaultFormatter FaultFormatter { get; }
 83
 084        internal bool IsInitiating { get; }
 85
 286        internal bool IsOneWay { get; }
 87
 188        internal bool IsTerminating { get; }
 89
 190        internal bool IsSessionOpenNotificationEnabled { get; }
 91
 092        internal string Name { get; }
 93
 694        internal ImmutableClientRuntime Parent { get; }
 95
 296        internal string ReplyAction { get; }
 97
 298        internal bool DeserializeReply { get; }
 99
 2100        internal bool SerializeRequest { get; }
 101
 102        internal Type TaskTResult
 103        {
 0104            get;
 2105            set;
 106        }
 107
 108        internal void AfterReply(ref ProxyRpc rpc)
 109        {
 1110            if (!IsOneWay)
 111            {
 1112                Message reply = rpc.Reply;
 113
 1114                if (DeserializeReply)
 115                {
 116                    //if (TD.ClientFormatterDeserializeReplyStartIsEnabled())
 117                    //{
 118                    //    TD.ClientFormatterDeserializeReplyStart(rpc.EventTraceActivity);
 119                    //}
 120
 1121                    rpc.ReturnValue = _formatter.DeserializeReply(reply, rpc.OutputParameters);
 122
 123                    //if (TD.ClientFormatterDeserializeReplyStopIsEnabled())
 124                    //{
 125                    //    TD.ClientFormatterDeserializeReplyStop(rpc.EventTraceActivity);
 126                    //}
 127                }
 128                else
 129                {
 0130                    rpc.ReturnValue = reply;
 131                }
 132
 1133                int offset = Parent.ParameterInspectorCorrelationOffset;
 134                try
 135                {
 2136                    for (int i = _parameterInspectors.Length - 1; i >= 0; i--)
 137                    {
 0138                        _parameterInspectors[i].AfterCall(Name,
 0139                                                              rpc.OutputParameters,
 0140                                                              rpc.ReturnValue,
 0141                                                              rpc.Correlation[offset + i]);
 142                        //if (TD.ClientParameterInspectorAfterCallInvokedIsEnabled())
 143                        //{
 144                        //    TD.ClientParameterInspectorAfterCallInvoked(rpc.EventTraceActivity, this._parameterInspect
 145                        //}
 146                    }
 1147                }
 0148                catch (Exception e)
 149                {
 0150                    if (Fx.IsFatal(e))
 151                    {
 0152                        throw;
 153                    }
 0154                    if (ErrorBehavior.ShouldRethrowClientSideExceptionAsIs(e))
 155                    {
 0156                        throw;
 157                    }
 0158                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperCallback(e);
 159                }
 160
 1161                if (Parent.ValidateMustUnderstand)
 162                {
 1163                    Collection<MessageHeaderInfo> headersNotUnderstood = reply.Headers.GetHeadersNotUnderstood();
 1164                    if (headersNotUnderstood != null && headersNotUnderstood.Count > 0)
 165                    {
 0166                        throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ProtocolException(SR.Format(SR.SFx
 167                    }
 168                }
 169            }
 1170        }
 171
 172        internal void BeforeRequest(ref ProxyRpc rpc)
 173        {
 1174            int offset = Parent.ParameterInspectorCorrelationOffset;
 175            try
 176            {
 2177                for (int i = 0; i < _parameterInspectors.Length; i++)
 178                {
 0179                    rpc.Correlation[offset + i] = _parameterInspectors[i].BeforeCall(Name, rpc.InputParameters);
 180                    //if (TD.ClientParameterInspectorBeforeCallInvokedIsEnabled())
 181                    //{
 182                    //    TD.ClientParameterInspectorBeforeCallInvoked(rpc.EventTraceActivity, this._parameterInspectors
 183                    //}
 184                }
 1185            }
 0186            catch (Exception e)
 187            {
 0188                if (Fx.IsFatal(e))
 189                {
 0190                    throw;
 191                }
 0192                if (ErrorBehavior.ShouldRethrowClientSideExceptionAsIs(e))
 193                {
 0194                    throw;
 195                }
 0196                throw DiagnosticUtility.ExceptionUtility.ThrowHelperCallback(e);
 197            }
 198
 1199            if (SerializeRequest)
 200            {
 201                //if (TD.ClientFormatterSerializeRequestStartIsEnabled())
 202                //{
 203                //    TD.ClientFormatterSerializeRequestStart(rpc.EventTraceActivity);
 204                //}
 205
 1206                rpc.Request = _formatter.SerializeRequest(rpc.MessageVersion, rpc.InputParameters);
 207
 208                //if (TD.ClientFormatterSerializeRequestStopIsEnabled())
 209                //{
 210                //    TD.ClientFormatterSerializeRequestStop(rpc.EventTraceActivity);
 211                //}
 212            }
 213            else
 214            {
 0215                if (rpc.InputParameters[0] == null)
 216                {
 0217                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.Format(SR
 218                }
 219
 0220                rpc.Request = (Message)rpc.InputParameters[0];
 0221                if (!IsValidAction(rpc.Request, Action))
 222                {
 0223                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.Format(SR
 224                }
 225            }
 0226        }
 227
 228        internal static object GetDefaultParameterValue(Type parameterType)
 229        {
 1230            return (parameterType.GetTypeInfo().IsValueType && parameterType != typeof(void)) ? Activator.CreateInstance
 231        }
 232
 233        internal bool IsSyncCall(MethodCall methodCall)
 234        {
 1235            if (_syncMethod == null)
 236            {
 0237                return false;
 238            }
 239
 240            Contract.Assert(methodCall != null);
 241            Contract.Assert(methodCall.MethodBase != null);
 1242            return methodCall.MethodBase.Equals(_syncMethod);
 243        }
 244
 245        internal bool IsBeginCall(MethodCall methodCall)
 246        {
 0247            if (_beginMethod == null)
 248            {
 0249                return false;
 250            }
 251
 252            Contract.Assert(methodCall != null);
 253            Contract.Assert(methodCall.MethodBase != null);
 0254            return methodCall.MethodBase.Equals(_beginMethod);
 255        }
 256
 257        internal bool IsTaskCall(MethodCall methodCall)
 258        {
 1259            if (_taskMethod == null)
 260            {
 1261                return false;
 262            }
 263
 264            Contract.Assert(methodCall != null);
 265            Contract.Assert(methodCall.MethodBase != null);
 0266            return methodCall.MethodBase.Equals(_taskMethod);
 267        }
 268
 269        internal object[] MapSyncInputs(MethodCall methodCall, out object[] outs)
 270        {
 1271            if (_outParams.Length == 0)
 272            {
 1273                outs = Array.Empty<object>();
 274            }
 275            else
 276            {
 0277                outs = new object[_outParams.Length];
 278            }
 1279            if (_inParams.Length == 0)
 280            {
 0281                return Array.Empty<object>();
 282            }
 283
 1284            return methodCall.Args;
 285        }
 286
 287        internal object[] MapAsyncBeginInputs(MethodCall methodCall, out AsyncCallback callback, out object asyncState)
 288        {
 289            object[] ins;
 0290            if (_inParams.Length == 0)
 291            {
 0292                ins = Array.Empty<object>();
 293            }
 294            else
 295            {
 0296                ins = new object[_inParams.Length];
 297            }
 298
 0299            object[] args = methodCall.Args;
 0300            for (int i = 0; i < ins.Length; i++)
 301            {
 0302                ins[i] = args[_inParams[i].Position];
 303            }
 304
 0305            callback = args[methodCall.Args.Length - 2] as AsyncCallback;
 0306            asyncState = args[methodCall.Args.Length - 1];
 0307            return ins;
 308        }
 309
 310        internal void MapAsyncEndInputs(MethodCall methodCall, out IAsyncResult result, out object[] outs)
 311        {
 0312            outs = new object[_endOutParams.Length];
 0313            result = methodCall.Args[methodCall.Args.Length - 1] as IAsyncResult;
 0314        }
 315
 316        internal object[] MapSyncOutputs(MethodCall methodCall, object[] outs, ref object ret)
 317        {
 1318            return MapOutputs(_outParams, methodCall, outs, ref ret);
 319        }
 320
 321        internal object[] MapAsyncOutputs(MethodCall methodCall, object[] outs, ref object ret)
 322        {
 0323            return MapOutputs(_endOutParams, methodCall, outs, ref ret);
 324        }
 325
 326        private object[] MapOutputs(ParameterInfo[] parameters, MethodCall methodCall, object[] outs, ref object ret)
 327        {
 1328            if (ret == null && _returnParam != null)
 329            {
 1330                ret = GetDefaultParameterValue(TypeLoader.GetParameterType(_returnParam));
 331            }
 332
 1333            if (parameters.Length == 0)
 334            {
 1335                return null;
 336            }
 337
 0338            object[] args = methodCall.Args;
 0339            for (int i = 0; i < parameters.Length; i++)
 340            {
 0341                if (outs[i] == null)
 342                {
 343                    // the RealProxy infrastructure requires a default value for value types
 0344                    args[parameters[i].Position] = GetDefaultParameterValue(TypeLoader.GetParameterType(parameters[i]));
 345                }
 346                else
 347                {
 0348                    args[parameters[i].Position] = outs[i];
 349                }
 350            }
 351
 0352            return args;
 353        }
 354
 355        internal static bool IsValidAction(Message message, string action)
 356        {
 10357            if (message == null)
 358            {
 0359                return false;
 360            }
 361
 10362            if (message.IsFault)
 363            {
 8364                return true;
 365            }
 366
 2367            if (action == MessageHeaders.WildcardAction)
 368            {
 1369                return true;
 370            }
 371
 1372            return (string.CompareOrdinal(message.Headers.Action, action) == 0);
 373        }
 374    }
 375}