public PropertyUnitTests(ITestOutputHelper testOutputHelper)
        {
            this.testOutputHelper = testOutputHelper;

            //Define the factories
            this.defaultObjectFactory = new ObjectFactory();

            this.proxyPropertyToObjectModelMapping = new List <ComparerPropertyMapping>()
            {
                new ComparerPropertyMapping(typeof(CloudPool), typeof(Protocol.Models.CloudPool), "AutoScaleEnabled", "EnableAutoScale"),
                new ComparerPropertyMapping(typeof(CloudPool), typeof(Protocol.Models.CloudPool), "VirtualMachineSize", "VmSize"),
                new ComparerPropertyMapping(typeof(CloudPool), typeof(Protocol.Models.CloudPool), "MaxTasksPerComputeNode", "MaxTasksPerNode"),
                new ComparerPropertyMapping(typeof(CloudPool), typeof(Protocol.Models.CloudPool), "Statistics", "Stats"),
                new ComparerPropertyMapping(typeof(CloudPool), typeof(Protocol.Models.CloudPool), "InterComputeNodeCommunicationEnabled", "EnableInterNodeCommunication"),
                new ComparerPropertyMapping(typeof(CloudPool), typeof(Protocol.Models.CloudPool), "CurrentDedicatedComputeNodes", "CurrentDedicatedNodes"),
                new ComparerPropertyMapping(typeof(CloudPool), typeof(Protocol.Models.CloudPool), "CurrentLowPriorityComputeNodes", "CurrentLowPriorityNodes"),
                new ComparerPropertyMapping(typeof(CloudPool), typeof(Protocol.Models.CloudPool), "TargetDedicatedComputeNodes", "TargetDedicatedNodes"),
                new ComparerPropertyMapping(typeof(CloudPool), typeof(Protocol.Models.CloudPool), "TargetLowPriorityComputeNodes", "TargetLowPriorityNodes"),

                new ComparerPropertyMapping(typeof(CloudPool), typeof(Protocol.Models.PoolAddParameter), "VirtualMachineSize", "VmSize"),
                new ComparerPropertyMapping(typeof(CloudPool), typeof(Protocol.Models.PoolAddParameter), "AutoScaleEnabled", "EnableAutoScale"),
                new ComparerPropertyMapping(typeof(CloudPool), typeof(Protocol.Models.PoolAddParameter), "MaxTasksPerComputeNode", "MaxTasksPerNode"),
                new ComparerPropertyMapping(typeof(CloudPool), typeof(Protocol.Models.PoolAddParameter), "InterComputeNodeCommunicationEnabled", "EnableInterNodeCommunication"),
                new ComparerPropertyMapping(typeof(CloudPool), typeof(Protocol.Models.PoolAddParameter), "TargetDedicatedComputeNodes", "TargetDedicatedNodes"),
                new ComparerPropertyMapping(typeof(CloudPool), typeof(Protocol.Models.PoolAddParameter), "TargetLowPriorityComputeNodes", "TargetLowPriorityNodes"),

                new ComparerPropertyMapping(typeof(PoolSpecification), typeof(Protocol.Models.PoolSpecification), "AutoScaleEnabled", "EnableAutoScale"),
                new ComparerPropertyMapping(typeof(PoolSpecification), typeof(Protocol.Models.PoolSpecification), "VirtualMachineSize", "VmSize"),
                new ComparerPropertyMapping(typeof(PoolSpecification), typeof(Protocol.Models.PoolSpecification), "MaxTasksPerComputeNode", "MaxTasksPerNode"),
                new ComparerPropertyMapping(typeof(PoolSpecification), typeof(Protocol.Models.PoolSpecification), "InterComputeNodeCommunicationEnabled", "EnableInterNodeCommunication"),
                new ComparerPropertyMapping(typeof(PoolSpecification), typeof(Protocol.Models.PoolSpecification), "CurrentDedicatedComputeNodes", "CurrentDedicatedNodes"),
                new ComparerPropertyMapping(typeof(PoolSpecification), typeof(Protocol.Models.PoolSpecification), "CurrentLowPriorityComputeNodes", "CurrentLowPriorityNodes"),
                new ComparerPropertyMapping(typeof(PoolSpecification), typeof(Protocol.Models.PoolSpecification), "TargetDedicatedComputeNodes", "TargetDedicatedNodes"),
                new ComparerPropertyMapping(typeof(PoolSpecification), typeof(Protocol.Models.PoolSpecification), "TargetLowPriorityComputeNodes", "TargetLowPriorityNodes"),

                new ComparerPropertyMapping(typeof(CloudServiceConfiguration), typeof(Protocol.Models.CloudServiceConfiguration), "OSFamily", "OsFamily"),
                new ComparerPropertyMapping(typeof(CloudServiceConfiguration), typeof(Protocol.Models.CloudServiceConfiguration), "OSVersion", "OsVersion"),

                new ComparerPropertyMapping(typeof(TaskInformation), typeof(Protocol.Models.TaskInformation), "ExecutionInformation", "TaskExecutionInformation"),

                new ComparerPropertyMapping(typeof(AutoPoolSpecification), typeof(Protocol.Models.AutoPoolSpecification), "PoolSpecification", "Pool"),

                new ComparerPropertyMapping(typeof(JobPreparationAndReleaseTaskExecutionInformation), typeof(Protocol.Models.JobPreparationAndReleaseTaskExecutionInformation), "ComputeNodeId", "NodeId"),
                new ComparerPropertyMapping(typeof(JobPreparationAndReleaseTaskExecutionInformation), typeof(Protocol.Models.JobPreparationAndReleaseTaskExecutionInformation), "ComputeNodeUrl", "NodeUrl"),
                new ComparerPropertyMapping(typeof(JobPreparationAndReleaseTaskExecutionInformation), typeof(Protocol.Models.JobPreparationAndReleaseTaskExecutionInformation), "JobPreparationTaskExecutionInformation", "JobPreparationTaskExecutionInfo"),
                new ComparerPropertyMapping(typeof(JobPreparationAndReleaseTaskExecutionInformation), typeof(Protocol.Models.JobPreparationAndReleaseTaskExecutionInformation), "JobReleaseTaskExecutionInformation", "JobReleaseTaskExecutionInfo"),

                new ComparerPropertyMapping(typeof(JobPreparationTaskExecutionInformation), typeof(Protocol.Models.JobPreparationTaskExecutionInformation), "FailureInformation", "FailureInfo"),
                new ComparerPropertyMapping(typeof(JobPreparationTaskExecutionInformation), typeof(Protocol.Models.JobPreparationTaskExecutionInformation), "ContainerInformation", "ContainerInfo"),

                new ComparerPropertyMapping(typeof(JobReleaseTaskExecutionInformation), typeof(Protocol.Models.JobReleaseTaskExecutionInformation), "FailureInformation", "FailureInfo"),
                new ComparerPropertyMapping(typeof(JobReleaseTaskExecutionInformation), typeof(Protocol.Models.JobReleaseTaskExecutionInformation), "ContainerInformation", "ContainerInfo"),

                new ComparerPropertyMapping(typeof(TaskExecutionInformation), typeof(Protocol.Models.TaskExecutionInformation), "FailureInformation", "FailureInfo"),
                new ComparerPropertyMapping(typeof(TaskExecutionInformation), typeof(Protocol.Models.TaskExecutionInformation), "ContainerInformation", "ContainerInfo"),

                new ComparerPropertyMapping(typeof(SubtaskInformation), typeof(Protocol.Models.SubtaskInformation), "FailureInformation", "FailureInfo"),
                new ComparerPropertyMapping(typeof(SubtaskInformation), typeof(Protocol.Models.SubtaskInformation), "ContainerInformation", "ContainerInfo"),

                new ComparerPropertyMapping(typeof(StartTaskInformation), typeof(Protocol.Models.StartTaskInformation), "FailureInformation", "FailureInfo"),
                new ComparerPropertyMapping(typeof(StartTaskInformation), typeof(Protocol.Models.StartTaskInformation), "ContainerInformation", "ContainerInfo"),

                new ComparerPropertyMapping(typeof(PoolStatistics), typeof(Protocol.Models.PoolStatistics), "UsageStatistics", "UsageStats"),
                new ComparerPropertyMapping(typeof(PoolStatistics), typeof(Protocol.Models.PoolStatistics), "ResourceStatistics", "ResourceStats"),

                new ComparerPropertyMapping(typeof(JobStatistics), typeof(Protocol.Models.JobStatistics), "UserCpuTime", "UserCPUTime"),
                new ComparerPropertyMapping(typeof(JobStatistics), typeof(Protocol.Models.JobStatistics), "KernelCpuTime", "KernelCPUTime"),
                new ComparerPropertyMapping(typeof(JobStatistics), typeof(Protocol.Models.JobStatistics), "SucceededTaskCount", "NumSucceededTasks"),
                new ComparerPropertyMapping(typeof(JobStatistics), typeof(Protocol.Models.JobStatistics), "FailedTaskCount", "NumFailedTasks"),
                new ComparerPropertyMapping(typeof(JobStatistics), typeof(Protocol.Models.JobStatistics), "TaskRetryCount", "NumTaskRetries"),

                new ComparerPropertyMapping(typeof(JobScheduleStatistics), typeof(Protocol.Models.JobScheduleStatistics), "UserCpuTime", "UserCPUTime"),
                new ComparerPropertyMapping(typeof(JobScheduleStatistics), typeof(Protocol.Models.JobScheduleStatistics), "KernelCpuTime", "KernelCPUTime"),
                new ComparerPropertyMapping(typeof(JobScheduleStatistics), typeof(Protocol.Models.JobScheduleStatistics), "SucceededTaskCount", "NumSucceededTasks"),
                new ComparerPropertyMapping(typeof(JobScheduleStatistics), typeof(Protocol.Models.JobScheduleStatistics), "FailedTaskCount", "NumFailedTasks"),
                new ComparerPropertyMapping(typeof(JobScheduleStatistics), typeof(Protocol.Models.JobScheduleStatistics), "TaskRetryCount", "NumTaskRetries"),

                new ComparerPropertyMapping(typeof(ResourceStatistics), typeof(Protocol.Models.ResourceStatistics), "AverageCpuPercentage", "AvgCPUPercentage"),
                new ComparerPropertyMapping(typeof(ResourceStatistics), typeof(Protocol.Models.ResourceStatistics), "AverageMemoryGiB", "AvgMemoryGiB"),
                new ComparerPropertyMapping(typeof(ResourceStatistics), typeof(Protocol.Models.ResourceStatistics), "AverageDiskGiB", "AvgDiskGiB"),

                new ComparerPropertyMapping(typeof(TaskStatistics), typeof(Protocol.Models.TaskStatistics), "UserCpuTime", "UserCPUTime"),
                new ComparerPropertyMapping(typeof(TaskStatistics), typeof(Protocol.Models.TaskStatistics), "KernelCpuTime", "KernelCPUTime"),

                new ComparerPropertyMapping(typeof(CloudJob), typeof(Protocol.Models.CloudJob), "PoolInformation", "PoolInfo"),
                new ComparerPropertyMapping(typeof(CloudJob), typeof(Protocol.Models.CloudJob), "ExecutionInformation", "ExecutionInfo"),
                new ComparerPropertyMapping(typeof(CloudJob), typeof(Protocol.Models.CloudJob), "Statistics", "Stats"),

                new ComparerPropertyMapping(typeof(CloudJob), typeof(Protocol.Models.JobAddParameter), "PoolInformation", "PoolInfo"),

                new ComparerPropertyMapping(typeof(JobSpecification), typeof(Protocol.Models.JobSpecification), "PoolInformation", "PoolInfo"),

                new ComparerPropertyMapping(typeof(CloudJobSchedule), typeof(Protocol.Models.CloudJobSchedule), "ExecutionInformation", "ExecutionInfo"),
                new ComparerPropertyMapping(typeof(CloudJobSchedule), typeof(Protocol.Models.CloudJobSchedule), "Statistics", "Stats"),

                new ComparerPropertyMapping(typeof(CloudTask), typeof(Protocol.Models.CloudTask), "AffinityInformation", "AffinityInfo"),
                new ComparerPropertyMapping(typeof(CloudTask), typeof(Protocol.Models.CloudTask), "ExecutionInformation", "ExecutionInfo"),
                new ComparerPropertyMapping(typeof(CloudTask), typeof(Protocol.Models.CloudTask), "ComputeNodeInformation", "NodeInfo"),
                new ComparerPropertyMapping(typeof(CloudTask), typeof(Protocol.Models.CloudTask), "Statistics", "Stats"),

                new ComparerPropertyMapping(typeof(CloudTask), typeof(Protocol.Models.TaskAddParameter), "AffinityInformation", "AffinityInfo"),
                new ComparerPropertyMapping(typeof(CloudTask), typeof(Protocol.Models.TaskAddParameter), "ComputeNodeInformation", "NodeInfo"),

                new ComparerPropertyMapping(typeof(ExitConditions), typeof(Protocol.Models.ExitConditions), "Default", "DefaultProperty"),

                new ComparerPropertyMapping(typeof(TaskInformation), typeof(Protocol.Models.TaskInformation), "ExecutionInformation", "ExecutionInfo"),

                new ComparerPropertyMapping(typeof(ComputeNode), typeof(Protocol.Models.ComputeNode), "IPAddress", "IpAddress"),
                new ComparerPropertyMapping(typeof(ComputeNode), typeof(Protocol.Models.ComputeNode), "VirtualMachineSize", "VmSize"),
                new ComparerPropertyMapping(typeof(ComputeNode), typeof(Protocol.Models.ComputeNode), "StartTaskInformation", "StartTaskInfo"),
                new ComparerPropertyMapping(typeof(ComputeNode), typeof(Protocol.Models.ComputeNode), "NodeAgentInformation", "NodeAgentInfo"),

                new ComparerPropertyMapping(typeof(ComputeNodeInformation), typeof(Protocol.Models.ComputeNodeInformation), "ComputeNodeId", "NodeId"),
                new ComparerPropertyMapping(typeof(ComputeNodeInformation), typeof(Protocol.Models.ComputeNodeInformation), "ComputeNodeUrl", "NodeUrl"),

                new ComparerPropertyMapping(typeof(JobPreparationTask), typeof(Protocol.Models.JobPreparationTask), "RerunOnComputeNodeRebootAfterSuccess", "RerunOnNodeRebootAfterSuccess"),

                new ComparerPropertyMapping(typeof(ImageReference), typeof(Protocol.Models.ImageReference), "SkuId", "Sku"),

                new ComparerPropertyMapping(typeof(VirtualMachineConfiguration), typeof(Protocol.Models.VirtualMachineConfiguration), "NodeAgentSkuId", "NodeAgentSKUId"),
                new ComparerPropertyMapping(typeof(VirtualMachineConfiguration), typeof(Protocol.Models.VirtualMachineConfiguration), "OSDisk", "OsDisk"),

                new ComparerPropertyMapping(typeof(TaskSchedulingPolicy), typeof(Protocol.Models.TaskSchedulingPolicy), "ComputeNodeFillType", "NodeFillType"),

                new ComparerPropertyMapping(typeof(PoolEndpointConfiguration), typeof(Protocol.Models.PoolEndpointConfiguration), "InboundNatPools", "InboundNATPools"),
                new ComparerPropertyMapping(typeof(InboundEndpoint), typeof(Protocol.Models.InboundEndpoint), "PublicFqdn", "PublicFQDN"),

                new ComparerPropertyMapping(typeof(ImageInformation), typeof(Protocol.Models.ImageInformation), "NodeAgentSkuId", "NodeAgentSKUId"),
                new ComparerPropertyMapping(typeof(ImageInformation), typeof(Protocol.Models.ImageInformation), "OSType", "OsType"),
            };

            Random rand = new Random();

            Func <object> omTaskRangeBuilder = () =>
            {
                int rangeLimit1 = rand.Next(0, int.MaxValue);
                int rangeLimit2 = rand.Next(0, int.MaxValue);

                return(new TaskIdRange(Math.Min(rangeLimit1, rangeLimit2), Math.Max(rangeLimit1, rangeLimit2)));
            };

            Func <object> iFileStagingProviderBuilder = () => null;

            Func <object> batchClientBehaviorBuilder = () => null;

            Func <object> taskRangeBuilder = () =>
            {
                int rangeLimit1 = rand.Next(0, int.MaxValue);
                int rangeLimit2 = rand.Next(0, int.MaxValue);

                return(new Protocol.Models.TaskIdRange(Math.Min(rangeLimit1, rangeLimit2), Math.Max(rangeLimit1, rangeLimit2)));
            };

            ObjectFactoryConstructionSpecification certificateReferenceSpecification = new ObjectFactoryConstructionSpecification(
                typeof(Protocol.Models.CertificateReference),
                () => BuildCertificateReference(rand));

            ObjectFactoryConstructionSpecification authenticationTokenSettingsSpecification = new ObjectFactoryConstructionSpecification(
                typeof(Protocol.Models.AuthenticationTokenSettings),
                () => BuildAuthenticationTokenSettings(rand));

            ObjectFactoryConstructionSpecification taskRangeSpecification = new ObjectFactoryConstructionSpecification(
                typeof(Protocol.Models.TaskIdRange),
                taskRangeBuilder);

            ObjectFactoryConstructionSpecification omTaskRangeSpecification = new ObjectFactoryConstructionSpecification(
                typeof(TaskIdRange),
                omTaskRangeBuilder);

            ObjectFactoryConstructionSpecification batchClientBehaviorSpecification = new ObjectFactoryConstructionSpecification(
                typeof(BatchClientBehavior),
                batchClientBehaviorBuilder);

            ObjectFactoryConstructionSpecification fileStagingProviderSpecification = new ObjectFactoryConstructionSpecification(
                typeof(IFileStagingProvider),
                iFileStagingProviderBuilder);

            this.customizedObjectFactory = new ObjectFactory(new List <ObjectFactoryConstructionSpecification>
            {
                certificateReferenceSpecification,
                authenticationTokenSettingsSpecification,
                taskRangeSpecification,
                omTaskRangeSpecification,
                fileStagingProviderSpecification,
                batchClientBehaviorSpecification,
            });

            // We need a custom comparison rule for certificate references because they are a different type in the proxy vs
            // the object model (string in proxy, flags enum in OM
            ComparisonRule certificateReferenceComparisonRule = ComparisonRule.Create <CertificateVisibility?, List <Protocol.Models.CertificateVisibility> >(
                typeof(CertificateReference),
                typeof(Protocol.Models.CertificateReference), // This is the type that hold the target property
                (visibility, proxyVisibility) =>
            {
                CertificateVisibility?convertedProxyVisibility = UtilitiesInternal.ParseCertificateVisibility(proxyVisibility);

                //Treat null as None for the purposes of comparison:
                bool areEqual = convertedProxyVisibility == visibility || !visibility.HasValue && convertedProxyVisibility == CertificateVisibility.None;

                return(areEqual ? ObjectComparer.CheckEqualityResult.True : ObjectComparer.CheckEqualityResult.False("Certificate visibility doesn't match"));
            },
                type1PropertyName: "Visibility",
                type2PropertyName: "Visibility");

            ComparisonRule accessScopeComparisonRule = ComparisonRule.Create <AccessScope, List <Protocol.Models.AccessScope> >(
                typeof(AuthenticationTokenSettings),
                typeof(Protocol.Models.AuthenticationTokenSettings),  // This is the type that hold the target property
                (scope, proxyVisibility) =>
            {
                AccessScope convertedProxyAccessScope = UtilitiesInternal.ParseAccessScope(proxyVisibility);

                //Treat null as None for the purposes of comparison:
                bool areEqual = convertedProxyAccessScope == scope || convertedProxyAccessScope == AccessScope.None;

                return(areEqual ? ObjectComparer.CheckEqualityResult.True : ObjectComparer.CheckEqualityResult.False("AccessScope doesn't match"));
            },
                type1PropertyName: "Access",
                type2PropertyName: "Access");

            this.objectComparer = new ObjectComparer(
                comparisonRules: new List <ComparisonRule>()
            {
                certificateReferenceComparisonRule, accessScopeComparisonRule
            },
                propertyMappings: this.proxyPropertyToObjectModelMapping,
                shouldThrowOnPropertyReadException: e => !(e.InnerException is InvalidOperationException) || !e.InnerException.Message.Contains("while the object is in the Unbound"));
        }
