Esempio n. 1
0
        private async Task CheckForWorkItemFailureAsync(string workItemName, string jobName)
        {
            await Task.Yield();

            try
            {
                WorkItemDetails details = await HelixApi.RetryAsync(
                    () => HelixApi.WorkItem.DetailsAsync(workItemName, jobName),
                    LogExceptionRetry);

                string message = $"Work item {workItemName} in job {jobName} has {details.State} with exit code {details.ExitCode}";
                if (IsFailed(details))
                {
                    Log.LogError(message);
                }
                else
                {
                    Log.LogMessage(MessageImportance.Low, message);
                }
            }
            catch (Exception ex)
            {
                Log.LogError($"Unable to get work item status for '{workItemName}', assuming failure. Exception: {ex}");
            }
        }
Esempio n. 2
0
        private async Task WaitForHelixJobAsync(string jobName)
        {
            await Task.Yield();

            Log.LogMessage($"Waiting for completion of job {jobName}");

            while (true)
            {
                var workItems = await HelixApi.RetryAsync(
                    () => HelixApi.WorkItem.ListAsync(jobName),
                    LogExceptionRetry);

                var waitingCount  = workItems.Count(wi => wi.State == "Waiting");
                var runningCount  = workItems.Count(wi => wi.State == "Running");
                var finishedCount = workItems.Count(wi => wi.State == "Finished");
                if (waitingCount == 0 && runningCount == 0 && finishedCount > 0)
                {
                    // determines whether any of the work items failed (fireballed)
                    await Task.WhenAll(workItems.Select(wi => CheckForWorkItemFailureAsync(wi.Name, jobName)));

                    Log.LogMessage(MessageImportance.High, $"Job {jobName} is completed with {finishedCount} finished work items.");
                    return;
                }

                Log.LogMessage($"Job {jobName} is not yet completed with Waiting: {waitingCount}, Running: {runningCount}, Finished: {finishedCount}");
                await Task.Delay(10000);
            }
        }
Esempio n. 3
0
        private async Task WaitForHelixJobAsync(string jobName, CancellationToken cancellationToken)
        {
            await Task.Yield();

            cancellationToken.ThrowIfCancellationRequested();
            Log.LogMessage(MessageImportance.High, $"Waiting for completion of job {jobName}");

            for (;; await Task.Delay(10000, cancellationToken)) // delay every time this loop repeats
            {
                cancellationToken.ThrowIfCancellationRequested();
                var pf = await HelixApi.RetryAsync(
                    () => HelixApi.Job.PassFailAsync(jobName, cancellationToken),
                    LogExceptionRetry,
                    cancellationToken);

                if (pf.Working == 0 && pf.Total != 0)
                {
                    Log.LogMessage(MessageImportance.High, $"Job {jobName} is completed with {pf.Total} finished work items.");
                    return;
                }

                Log.LogMessage($"Job {jobName} is not yet completed with Pending: {pf.Working}, Finished: {pf.Total - pf.Working}");
                cancellationToken.ThrowIfCancellationRequested();
            }
        }
