Exemple #1
0
        private static bool SpinWait(
            Mutex mutex,
            TimeSpan waitTimeout, TimeSpan spinWaitTimeout,
            IMessageLogger messageLogger)
        {
            Code.InRange(waitTimeout, nameof(spinWaitTimeout), TimeSpan.Zero, _totalWaitTimeout);
            Code.InRange(spinWaitTimeout, nameof(spinWaitTimeout), TimeSpan.Zero, _totalWaitTimeout);

            if (spinWaitTimeout > waitTimeout)
            {
                spinWaitTimeout = waitTimeout;
            }

            bool lockTaken     = false;
            var  totalSpinTime = TimeSpan.Zero;

            while (!lockTaken && totalSpinTime < waitTimeout)
            {
                try
                {
                    lockTaken = mutex.WaitOne(spinWaitTimeout);

                    if (!lockTaken)
                    {
                        messageLogger.WriteInfoMessage($"Another perftest is running, wait timeout {totalSpinTime} of {waitTimeout}.");
                    }
                    else if (totalSpinTime > TimeSpan.Zero)
                    {
                        messageLogger.WriteInfoMessage(
                            $"Another perftest completed, starting. Wait timeout {totalSpinTime} of {waitTimeout}.");
                    }
                }
                catch (AbandonedMutexException ex)
                {
                    // It's ok to swallow abandoned mutex exception as we have no shared resources but logger output
                    // and the log is protected by FileShare.Read lock
                    // see https://msdn.microsoft.com/en-us/library/system.threading.abandonedmutexexception.aspx
                    // for more detail.
                    messageLogger.WriteExceptionMessage(
                        MessageSeverity.Informational,
                        $"Another perftest aborted, starting. Wait timeout {totalSpinTime} of {waitTimeout}.", ex);

                    lockTaken = true;
                }

                totalSpinTime += spinWaitTimeout;
            }

            return(lockTaken);
        }
Exemple #2
0
        private static StoredTargetInfo TryGetStoredTarget(
            Target target, MetricInfo[] metrics, IMessageLogger messageLogger)
        {
            var metricsByType = metrics.ToDictionary(m => m.AttributeType);
            var result        = new List <StoredMetricValue>(metricsByType.Count);

            foreach (var metricAttribute in target.Method.GetMetadataAttributes <IStoredMetricValue>(true).ToArray())
            {
                if (!metricsByType.ContainsKey(metricAttribute.MetricAttributeType))
                {
                    // TODO: improve check for primary metric?
                    if (metricAttribute.MetricAttributeType != MetricInfo.PrimaryMetric.AttributeType)
                    {
                        // TODO: common API for unknown metrics, refactor it to base?
                        var metricName = metricAttribute.MetricAttributeType.GetShortAttributeName();
                        messageLogger.WriteInfoMessage(
                            target,
                            $"Metric {metricName} not listed in config and therefore is ignored.",
                            $"List of metrics is exposed as {nameof(ICompetitionConfig)}.{nameof(ICompetitionConfig.GetMetrics)}().");
                    }
                    continue;
                }

                // Transport object allows to not hold ref to the attribute.
                var storedMetric = new StoredMetricValue(
                    metricAttribute.MetricAttributeType,
                    metricAttribute.Min,
                    metricAttribute.Max,
                    metricAttribute.UnitOfMeasurement);

                result.Add(storedMetric);
            }
            return(new StoredTargetInfo(result.ToArray()));
        }
Exemple #3
0
        private static StoredTargetInfo TryGetStoredTarget(
            Target target, MetricInfo[] metrics, IMessageLogger messageLogger)
        {
            var metricsByType = metrics.ToDictionary(m => m.AttributeType);
            var result        = new List <StoredMetricValue>(metricsByType.Count);

            foreach (var metricAttribute in target.Method.GetMetadataAttributes <IStoredMetricValue>(true).ToArray())
            {
                if (!metricsByType.ContainsKey(metricAttribute.MetricAttributeType))
                {
                    // TODO: improve check for primary metric?
                    if (metricAttribute.MetricAttributeType != MetricInfo.PrimaryMetric.AttributeType)
                    {
                        // TODO: common API for unknown metrics, refactor it to base?
                        messageLogger.WriteInfoMessage(
                            target,
                            $"unknown metric {metricAttribute.MetricAttributeType.Name}, ignored.");
                    }
                    continue;
                }

                // Transport object used to not hold ref to the attribute.
                var storedMetric = new StoredMetricValue(
                    metricAttribute.MetricAttributeType,
                    metricAttribute.Min,
                    metricAttribute.Max,
                    metricAttribute.UnitOfMeasurement);

                result.Add(storedMetric);
            }
            return(new StoredTargetInfo(result.ToArray()));
        }
        protected static CompetitionTarget ParseCompetitionTarget(
            [NotNull] Target target,
            [NotNull] MetricInfo[] metrics,
            [CanBeNull] StoredTargetInfo storedTarget,
            [NotNull] IMessageLogger messageLogger)
        {
            if (storedTarget == null)
            {
                messageLogger.WriteInfoMessage(
                    target,
                    "Has no annotations applied, all metrics will be treated as empty.",
                    "Check if the method was renamed; add annotations for the method or enable auto-annotation feature.");

                return(CreateEmptyCompetitionTarget(target, metrics));
            }

            if (storedTarget.Baseline != null && storedTarget.Baseline != target.Baseline)
            {
                messageLogger.WriteSetupErrorMessage(
                    target,
                    "Baseline flag on the method and in the annotation do not match.",
                    "Check if the method was renamed. Rename it back or update previous run log with new method name.");
            }

            var parseEvents = new List <(MetricInfo metric, MetricParseEvent parseEvent)>();
            var result      = ParseCompetitionMetricValues(target, metrics, storedTarget, parseEvents);

            ReportParseEventSummary(target, parseEvents, messageLogger);

            return(new CompetitionTarget(target, result.ToArray()));
        }