예제 #2
0
        public PropertyUnitTests(ITestOutputHelper testOutputHelper)
        {
            this.testOutputHelper = testOutputHelper;

            //Define the factories
            this.defaultObjectFactory = new ObjectFactory();

            this.proxyPropertyToObjectModelMapping = new List <ComparerPropertyMapping>()
            {
                new ComparerPropertyMapping(typeof(CloudPool), typeof(Protocol.Models.CloudPool), "AutoScaleEnabled", "EnableAutoScale"),
                new ComparerPropertyMapping(typeof(CloudPool), typeof(Protocol.Models.CloudPool), "VirtualMachineSize", "VmSize"),
                new ComparerPropertyMapping(typeof(CloudPool), typeof(Protocol.Models.CloudPool), "MaxTasksPerComputeNode", "MaxTasksPerNode"),
                new ComparerPropertyMapping(typeof(CloudPool), typeof(Protocol.Models.CloudPool), "Statistics", "Stats"),
                new ComparerPropertyMapping(typeof(CloudPool), typeof(Protocol.Models.CloudPool), "InterComputeNodeCommunicationEnabled", "EnableInterNodeCommunication"),

                new ComparerPropertyMapping(typeof(CloudPool), typeof(Protocol.Models.PoolAddParameter), "VirtualMachineSize", "VmSize"),
                new ComparerPropertyMapping(typeof(CloudPool), typeof(Protocol.Models.PoolAddParameter), "AutoScaleEnabled", "EnableAutoScale"),
                new ComparerPropertyMapping(typeof(CloudPool), typeof(Protocol.Models.PoolAddParameter), "MaxTasksPerComputeNode", "MaxTasksPerNode"),
                new ComparerPropertyMapping(typeof(CloudPool), typeof(Protocol.Models.PoolAddParameter), "InterComputeNodeCommunicationEnabled", "EnableInterNodeCommunication"),

                new ComparerPropertyMapping(typeof(PoolSpecification), typeof(Protocol.Models.PoolSpecification), "AutoScaleEnabled", "EnableAutoScale"),
                new ComparerPropertyMapping(typeof(PoolSpecification), typeof(Protocol.Models.PoolSpecification), "VirtualMachineSize", "VmSize"),
                new ComparerPropertyMapping(typeof(PoolSpecification), typeof(Protocol.Models.PoolSpecification), "MaxTasksPerComputeNode", "MaxTasksPerNode"),
                new ComparerPropertyMapping(typeof(PoolSpecification), typeof(Protocol.Models.PoolSpecification), "InterComputeNodeCommunicationEnabled", "EnableInterNodeCommunication"),

                new ComparerPropertyMapping(typeof(CloudServiceConfiguration), typeof(Protocol.Models.CloudServiceConfiguration), "OSFamily", "OsFamily"),

                new ComparerPropertyMapping(typeof(TaskInformation), typeof(Protocol.Models.TaskInformation), "ExecutionInformation", "TaskExecutionInformation"),

                new ComparerPropertyMapping(typeof(AutoPoolSpecification), typeof(Protocol.Models.AutoPoolSpecification), "PoolSpecification", "Pool"),

                new ComparerPropertyMapping(typeof(JobPreparationAndReleaseTaskExecutionInformation), typeof(Protocol.Models.JobPreparationAndReleaseTaskExecutionInformation), "ComputeNodeId", "NodeId"),
                new ComparerPropertyMapping(typeof(JobPreparationAndReleaseTaskExecutionInformation), typeof(Protocol.Models.JobPreparationAndReleaseTaskExecutionInformation), "ComputeNodeUrl", "NodeUrl"),
                new ComparerPropertyMapping(typeof(JobPreparationAndReleaseTaskExecutionInformation), typeof(Protocol.Models.JobPreparationAndReleaseTaskExecutionInformation), "JobPreparationTaskExecutionInformation", "JobPreparationTaskExecutionInfo"),
                new ComparerPropertyMapping(typeof(JobPreparationAndReleaseTaskExecutionInformation), typeof(Protocol.Models.JobPreparationAndReleaseTaskExecutionInformation), "JobReleaseTaskExecutionInformation", "JobReleaseTaskExecutionInfo"),

                new ComparerPropertyMapping(typeof(PoolStatistics), typeof(Protocol.Models.PoolStatistics), "UsageStatistics", "UsageStats"),
                new ComparerPropertyMapping(typeof(PoolStatistics), typeof(Protocol.Models.PoolStatistics), "ResourceStatistics", "ResourceStats"),

                new ComparerPropertyMapping(typeof(JobStatistics), typeof(Protocol.Models.JobStatistics), "UserCpuTime", "UserCPUTime"),
                new ComparerPropertyMapping(typeof(JobStatistics), typeof(Protocol.Models.JobStatistics), "KernelCpuTime", "KernelCPUTime"),
                new ComparerPropertyMapping(typeof(JobStatistics), typeof(Protocol.Models.JobStatistics), "SucceededTaskCount", "NumSucceededTasks"),
                new ComparerPropertyMapping(typeof(JobStatistics), typeof(Protocol.Models.JobStatistics), "FailedTaskCount", "NumFailedTasks"),
                new ComparerPropertyMapping(typeof(JobStatistics), typeof(Protocol.Models.JobStatistics), "TaskRetryCount", "NumTaskRetries"),

                new ComparerPropertyMapping(typeof(JobScheduleStatistics), typeof(Protocol.Models.JobScheduleStatistics), "UserCpuTime", "UserCPUTime"),
                new ComparerPropertyMapping(typeof(JobScheduleStatistics), typeof(Protocol.Models.JobScheduleStatistics), "KernelCpuTime", "KernelCPUTime"),
                new ComparerPropertyMapping(typeof(JobScheduleStatistics), typeof(Protocol.Models.JobScheduleStatistics), "SucceededTaskCount", "NumSucceededTasks"),
                new ComparerPropertyMapping(typeof(JobScheduleStatistics), typeof(Protocol.Models.JobScheduleStatistics), "FailedTaskCount", "NumFailedTasks"),
                new ComparerPropertyMapping(typeof(JobScheduleStatistics), typeof(Protocol.Models.JobScheduleStatistics), "TaskRetryCount", "NumTaskRetries"),

                new ComparerPropertyMapping(typeof(ResourceStatistics), typeof(Protocol.Models.ResourceStatistics), "AverageCpuPercentage", "AvgCPUPercentage"),
                new ComparerPropertyMapping(typeof(ResourceStatistics), typeof(Protocol.Models.ResourceStatistics), "AverageMemoryGiB", "AvgMemoryGiB"),
                new ComparerPropertyMapping(typeof(ResourceStatistics), typeof(Protocol.Models.ResourceStatistics), "AverageDiskGiB", "AvgDiskGiB"),

                new ComparerPropertyMapping(typeof(TaskStatistics), typeof(Protocol.Models.TaskStatistics), "UserCpuTime", "UserCPUTime"),
                new ComparerPropertyMapping(typeof(TaskStatistics), typeof(Protocol.Models.TaskStatistics), "KernelCpuTime", "KernelCPUTime"),

                new ComparerPropertyMapping(typeof(CloudJob), typeof(Protocol.Models.CloudJob), "PoolInformation", "PoolInfo"),
                new ComparerPropertyMapping(typeof(CloudJob), typeof(Protocol.Models.CloudJob), "ExecutionInformation", "ExecutionInfo"),
                new ComparerPropertyMapping(typeof(CloudJob), typeof(Protocol.Models.CloudJob), "Statistics", "Stats"),

                new ComparerPropertyMapping(typeof(CloudJob), typeof(Protocol.Models.JobAddParameter), "PoolInformation", "PoolInfo"),

                new ComparerPropertyMapping(typeof(JobSpecification), typeof(Protocol.Models.JobSpecification), "PoolInformation", "PoolInfo"),

                new ComparerPropertyMapping(typeof(CloudJobSchedule), typeof(Protocol.Models.CloudJobSchedule), "ExecutionInformation", "ExecutionInfo"),
                new ComparerPropertyMapping(typeof(CloudJobSchedule), typeof(Protocol.Models.CloudJobSchedule), "Statistics", "Stats"),

                new ComparerPropertyMapping(typeof(CloudTask), typeof(Protocol.Models.CloudTask), "AffinityInformation", "AffinityInfo"),
                new ComparerPropertyMapping(typeof(CloudTask), typeof(Protocol.Models.CloudTask), "ExecutionInformation", "ExecutionInfo"),
                new ComparerPropertyMapping(typeof(CloudTask), typeof(Protocol.Models.CloudTask), "ComputeNodeInformation", "NodeInfo"),
                new ComparerPropertyMapping(typeof(CloudTask), typeof(Protocol.Models.CloudTask), "Statistics", "Stats"),

                new ComparerPropertyMapping(typeof(CloudTask), typeof(Protocol.Models.TaskAddParameter), "AffinityInformation", "AffinityInfo"),
                new ComparerPropertyMapping(typeof(CloudTask), typeof(Protocol.Models.TaskAddParameter), "ComputeNodeInformation", "NodeInfo"),

                new ComparerPropertyMapping(typeof(ExitConditions), typeof(Protocol.Models.ExitConditions), "Default", "DefaultProperty"),

                new ComparerPropertyMapping(typeof(TaskInformation), typeof(Protocol.Models.TaskInformation), "ExecutionInformation", "ExecutionInfo"),

                new ComparerPropertyMapping(typeof(ComputeNode), typeof(Protocol.Models.ComputeNode), "IPAddress", "IpAddress"),
                new ComparerPropertyMapping(typeof(ComputeNode), typeof(Protocol.Models.ComputeNode), "VirtualMachineSize", "VmSize"),
                new ComparerPropertyMapping(typeof(ComputeNode), typeof(Protocol.Models.ComputeNode), "StartTaskInformation", "StartTaskInfo"),

                new ComparerPropertyMapping(typeof(ComputeNodeInformation), typeof(Protocol.Models.ComputeNodeInformation), "ComputeNodeId", "NodeId"),
                new ComparerPropertyMapping(typeof(ComputeNodeInformation), typeof(Protocol.Models.ComputeNodeInformation), "ComputeNodeUrl", "NodeUrl"),

                new ComparerPropertyMapping(typeof(JobPreparationTask), typeof(Protocol.Models.JobPreparationTask), "RerunOnComputeNodeRebootAfterSuccess", "RerunOnNodeRebootAfterSuccess"),

                new ComparerPropertyMapping(typeof(ImageReference), typeof(Protocol.Models.ImageReference), "SkuId", "Sku"),

                new ComparerPropertyMapping(typeof(VirtualMachineConfiguration), typeof(Protocol.Models.VirtualMachineConfiguration), "NodeAgentSkuId", "NodeAgentSKUId"),

                new ComparerPropertyMapping(typeof(TaskSchedulingPolicy), typeof(Protocol.Models.TaskSchedulingPolicy), "ComputeNodeFillType", "NodeFillType"),
            };

            Random rand = new Random();

            Func <object> certificateReferenceBuilder = () =>
            {
                //Build cert visibility (which is a required property)
                IList          values         = Enum.GetValues(typeof(CertificateVisibility));
                IList <object> valuesToSelect = new List <object>();

                foreach (object value in values)
                {
                    valuesToSelect.Add(value);
                }

                int valuesToPick = rand.Next(0, values.Count);
                CertificateVisibility?visibility = null;

                // If valuesToPick is 0, we want to allow visibility to be null (since null is a valid value)
                // so only set visibility to be None if valuesToPick > 0
                if (valuesToPick > 0)
                {
                    visibility = CertificateVisibility.None;
                    for (int i = 0; i < valuesToPick; i++)
                    {
                        int    selectedValueIndex = rand.Next(valuesToSelect.Count);
                        object selectedValue      = valuesToSelect[selectedValueIndex];
                        visibility |= (CertificateVisibility)selectedValue;

                        valuesToSelect.RemoveAt(selectedValueIndex);
                    }
                }

                Protocol.Models.CertificateReference reference =
                    this.defaultObjectFactory.GenerateNew <Protocol.Models.CertificateReference>();

                //Set certificate visibility since it is required
                reference.Visibility = visibility == null ? null : UtilitiesInternal.CertificateVisibilityToList(visibility.Value);

                return(reference);
            };

            Func <object> omTaskRangeBuilder = () =>
            {
                int rangeLimit1 = rand.Next(0, int.MaxValue);
                int rangeLimit2 = rand.Next(0, int.MaxValue);

                return(new TaskIdRange(Math.Min(rangeLimit1, rangeLimit2), Math.Max(rangeLimit1, rangeLimit2)));
            };

            Func <object> iFileStagingProviderBuilder = () => { return(null); };

            Func <object> batchClientBehaviorBuilder = () => { return(null); };

            Func <object> taskRangeBuilder = () =>
            {
                int rangeLimit1 = rand.Next(0, int.MaxValue);
                int rangeLimit2 = rand.Next(0, int.MaxValue);

                return(new Protocol.Models.TaskIdRange(Math.Min(rangeLimit1, rangeLimit2), Math.Max(rangeLimit1, rangeLimit2)));
            };

            ObjectFactoryConstructionSpecification visibilitySpecification = new ObjectFactoryConstructionSpecification(
                typeof(Protocol.Models.CertificateReference),
                certificateReferenceBuilder);

            ObjectFactoryConstructionSpecification taskRangeSpecification = new ObjectFactoryConstructionSpecification(
                typeof(Protocol.Models.TaskIdRange),
                taskRangeBuilder);

            ObjectFactoryConstructionSpecification omTaskRangeSpecification = new ObjectFactoryConstructionSpecification(
                typeof(TaskIdRange),
                omTaskRangeBuilder);

            ObjectFactoryConstructionSpecification batchClientBehaviorSpecification = new ObjectFactoryConstructionSpecification(
                typeof(BatchClientBehavior),
                batchClientBehaviorBuilder);

            ObjectFactoryConstructionSpecification fileStagingProviderSpecification = new ObjectFactoryConstructionSpecification(
                typeof(IFileStagingProvider),
                iFileStagingProviderBuilder);

            this.customizedObjectFactory = new ObjectFactory(new List <ObjectFactoryConstructionSpecification>
            {
                visibilitySpecification,
                taskRangeSpecification,
                omTaskRangeSpecification,
                fileStagingProviderSpecification,
                batchClientBehaviorSpecification
            });

            // We need a custom comparison rule for certificate references because they are a different type in the proxy vs
            // the object model (string in proxy, flags enum in OM
            ComparisonRule certificateReferenceComparisonRule = ComparisonRule.Create <CertificateVisibility?, List <Protocol.Models.CertificateVisibility?> >(
                typeof(CertificateReference),
                typeof(Protocol.Models.CertificateReference),
                (visibility, proxyVisibility) =>
            {
                CertificateVisibility?convertedProxyVisibility = UtilitiesInternal.ParseCertificateVisibility(proxyVisibility);

                //Treat null as None for the purposes of comparison:
                bool areEqual = convertedProxyVisibility == visibility || !visibility.HasValue && convertedProxyVisibility == CertificateVisibility.None;

                return(areEqual ? ObjectComparer.CheckEqualityResult.True : ObjectComparer.CheckEqualityResult.False("Certificate visibility doesn't match"));
            },
                type1PropertyName: "Visibility",
                type2PropertyName: "Visibility");

            this.objectComparer = new ObjectComparer(
                comparisonRules: new List <ComparisonRule>()
            {
                certificateReferenceComparisonRule
            },
                propertyMappings: this.proxyPropertyToObjectModelMapping,
                shouldThrowOnPropertyReadException: e => !(e.InnerException is InvalidOperationException) || !e.InnerException.Message.Contains("while the object is in the Unbound"));
        }