Esempio n. 4
0
        private async Task <IEnumerable <ITaskItem> > GetFailedWorkItemsAsync(ITaskItem job, CancellationToken cancellationToken)
        {
            var jobName = job.GetMetadata("Identity");

            Log.LogMessage($"Getting status of job {jobName}");

            var status = await HelixApi.RetryAsync(
                () => HelixApi.Job.PassFailAsync(jobName, cancellationToken),
                LogExceptionRetry,
                cancellationToken);

            if (status.Working > 0)
            {
                Log.LogError(
                    FailureCategory.Build,
                    $"This task can only be used on completed jobs. There are {status.Working} of {status.Total} unfinished work items.");
                return(Array.Empty <ITaskItem>());
            }

            return(await Task.WhenAll(status.Failed.Select(async wi =>
            {
                // copy all job metadata into the new item
                var metadata = job.CloneCustomMetadata();
                metadata["JobName"] = jobName;
                metadata["WorkItemName"] = wi;
                var consoleUri = HelixApi.BaseUri.AbsoluteUri.TrimEnd('/') + $"/api/2019-06-17/jobs/{jobName}/workitems/{Uri.EscapeDataString(wi)}/console";
                metadata["ConsoleOutputUri"] = consoleUri;

                try
                {
                    var files = await HelixApi.RetryAsync(
                        () => HelixApi.WorkItem.ListFilesAsync(wi, jobName, cancellationToken),
                        LogExceptionRetry,
                        cancellationToken);

                    if (!string.IsNullOrEmpty(AccessToken))
                    {
                        // Add AccessToken to all file links because the api requires auth if we submitted the job with auth
                        files = files
                                .Select(file => new UploadedFile(file.Name, file.Link + "?access_token=" + AccessToken))
                                .ToImmutableList();
                    }

                    metadata["UploadedFiles"] = JsonConvert.SerializeObject(files);
                }
                catch (Exception ex)
                {
                    Log.LogWarningFromException(ex);
                }

                return new TaskItem($"{jobName}/{wi}", metadata);
            })));
        }
        private async Task CheckHelixJobAsync(HttpClient client, string jobName, string testRunId, CancellationToken cancellationToken)
        {
            await Task.Yield();

            cancellationToken.ThrowIfCancellationRequested();
            Log.LogMessage($"Checking status of job {jobName}");
            var status = await HelixApi.RetryAsync(
                () => HelixApi.Job.PassFailAsync(jobName, cancellationToken),
                LogExceptionRetry,
                cancellationToken);

            if (status.Working > 0)
            {
                Log.LogError(
                    $"This task can only be used on completed jobs. There are {status.Working} of {status.Total} unfinished work items.");
                return;
            }
            if (FailOnWorkItemFailure)
            {
                foreach (string failedWorkItem in status.Failed)
                {
                    var consoleUri = HelixApi.BaseUri.AbsoluteUri.TrimEnd('/') + $"/api/2019-06-17/jobs/{jobName}/workitems/{Uri.EscapeDataString(failedWorkItem)}/console";

                    Log.LogError($"Work item {failedWorkItem} in job {jobName} has failed, logs available here: {consoleUri}.");

                    var testResultId = await CreateFakeTestResultAsync(client, testRunId, failedWorkItem);

                    string fileStreamString = await GetUploadedFilesAsync(jobName, failedWorkItem, cancellationToken);

                    if (fileStreamString != null)
                    {
                        await AttachResultFileToTestResultAsync(client, testRunId, testResultId, fileStreamString);
                    }
                }
            }

            if (FailOnMissionControlTestFailure)
            {
                for (; ; await Task.Delay(10000, cancellationToken)) // delay every time this loop repeats
                {
                    if (await MissionControlTestProcessingDoneAsync(jobName, cancellationToken))
                    {
                        break;
                    }

                    Log.LogMessage($"Job {jobName} is still processing xunit results.");
                    cancellationToken.ThrowIfCancellationRequested();
                }
            }
        }
Esempio n. 6
0
        private async Task CheckHelixJobAsync(string jobName)
        {
            await Task.Yield();

            Log.LogMessage($"Checking status of job {jobName}");
            var workItems = await HelixApi.RetryAsync(
                () => HelixApi.WorkItem.ListAsync(jobName),
                LogExceptionRetry);

            var waitingCount = workItems.Count(wi => wi.State == "Waiting");
            var runningCount = workItems.Count(wi => wi.State == "Running");

            if (waitingCount != 0 || runningCount != 0)
            {
                Log.LogError(
                    $"This task can only be used on completed jobs. There are {waitingCount} waiting and {runningCount} running work items.");
                return;
            }
            if (FailOnWorkItemFailure)
            {
                // determines whether any of the work items failed (fireballed)
                // Doing these all in parallel overloads the Helix server
                foreach (var wi in workItems)
                {
                    await CheckForWorkItemFailureAsync(wi.Name, jobName);
                }
            }

            if (FailOnMissionControlTestFailure)
            {
                for (; ; await Task.Delay(10000)) // delay every time this loop repeats
                {
                    if (await MissionControlTestProcessingDoneAsync(jobName))
                    {
                        break;
                    }

                    Log.LogMessage($"Job {jobName} is still processing xunit results.");
                }
            }
        }