Exemple #5
0
        private static bool CheckCompetitionAttribute(Target target, IMessageLogger messageLogger)
        {
            var benchmarkAttribute = target.Method.GetCustomAttribute <CompetitionBenchmarkAttribute>(false);

            if (benchmarkAttribute == null)
            {
                messageLogger.WriteInfoMessage(
                    target,
                    $"Metric validation skipped as the method is not marked with {nameof(CompetitionBenchmarkAttribute)}.");
                return(false);
            }

            if (benchmarkAttribute.DoesNotCompete)
            {
                messageLogger.WriteInfoMessage(
                    target,
                    "Metric validation skipped as the method is marked with " +
                    $"{nameof(CompetitionBenchmarkAttribute)}.{nameof(CompetitionBenchmarkAttribute.DoesNotCompete)} set to true.");
                return(false);
            }

            return(true);
        }
Exemple #6
0
        private static bool CheckPreconditions(
            CompetitionState competitionState, bool lockTaken,
            IMessageLogger messageLogger)
        {
            var runOptions = competitionState.Options.RunOptions;

            if (!lockTaken)
            {
                switch (runOptions.Concurrent)
                {
                case ConcurrentRunBehavior.Lock:
                case ConcurrentRunBehavior.Skip:
                    messageLogger.WriteWarningMessage(
                        "Competition run skipped. Competitions cannot be run in parallel, be sure to disable parallel test execution.");
                    return(false);

                case ConcurrentRunBehavior.Fail:
                    messageLogger.WriteSetupErrorMessage(
                        "Competition run failed. Competitions cannot be run in parallel, be sure to disable parallel test execution.");
                    return(false);

                default:
                    throw CodeExceptions.UnexpectedArgumentValue(nameof(runOptions.Concurrent), runOptions.Concurrent);
                }
            }

            var benchmarkAssembly = competitionState.BenchmarkType.Assembly;

            if (!runOptions.AllowDebugBuilds && benchmarkAssembly.IsDebugAssembly())
            {
                messageLogger.WriteWarningMessage(
                    $"Competition run skipped. Assembly {benchmarkAssembly.GetName().Name} was build as debug.");

                return(false);
            }

            if (runOptions.ContinuousIntegrationMode)
            {
                messageLogger.WriteInfoMessage(
                    "Competition is run under continuous integration service.");
            }

            return(true);
        }
Exemple #7
0
        protected static CompetitionTarget ParseCompetitionTarget(
            [NotNull] Target target,
            [NotNull] MetricInfo[] metrics,
            [CanBeNull] StoredTargetInfo storedTarget,
            [NotNull] IMessageLogger messageLogger)
        {
            var result = new List <CompetitionMetricValue>();

            if (storedTarget == null)
            {
                messageLogger.WriteInfoMessage(
                    target,
                    "Has no annotations applied, all metrics will be threated as empty.",
                    "Check if the method was renamed; add annnotations for the method or enable auto-annotation feature.");

                return(new CompetitionTarget(target, result.ToArray()));
            }

            if (storedTarget.Baseline != null && storedTarget.Baseline != target.Baseline)
            {
                messageLogger.WriteSetupErrorMessage(
                    target,
                    "Baseline flag on the method and in the annotation do not match.",
                    "Check if the method was renamed. Rename it back or update previous run log with new method name.");
            }

            var hasAnyMetric = storedTarget.MetricValues.Any();

            // TODO: group messages into one?
            var metricsByType = storedTarget.MetricValues.ToDictionary(m => m.MetricAttributeType);

            foreach (var metric in metrics)
            {
                var metricIsApplicable = !target.Baseline || !metric.IsRelative;
                if (metricsByType.TryGetValue(metric.AttributeType, out var storedMetric))
                {
                    if (metricIsApplicable)
                    {
                        var metricValue = storedMetric.ToMetricValue(metric);
                        if (CheckMetricValue(target, metricValue, messageLogger))
                        {
                            result.Add(storedMetric.ToMetricValue(metric));
                        }
                    }
                    else if (!metric.IsPrimaryMetric)
                    {
                        messageLogger.WriteSetupErrorMessage(
                            target,
                            $"Annotation for relative metric {metric} cannot be applied as the target is baseline.",
                            "Check if baseline method for the competition was changed.");
                    }
                }
                else if (metricIsApplicable)
                {
                    if (hasAnyMetric)
                    {
                        messageLogger.WriteInfoMessage(
                            target,
                            $"Annotation for metric {metric} not found, threated as empty.",
                            "Add annnotation for the metric or enable auto-annotation feature.");
                    }

                    result.Add(new CompetitionMetricValue(metric));
                }
            }

            return(new CompetitionTarget(target, result.ToArray()));
        }