Skip to content

Commit

Permalink
feat(playwrighttesting): Add support to publish attachments (#46780)
Browse files Browse the repository at this point in the history
* Add support to upload attachments

* fix tests

* minor comments fixes
  • Loading branch information
puagarwa authored Oct 24, 2024
1 parent 02c5753 commit cf787a1
Show file tree
Hide file tree
Showing 3 changed files with 90 additions and 11 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,13 @@ internal class TestProcessor : ITestProcessor
internal int PassedTestCount { get; set; } = 0;
internal int FailedTestCount { get; set; } = 0;
internal int SkippedTestCount { get; set; } = 0;
internal int TotalArtifactCount { get; set; } = 0;
internal int TotalArtifactSizeInBytes { get; set; } = 0;
internal List<TestResults> TestResults { get; set; } = new List<TestResults>();
internal ConcurrentDictionary<string, RawTestResult?> RawTestResultsMap { get; set; } = new();
internal bool FatalTestExecution { get; set; } = false;
internal TestRunShardDto? _testRunShard;
internal TestResultsUri? _testResultsSasUri;

public TestProcessor(CloudRunMetadata cloudRunMetadata, CIInfo cIInfo, ILogger? logger = null, IDataProcessor? dataProcessor = null, ICloudRunErrorParser? cloudRunErrorParser = null, IServiceClient? serviceClient = null, IConsoleWriter? consoleWriter = null)
{
Expand Down Expand Up @@ -93,15 +96,22 @@ public void TestCaseResultHandler(object? sender, TestResultEventArgs e)
TestResult testResultSource = e.Result;
TestResults? testResult = _dataProcessor.GetTestCaseResultData(testResultSource);
RawTestResult rawResult = DataProcessor.GetRawResultObject(testResultSource);
RawTestResultsMap.TryAdd(testResult.TestExecutionId, rawResult);

// TODO - Send error to blob
_cloudRunErrorParser.HandleScalableRunErrorMessage(testResultSource.ErrorMessage);
_cloudRunErrorParser.HandleScalableRunErrorMessage(testResultSource.ErrorStackTrace);
if (!_cloudRunMetadata.EnableResultPublish)
if (!_cloudRunMetadata.EnableResultPublish || FatalTestExecution)
{
return;
}

// TODO move rawResult upload here same as JS
RawTestResultsMap.TryAdd(testResult.TestExecutionId, rawResult);

// Upload Attachments
UploadAttachment(e, testResult.TestExecutionId);

// Update Test Count
if (testResult != null)
{
TotalTestCount++;
Expand Down Expand Up @@ -143,20 +153,15 @@ public void TestRunCompleteHandler(object? sender, TestRunCompleteEventArgs e)
}
try
{
TestResultsUri? sasUri = _serviceClient.GetTestRunResultsUri();
TestResultsUri? sasUri = CheckAndRenewSasUri();
if (!string.IsNullOrEmpty(sasUri?.Uri))
{
foreach (TestResults testResult in TestResults)
{
if (RawTestResultsMap.TryGetValue(testResult.TestExecutionId!, out RawTestResult? rawResult) && rawResult != null)
{
// Renew the SAS URI if needed
var reporterUtils = new ReporterUtils();
if (sasUri == null || !reporterUtils.IsTimeGreaterThanCurrentPlus10Minutes(sasUri.Uri))
{
sasUri = _serviceClient.GetTestRunResultsUri(); // Create new SAS URI
_logger.Info($"Fetched SAS URI with validity: {sasUri?.ExpiresAt} and access: {sasUri?.AccessLevel}.");
}
sasUri = CheckAndRenewSasUri();
if (sasUri == null)
{
_logger.Warning("SAS URI is empty");
Expand Down Expand Up @@ -189,6 +194,60 @@ public void TestRunCompleteHandler(object? sender, TestRunCompleteEventArgs e)
}

#region Test Processor Helper Methods

private void UploadAttachment(TestResultEventArgs e, string testExecutionId)
{
_testResultsSasUri = CheckAndRenewSasUri();
if (e.Result.Attachments != null)
{
foreach (var attachmentSet in e.Result.Attachments)
{
foreach (var attachmentData in attachmentSet.Attachments)
{
var filePath = attachmentData.Uri.LocalPath;
_logger.Info($"Uploading attachment: {filePath}");
if (!File.Exists( filePath ))
{
_logger.Error($"Attachment file not found: {filePath}");
continue;
}
try
{
// get file size
var fileSize = new FileInfo(filePath).Length;
var cloudFileName = ReporterUtils.GetCloudFileName(filePath, testExecutionId);
if (cloudFileName != null) {
UploadBlobFile(_testResultsSasUri!.Uri!, cloudFileName, filePath);
TotalArtifactCount++;
TotalArtifactSizeInBytes = TotalArtifactSizeInBytes + (int)fileSize;
}
else
{
_logger.Error($"Attachment file Upload Failed: {filePath}");
}
}
catch (Exception ex)
{
var error = $"Cannot Upload '{filePath}' file: {ex.Message}";

_logger.Error(error);
}
}
}
}
}

private TestResultsUri? CheckAndRenewSasUri()
{
var reporterUtils = new ReporterUtils();
if (_testResultsSasUri == null || !reporterUtils.IsTimeGreaterThanCurrentPlus10Minutes(_testResultsSasUri.Uri))
{
_testResultsSasUri = _serviceClient.GetTestRunResultsUri();
_logger.Info($"Fetched SAS URI with validity: {_testResultsSasUri?.ExpiresAt} and access: {_testResultsSasUri?.AccessLevel}.");
}
return _testResultsSasUri;
}

private void EndTestRun(TestRunCompleteEventArgs e)
{
if (_cloudRunMetadata.EnableResultPublish && !FatalTestExecution)
Expand Down Expand Up @@ -227,6 +286,16 @@ private void UploadBuffer(string uri, string buffer, string fileRelativePath)
blobClient.Upload(new BinaryData(bufferBytes), overwrite: true);
_logger.Info($"Uploaded buffer to {fileRelativePath}");
}

private void UploadBlobFile(string uri, string fileRelativePath, string filePath)
{
string cloudFilePath = GetCloudFilePath(uri, fileRelativePath);
BlobClient blobClient = new(new Uri(cloudFilePath));
// Upload filePath to Blob
blobClient.Upload(filePath, overwrite: true);
_logger.Info($"Uploaded file {filePath} to {fileRelativePath}");
}

private TestRunShardDto GetTestRunEndShard(TestRunCompleteEventArgs e)
{
DateTime testRunEndedOn = DateTime.UtcNow;
Expand All @@ -247,7 +316,7 @@ private TestRunShardDto GetTestRunEndShard(TestRunCompleteEventArgs e)
testRunShard.Summary.StartTime = _cloudRunMetadata.TestRunStartTime.ToString("yyyy-MM-ddTHH:mm:ssZ");
testRunShard.Summary.EndTime = testRunEndedOn.ToString("yyyy-MM-ddTHH:mm:ssZ");
testRunShard.Summary.TotalTime = durationInMs;
testRunShard.Summary.UploadMetadata = new UploadMetadata() { NumTestResults = TotalTestCount, NumTotalAttachments = 0, SizeTotalAttachments = 0 };
testRunShard.Summary.UploadMetadata = new UploadMetadata() { NumTestResults = TotalTestCount, NumTotalAttachments = TotalArtifactCount, SizeTotalAttachments = TotalArtifactSizeInBytes };
testRunShard.UploadCompleted = true;
return testRunShard;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

using System;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Security.Cryptography;
using System.Threading.Tasks;
Expand Down Expand Up @@ -114,6 +115,15 @@ internal static string GetCurrentOS()
else
return OSConstants.s_wINDOWS;
}
internal static string? GetCloudFileName(string filePath, string testExecutionId)
{
var fileName = Path.GetFileName(filePath);
if (fileName == null)
{
return null;
}
return $"{testExecutionId}/{fileName}"; // TODO check if we need to add {Guid.NewGuid()} for file with same name
}

internal TokenDetails ParseWorkspaceIdFromAccessToken(JsonWebTokenHandler? jsonWebTokenHandler, string? accessToken)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -355,7 +355,7 @@ public void TestCaseResultHandler_EnableResultPublishFalse_OnlyParseScalableErro
testProcessor.TestCaseResultHandler(sender, new TestResultEventArgs(testResult));

Assert.AreEqual(0, testProcessor.TestResults.Count);
Assert.IsTrue(testProcessor.RawTestResultsMap.Keys.Count == 1);
Assert.IsTrue(testProcessor.RawTestResultsMap.Keys.Count == 0);
Assert.IsTrue(testProcessor.PassedTestCount == 0);
Assert.IsTrue(testProcessor.FailedTestCount == 0);
Assert.IsTrue(testProcessor.SkippedTestCount == 0);
Expand Down

0 comments on commit cf787a1

Please sign in to comment.