Esempio n. 7
0
        private async Task CheckForWorkItemFailureAsync(string workItemName, string jobName)
        {
            await Task.Yield();

            try
            {
                var details = await HelixApi.RetryAsync(
                    () => HelixApi.WorkItem.DetailsAsync(jobName, workItemName),
                    LogExceptionRetry);

                if (details.State == "Failed")
                {
                    Log.LogError(
                        $"Work item {workItemName} on job {jobName} has failed with exit code {details.ExitCode}.");
                }
            }
            catch (Exception ex)
            {
                Log.LogError($"Unable to get work item status for '{workItemName}', assuming failure. Exception: {ex}");
            }
        }
        private async Task <string> GetUploadedFilesAsync(string jobName, string workItemFriendlyName, CancellationToken cancellationToken)
        {
            cancellationToken.ThrowIfCancellationRequested();
            Log.LogMessage($"Looking up files for work item {workItemFriendlyName} in job {jobName}");

            try
            {
                var uploadedFiles = await HelixApi.RetryAsync(
                    () => HelixApi.WorkItem.ListFilesAsync(workItemFriendlyName, jobName, cancellationToken),
                    LogExceptionRetry,
                    cancellationToken);

                if (uploadedFiles.Count > 0)
                {
                    using (var ms = new MemoryStream())
                    {
                        TextWriter tw = new StreamWriter(ms);

                        tw.WriteLine("<ul>");
                        foreach (var uploadedFile in uploadedFiles)
                        {
                            tw.WriteLine($"<li><a href='{uploadedFile.Link}' target='_blank'>{uploadedFile.Name}</a></li>");
                        }
                        tw.WriteLine("</ul>");

                        tw.Flush();
                        ms.Position = 0;
                        return(Convert.ToBase64String(ms.ToArray()));
                    }
                }

                return(null);
            }
            catch (Exception ex)
            {
                Log.LogErrorFromException(ex);
                return(null);
            }
        }
Esempio n. 9
0
        private async Task WaitForHelixJobAsync(string jobName)
        {
            await Task.Yield();

            Log.LogMessage($"Waiting for completion of job {jobName}");

            for (;; await Task.Delay(10000)) // delay every time this loop repeats
            {
                var workItems = await HelixApi.RetryAsync(
                    () => HelixApi.WorkItem.ListAsync(jobName),
                    LogExceptionRetry);

                var waitingCount  = workItems.Count(wi => wi.State == "Waiting");
                var runningCount  = workItems.Count(wi => wi.State == "Running");
                var finishedCount = workItems.Count(wi => wi.State == "Finished");
                if (waitingCount == 0 && runningCount == 0 && finishedCount > 0)
                {
                    if (FailOnWorkItemFailure)
                    {
                        // determines whether any of the work items failed (fireballed)
                        await Task.WhenAll(workItems.Select(wi => CheckForWorkItemFailureAsync(wi.Name, jobName)));
                    }

                    if (FailOnMissionControlTestFailure)
                    {
                        if (!(await MissionControlTestProcessingDoneAsync(jobName)))
                        {
                            Log.LogMessage($"Job {jobName} is still processing xunit results.");
                            continue;
                        }
                    }

                    Log.LogMessage(MessageImportance.High, $"Job {jobName} is completed with {finishedCount} finished work items.");
                    return;
                }

                Log.LogMessage($"Job {jobName} is not yet completed with Waiting: {waitingCount}, Running: {runningCount}, Finished: {finishedCount}");
            }
        }
Esempio n. 10
0
        private async Task WaitForHelixJobAsync(string jobName)
        {
            await Task.Yield();

            Log.LogMessage(MessageImportance.High, $"Waiting for completion of job {jobName}");

            for (;; await Task.Delay(10000)) // delay every time this loop repeats
            {
                var workItems = await HelixApi.RetryAsync(
                    () => HelixApi.WorkItem.ListAsync(jobName),
                    LogExceptionRetry);

                var waitingCount  = workItems.Count(wi => wi.State == "Waiting");
                var runningCount  = workItems.Count(wi => wi.State == "Running");
                var finishedCount = workItems.Count(wi => wi.State == "Finished");
                if (waitingCount == 0 && runningCount == 0 && finishedCount > 0)
                {
                    Log.LogMessage(MessageImportance.High, $"Job {jobName} is completed with {finishedCount} finished work items.");
                    return;
                }

                Log.LogMessage($"Job {jobName} is not yet completed with Waiting: {waitingCount}, Running: {runningCount}, Finished: {finishedCount}");
            }
        }
Esempio n. 11
0
        private async Task CheckHelixJobAsync(string jobName)
        {
            await Task.Yield();

            Log.LogMessage($"Checking status of job {jobName}");
            var status = await HelixApi.RetryAsync(
                () => HelixApi.Job.PassFailAsync(jobName),
                LogExceptionRetry);

            if (status.Working > 0)
            {
                Log.LogError(
                    $"This task can only be used on completed jobs. There are {status.Working} of {status.Total} unfinished work items.");
                return;
            }
            if (FailOnWorkItemFailure)
            {
                foreach (string failedWorkItem in status.Failed)
                {
                    Log.LogError($"Work item {failedWorkItem} in job {jobName} has failed.");
                }
            }

            if (FailOnMissionControlTestFailure)
            {
                for (; ; await Task.Delay(10000)) // delay every time this loop repeats
                {
                    if (await MissionControlTestProcessingDoneAsync(jobName))
                    {
                        break;
                    }

                    Log.LogMessage($"Job {jobName} is still processing xunit results.");
                }
            }
        }