Skip to content

Commit 52190ed

Browse files
kashish2508guptakashish
andauthored
fix(playwrighttesting): Using dependency injection instead of BlobClient in TestProcessor (Azure#46807)
* fix(playwrighttesting): Using dependency injection instead of BlobClient in TestProcessor * update * update * removed previous commit * added test for bobService * update * update test * added test for sas uri. * updated UploadBlobFile * update --------- Co-authored-by: guptakashish <[email protected]>
1 parent 63e086e commit 52190ed

File tree

6 files changed

+187
-39
lines changed

6 files changed

+187
-39
lines changed
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
// Copyright (c) Microsoft Corporation. All rights reserved.
2+
// Licensed under the MIT License.
3+
4+
using System;
5+
using System.Collections.Generic;
6+
using System.Text;
7+
using Azure.Developer.MicrosoftPlaywrightTesting.TestLogger.Interface;
8+
using Azure.Storage.Blobs;
9+
using System.Threading.Tasks;
10+
using System.IO;
11+
12+
namespace Azure.Developer.MicrosoftPlaywrightTesting.TestLogger.Implementation
13+
{
14+
internal class BlobService:IBlobService
15+
{
16+
private readonly ILogger _logger;
17+
18+
public BlobService(ILogger? logger)
19+
{
20+
_logger = logger ?? new Logger();
21+
}
22+
23+
public async Task UploadBufferAsync(string uri, string buffer, string fileRelativePath)
24+
{
25+
try
26+
{
27+
string cloudFilePath = GetCloudFilePath(uri, fileRelativePath);
28+
BlobClient blobClient = new(new Uri(cloudFilePath));
29+
byte[] bufferBytes = Encoding.UTF8.GetBytes(buffer);
30+
await blobClient.UploadAsync(new BinaryData(bufferBytes), overwrite: true).ConfigureAwait(false);
31+
_logger.Info($"Uploaded buffer to {fileRelativePath}");
32+
}
33+
catch (Exception ex)
34+
{
35+
_logger.Error($"Failed to upload buffer: {ex}");
36+
}
37+
}
38+
public void UploadBlobFile(string uri, string fileRelativePath, string filePath)
39+
{
40+
string cloudFilePath = GetCloudFilePath(uri, fileRelativePath);
41+
BlobClient blobClient = new(new Uri(cloudFilePath));
42+
blobClient.Upload(filePath, overwrite: true);
43+
_logger.Info($"Uploaded file {filePath} to {fileRelativePath}");
44+
}
45+
public string GetCloudFilePath(string uri, string fileRelativePath)
46+
{
47+
string[] parts = uri.Split(new string[] { ReporterConstants.s_sASUriSeparator }, StringSplitOptions.None);
48+
string containerUri = parts[0];
49+
string sasToken = parts.Length > 1 ? parts[1] : string.Empty;
50+
51+
return $"{containerUri}/{fileRelativePath}?{sasToken}";
52+
}
53+
public string? GetCloudFileName(string filePath, string testExecutionId)
54+
{
55+
var fileName = Path.GetFileName(filePath);
56+
if (fileName == null)
57+
{
58+
return null;
59+
}
60+
return $"{testExecutionId}/{fileName}"; // TODO check if we need to add {Guid.NewGuid()} for file with same name
61+
}
62+
}
63+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
// Copyright (c) Microsoft Corporation. All rights reserved.
2+
// Licensed under the MIT License.
3+
4+
using System.Threading.Tasks;
5+
namespace Azure.Developer.MicrosoftPlaywrightTesting.TestLogger.Interface
6+
{
7+
internal interface IBlobService
8+
{
9+
/// <summary>
10+
///
11+
/// </summary>
12+
/// <param name="uri"></param>
13+
/// <param name="buffer"></param>
14+
/// <param name="fileRelativePath"></param>
15+
/// <returns>A <see cref="Task"/> representing the result of the asynchronous operation.</returns>
16+
Task UploadBufferAsync(string uri, string buffer, string fileRelativePath);
17+
string GetCloudFilePath(string uri, string fileRelativePath);
18+
void UploadBlobFile(string uri, string fileRelativePath, string filePath);
19+
public string? GetCloudFileName(string filePath, string testExecutionId);
20+
}
21+
}

sdk/playwrighttesting/Azure.Developer.MicrosoftPlaywrightTesting.TestLogger/src/Processor/TestProcessor.cs

Lines changed: 8 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
using System.IO;
88
using System.Text;
99
using System.Text.Json;
10+
using System.Threading.Tasks;
1011
using Azure.Developer.MicrosoftPlaywrightTesting.TestLogger.Implementation;
1112
using Azure.Developer.MicrosoftPlaywrightTesting.TestLogger.Interface;
1213
using Azure.Developer.MicrosoftPlaywrightTesting.TestLogger.Model;
@@ -28,6 +29,7 @@ internal class TestProcessor : ITestProcessor
2829
private readonly IConsoleWriter _consoleWriter;
2930
private readonly CIInfo _cIInfo;
3031
private readonly CloudRunMetadata _cloudRunMetadata;
32+
private readonly IBlobService _blobService;
3133

3234
// Test Metadata
3335
internal int TotalTestCount { get; set; } = 0;
@@ -42,7 +44,7 @@ internal class TestProcessor : ITestProcessor
4244
internal TestRunShardDto? _testRunShard;
4345
internal TestResultsUri? _testResultsSasUri;
4446

45-
public TestProcessor(CloudRunMetadata cloudRunMetadata, CIInfo cIInfo, ILogger? logger = null, IDataProcessor? dataProcessor = null, ICloudRunErrorParser? cloudRunErrorParser = null, IServiceClient? serviceClient = null, IConsoleWriter? consoleWriter = null)
47+
public TestProcessor(CloudRunMetadata cloudRunMetadata, CIInfo cIInfo, ILogger? logger = null, IDataProcessor? dataProcessor = null, ICloudRunErrorParser? cloudRunErrorParser = null, IServiceClient? serviceClient = null, IConsoleWriter? consoleWriter = null, IBlobService? blobService = null)
4648
{
4749
_cloudRunMetadata = cloudRunMetadata;
4850
_cIInfo = cIInfo;
@@ -51,6 +53,7 @@ public TestProcessor(CloudRunMetadata cloudRunMetadata, CIInfo cIInfo, ILogger?
5153
_cloudRunErrorParser = cloudRunErrorParser ?? new CloudRunErrorParser(_logger);
5254
_serviceClient = serviceClient ?? new ServiceClient(_cloudRunMetadata, _cloudRunErrorParser);
5355
_consoleWriter = consoleWriter ?? new ConsoleWriter();
56+
_blobService = blobService ?? new BlobService(_logger);
5457
}
5558

5659
public void TestRunStartHandler(object? sender, TestRunStartEventArgs e)
@@ -171,7 +174,7 @@ public void TestRunCompleteHandler(object? sender, TestRunCompleteEventArgs e)
171174
// Upload rawResult to blob storage using sasUri
172175
var rawTestResultJson = JsonSerializer.Serialize(rawResult);
173176
var filePath = $"{testResult.TestExecutionId}/rawTestResult.json";
174-
UploadBuffer(sasUri!.Uri!, rawTestResultJson, filePath);
177+
_blobService.UploadBufferAsync(sasUri!.Uri!, rawTestResultJson, filePath);
175178
}
176179
else
177180
{
@@ -215,9 +218,9 @@ private void UploadAttachment(TestResultEventArgs e, string testExecutionId)
215218
{
216219
// get file size
217220
var fileSize = new FileInfo(filePath).Length;
218-
var cloudFileName = ReporterUtils.GetCloudFileName(filePath, testExecutionId);
221+
var cloudFileName = _blobService.GetCloudFileName(filePath, testExecutionId);
219222
if (cloudFileName != null) {
220-
UploadBlobFile(_testResultsSasUri!.Uri!, cloudFileName, filePath);
223+
_blobService.UploadBlobFile(_testResultsSasUri!.Uri!, cloudFileName, filePath);
221224
TotalArtifactCount++;
222225
TotalArtifactSizeInBytes = TotalArtifactSizeInBytes + (int)fileSize;
223226
}
@@ -237,7 +240,7 @@ private void UploadAttachment(TestResultEventArgs e, string testExecutionId)
237240
}
238241
}
239242

240-
private TestResultsUri? CheckAndRenewSasUri()
243+
internal TestResultsUri? CheckAndRenewSasUri()
241244
{
242245
var reporterUtils = new ReporterUtils();
243246
if (_testResultsSasUri == null || !reporterUtils.IsTimeGreaterThanCurrentPlus10Minutes(_testResultsSasUri.Uri))
@@ -270,31 +273,6 @@ private void EndTestRun(TestRunCompleteEventArgs e)
270273
}
271274
_cloudRunErrorParser.DisplayMessages();
272275
}
273-
private static string GetCloudFilePath(string uri, string fileRelativePath)
274-
{
275-
string[] parts = uri.Split(new string[] { ReporterConstants.s_sASUriSeparator }, StringSplitOptions.None);
276-
string containerUri = parts[0];
277-
string sasToken = parts.Length > 1 ? parts[1] : string.Empty;
278-
279-
return $"{containerUri}/{fileRelativePath}?{sasToken}";
280-
}
281-
private void UploadBuffer(string uri, string buffer, string fileRelativePath)
282-
{
283-
string cloudFilePath = GetCloudFilePath(uri, fileRelativePath);
284-
BlobClient blobClient = new(new Uri(cloudFilePath));
285-
byte[] bufferBytes = Encoding.UTF8.GetBytes(buffer);
286-
blobClient.Upload(new BinaryData(bufferBytes), overwrite: true);
287-
_logger.Info($"Uploaded buffer to {fileRelativePath}");
288-
}
289-
290-
private void UploadBlobFile(string uri, string fileRelativePath, string filePath)
291-
{
292-
string cloudFilePath = GetCloudFilePath(uri, fileRelativePath);
293-
BlobClient blobClient = new(new Uri(cloudFilePath));
294-
// Upload filePath to Blob
295-
blobClient.Upload(filePath, overwrite: true);
296-
_logger.Info($"Uploaded file {filePath} to {fileRelativePath}");
297-
}
298276

299277
private TestRunShardDto GetTestRunEndShard(TestRunCompleteEventArgs e)
300278
{

sdk/playwrighttesting/Azure.Developer.MicrosoftPlaywrightTesting.TestLogger/src/Utility/ReporterUtils.cs

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -115,15 +115,6 @@ internal static string GetCurrentOS()
115115
else
116116
return OSConstants.s_wINDOWS;
117117
}
118-
internal static string? GetCloudFileName(string filePath, string testExecutionId)
119-
{
120-
var fileName = Path.GetFileName(filePath);
121-
if (fileName == null)
122-
{
123-
return null;
124-
}
125-
return $"{testExecutionId}/{fileName}"; // TODO check if we need to add {Guid.NewGuid()} for file with same name
126-
}
127118

128119
internal TokenDetails ParseWorkspaceIdFromAccessToken(JsonWebTokenHandler? jsonWebTokenHandler, string? accessToken)
129120
{
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
// Copyright (c) Microsoft Corporation. All rights reserved.
2+
// Licensed under the MIT License.
3+
4+
using System.Text;
5+
using System.Threading.Tasks;
6+
using Azure.Developer.MicrosoftPlaywrightTesting.TestLogger.Implementation;
7+
using Azure.Developer.MicrosoftPlaywrightTesting.TestLogger.Interface;
8+
using Moq;
9+
using NUnit.Framework;
10+
11+
namespace Azure.Developer.MicrosoftPlaywrightTesting.TestLogger.Tests.Implementation
12+
{
13+
[TestFixture]
14+
[Parallelizable(ParallelScope.Self)]
15+
public class BlobServiceTests
16+
{
17+
private Mock<ILogger>? _loggerMock;
18+
private BlobService? _blobService;
19+
20+
[SetUp]
21+
public void Setup()
22+
{
23+
_loggerMock = new Mock<ILogger>();
24+
_blobService = new BlobService(_loggerMock.Object);
25+
}
26+
[Test]
27+
public async Task UploadBufferAsync_WithException_LogsError()
28+
{
29+
string uri = "invalid_uri";
30+
string buffer = "Test buffer";
31+
string fileRelativePath = "test/path";
32+
33+
await _blobService!.UploadBufferAsync(uri, buffer, fileRelativePath);
34+
35+
_loggerMock!.Verify(logger => logger.Error(It.IsAny<string>()), Times.Once);
36+
}
37+
38+
[Test]
39+
public void GetCloudFilePath_WithValidParameters_ReturnsCorrectPath()
40+
{
41+
string uri = "https://example.com/container";
42+
string fileRelativePath = "test/path";
43+
string expectedPath = "https://example.com/container/test/path?";
44+
45+
string? result = _blobService?.GetCloudFilePath(uri, fileRelativePath);
46+
47+
Assert.AreEqual(expectedPath, result);
48+
}
49+
50+
[Test]
51+
public void GetCloudFilePath_WithSasUri_ReturnsCorrectPath()
52+
{
53+
string uri = "https://example.com/container?sasToken";
54+
string fileRelativePath = "test/path";
55+
string expectedPath = "https://example.com/container/test/path?sasToken";
56+
57+
string? result = _blobService?.GetCloudFilePath(uri, fileRelativePath);
58+
59+
Assert.AreEqual(expectedPath, result);
60+
}
61+
}
62+
}

sdk/playwrighttesting/Azure.Developer.MicrosoftPlaywrightTesting.TestLogger/tests/Processor/TestProcessorTests.cs

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -580,5 +580,38 @@ public void TestRunCompleteHandler_EnableResultPublishSetToFalse_DisplaysMessage
580580
serviceClientMock.Verify(c => c.PostTestRunShardInfo(It.IsAny<TestRunShardDto>()), Times.Never);
581581
cloudRunErrorParserMock.Verify(c => c.DisplayMessages(), Times.Exactly(1));
582582
}
583+
[Test]
584+
public void CheckAndRenewSasUri_WhenUriExpired_FetchesNewSasUri()
585+
{
586+
var loggerMock = new Mock<ILogger>();
587+
var dataProcessorMock = new Mock<IDataProcessor>();
588+
var consoleWriterMock = new Mock<IConsoleWriter>();
589+
var cloudRunErrorParserMock = new Mock<ICloudRunErrorParser>();
590+
var serviceClientMock = new Mock<IServiceClient>();
591+
var testProcessor = new TestProcessor(_cloudRunMetadata, _cIInfo, loggerMock.Object, dataProcessorMock.Object, cloudRunErrorParserMock.Object, serviceClientMock.Object, consoleWriterMock.Object);
592+
var expiredTestResultsSasUri = new TestResultsUri { Uri = "http://example.com", ExpiresAt = DateTime.UtcNow.AddMinutes(-5).ToString(), AccessLevel = AccessLevel.Read };
593+
var newTestResultsSasUri = new TestResultsUri { Uri = "http://newexample.com", ExpiresAt = DateTime.UtcNow.AddHours(1).ToString(), AccessLevel = AccessLevel.Read };
594+
testProcessor._testResultsSasUri = expiredTestResultsSasUri;
595+
serviceClientMock.Setup(sc => sc.GetTestRunResultsUri()).Returns(newTestResultsSasUri);
596+
TestResultsUri? result = testProcessor.CheckAndRenewSasUri();
597+
Assert.AreEqual(newTestResultsSasUri, result);
598+
loggerMock.Verify(l => l.Info(It.IsAny<string>()), Times.AtLeastOnce);
599+
}
600+
[Test]
601+
public void CheckAndRenewSasUri_WhenUriNotExpired_DoesNotFetchNewSasUri()
602+
{
603+
var loggerMock = new Mock<ILogger>();
604+
var dataProcessorMock = new Mock<IDataProcessor>();
605+
var consoleWriterMock = new Mock<IConsoleWriter>();
606+
var cloudRunErrorParserMock = new Mock<ICloudRunErrorParser>();
607+
var serviceClientMock = new Mock<IServiceClient>();
608+
var testProcessor = new TestProcessor(_cloudRunMetadata, _cIInfo, loggerMock.Object, dataProcessorMock.Object, cloudRunErrorParserMock.Object, serviceClientMock.Object, consoleWriterMock.Object);
609+
var validTestResultsSasUri = new TestResultsUri { Uri = "http://example.com?se=" + DateTime.UtcNow.AddMinutes(15).ToString("o"), ExpiresAt = DateTime.UtcNow.AddMinutes(15).ToString(), AccessLevel = AccessLevel.Read };
610+
testProcessor._testResultsSasUri = validTestResultsSasUri;
611+
TestResultsUri? result = testProcessor.CheckAndRenewSasUri();
612+
Assert.AreEqual(validTestResultsSasUri, result);
613+
serviceClientMock.Verify(sc => sc.GetTestRunResultsUri(), Times.Never);
614+
loggerMock.Verify(l => l.Info(It.IsAny<string>()), Times.Never);
615+
}
583616
}
584617
}

0 commit comments

Comments
 (0)