Skip to content

Commit 377322d

Browse files
authored
[DocumentIntelligence] Added tests for the batch API (Azure#47556)
1 parent e973e67 commit 377322d

File tree

6 files changed

+300
-3
lines changed

6 files changed

+300
-3
lines changed

sdk/documentintelligence/Azure.AI.DocumentIntelligence/assets.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,5 @@
22
"AssetsRepo": "Azure/azure-sdk-assets",
33
"AssetsRepoPrefixPath": "net",
44
"TagPrefix": "net/documentintelligence/Azure.AI.DocumentIntelligence",
5-
"Tag": "net/documentintelligence/Azure.AI.DocumentIntelligence_c6ca5d0f3d"
5+
"Tag": "net/documentintelligence/Azure.AI.DocumentIntelligence_1586f1c28d"
66
}

sdk/documentintelligence/Azure.AI.DocumentIntelligence/tests/DocumentAssert.cs

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,32 @@ namespace Azure.AI.DocumentIntelligence.Tests
99
{
1010
internal static class DocumentAssert
1111
{
12+
public static void AreEqual(AnalyzeBatchResult expected, AnalyzeBatchResult actual)
13+
{
14+
if (expected == null)
15+
{
16+
Assert.That(actual, Is.Null);
17+
return;
18+
}
19+
20+
Assert.That(actual, Is.Not.Null);
21+
22+
Assert.That(actual.SucceededCount, Is.EqualTo(expected.SucceededCount));
23+
Assert.That(actual.FailedCount, Is.EqualTo(expected.FailedCount));
24+
Assert.That(actual.SkippedCount, Is.EqualTo(expected.SkippedCount));
25+
26+
AreEquivalent(expected.Details, actual.Details);
27+
}
28+
29+
public static void AreEqual(AnalyzeBatchResultDetails expected, AnalyzeBatchResultDetails actual)
30+
{
31+
Assert.That(actual.SourceUri.AbsoluteUri, Is.EqualTo(expected.SourceUri.AbsoluteUri));
32+
Assert.That(actual.ResultUri.AbsoluteUri, Is.EqualTo(expected.ResultUri.AbsoluteUri));
33+
Assert.That(actual.Status, Is.EqualTo(expected.Status));
34+
35+
AreEqual(expected.Error, actual.Error);
36+
}
37+
1238
public static void AreEqual(BlobContentSource expected, BlobContentSource actual)
1339
{
1440
if (expected == null)
@@ -77,6 +103,40 @@ public static void AreEqual(DocumentFieldSchema expected, DocumentFieldSchema ac
77103
AreEquivalent(expected.Properties, actual.Properties);
78104
}
79105

106+
public static void AreEqual(DocumentIntelligenceError expected, DocumentIntelligenceError actual)
107+
{
108+
if (expected == null)
109+
{
110+
Assert.That(actual, Is.Null);
111+
return;
112+
}
113+
114+
Assert.That(actual, Is.Not.Null);
115+
116+
Assert.That(actual.Code, Is.EqualTo(expected.Code));
117+
Assert.That(actual.Message, Is.EqualTo(expected.Message));
118+
Assert.That(actual.Target, Is.EqualTo(expected.Target));
119+
120+
AreEquivalent(expected.Details, actual.Details);
121+
AreEqual(expected.InnerError, actual.InnerError);
122+
}
123+
124+
public static void AreEqual(DocumentIntelligenceInnerError expected, DocumentIntelligenceInnerError actual)
125+
{
126+
if (expected == null)
127+
{
128+
Assert.That(actual, Is.Null);
129+
return;
130+
}
131+
132+
Assert.That(actual, Is.Not.Null);
133+
134+
Assert.That(actual.Code, Is.EqualTo(expected.Code));
135+
Assert.That(actual.Message, Is.EqualTo(expected.Message));
136+
137+
AreEqual(expected.InnerError, actual.InnerError);
138+
}
139+
80140
public static void AreEqual(DocumentModelDetails expected, DocumentModelDetails actual)
81141
{
82142
Assert.That(actual.ModelId, Is.EqualTo(expected.ModelId));
@@ -101,6 +161,26 @@ public static void AreEqual(DocumentTypeDetails expected, DocumentTypeDetails ac
101161
AreEquivalent(expected.FieldSchema, actual.FieldSchema);
102162
}
103163

164+
public static void AreEquivalent(IReadOnlyList<AnalyzeBatchResultDetails> expected, IReadOnlyList<AnalyzeBatchResultDetails> actual)
165+
{
166+
Assert.That(actual.Count, Is.EqualTo(expected.Count));
167+
168+
for (int i = 0; i < actual.Count; i++)
169+
{
170+
AreEqual(expected[i], actual[i]);
171+
}
172+
}
173+
174+
public static void AreEquivalent(IReadOnlyList<DocumentIntelligenceError> expected, IReadOnlyList<DocumentIntelligenceError> actual)
175+
{
176+
Assert.That(actual.Count, Is.EqualTo(expected.Count));
177+
178+
for (int i = 0; i < actual.Count; i++)
179+
{
180+
AreEqual(expected[i], actual[i]);
181+
}
182+
}
183+
104184
public static void AreEquivalent(IReadOnlyDictionary<string, ClassifierDocumentTypeDetails> expected, IReadOnlyDictionary<string, ClassifierDocumentTypeDetails> actual)
105185
{
106186
Assert.That(actual.Count, Is.EqualTo(expected.Count));
Lines changed: 177 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,177 @@
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.Net;
7+
using System.Threading.Tasks;
8+
using Azure.Core.TestFramework;
9+
using NUnit.Framework;
10+
11+
namespace Azure.AI.DocumentIntelligence.Tests
12+
{
13+
[PlaybackOnly("https://github.com/Azure/azure-sdk-for-net/issues/47557")]
14+
public class DocumentBatchLiveTests : DocumentIntelligenceLiveTestBase
15+
{
16+
public DocumentBatchLiveTests(bool isAsync)
17+
: base(isAsync)
18+
{
19+
}
20+
21+
[Test]
22+
public async Task AnalyzeBatchDocuments()
23+
{
24+
var client = CreateDocumentIntelligenceClient();
25+
var sourceContainerUri = new Uri(TestEnvironment.BatchSourceBlobSasUrl);
26+
var resultContainerUri = new Uri(TestEnvironment.BatchResultBlobSasUrl);
27+
var blobSource = new BlobContentSource(sourceContainerUri);
28+
var options = new AnalyzeBatchDocumentsOptions("prebuilt-read", blobSource, resultContainerUri)
29+
{
30+
OverwriteExisting = true
31+
};
32+
33+
var operation = await client.AnalyzeBatchDocumentsAsync(WaitUntil.Completed, options);
34+
35+
Assert.That(operation.HasCompleted);
36+
Assert.That(operation.HasValue);
37+
38+
ValidateAcordAnalyzeBatchResult(operation.Value);
39+
}
40+
41+
[Test]
42+
public async Task GetAnalyzeBatchResult()
43+
{
44+
var client = CreateDocumentIntelligenceClient();
45+
var sourceContainerUri = new Uri(TestEnvironment.BatchSourceBlobSasUrl);
46+
var resultContainerUri = new Uri(TestEnvironment.BatchResultBlobSasUrl);
47+
var blobSource = new BlobContentSource(sourceContainerUri);
48+
var options = new AnalyzeBatchDocumentsOptions("prebuilt-read", blobSource, resultContainerUri)
49+
{
50+
OverwriteExisting = true
51+
};
52+
var startTime = Recording.UtcNow;
53+
54+
var operation = await client.AnalyzeBatchDocumentsAsync(WaitUntil.Completed, options);
55+
var getResponse = await client.GetAnalyzeBatchResultAsync("prebuilt-read", operation.Id);
56+
var operationDetails = getResponse.Value;
57+
58+
Assert.That(operationDetails.ResultId, Is.EqualTo(operation.Id));
59+
Assert.That(operationDetails.Status, Is.EqualTo(DocumentIntelligenceOperationStatus.Succeeded));
60+
Assert.That(operationDetails.CreatedOn, Is.GreaterThan(startTime - TimeSpan.FromHours(4)));
61+
Assert.That(operationDetails.LastUpdatedOn, Is.GreaterThanOrEqualTo(operationDetails.CreatedOn));
62+
Assert.That(operationDetails.PercentCompleted, Is.EqualTo(100));
63+
Assert.That(operationDetails.Error, Is.Null);
64+
65+
DocumentAssert.AreEqual(operation.Value, operationDetails.Result);
66+
}
67+
68+
[Test]
69+
public async Task GetAnalyzeBatchResults()
70+
{
71+
var client = CreateDocumentIntelligenceClient();
72+
var sourceContainerUri = new Uri(TestEnvironment.BatchSourceBlobSasUrl);
73+
var resultContainerUri = new Uri(TestEnvironment.BatchResultBlobSasUrl);
74+
var blobSource = new BlobContentSource(sourceContainerUri);
75+
var options = new AnalyzeBatchDocumentsOptions("prebuilt-read", blobSource, resultContainerUri)
76+
{
77+
OverwriteExisting = true
78+
};
79+
80+
var operation0 = await client.AnalyzeBatchDocumentsAsync(WaitUntil.Completed, options);
81+
var operation1 = await client.AnalyzeBatchDocumentsAsync(WaitUntil.Completed, options);
82+
var getResponse0 = await client.GetAnalyzeBatchResultAsync("prebuilt-read", operation0.Id);
83+
var getResponse1 = await client.GetAnalyzeBatchResultAsync("prebuilt-read", operation1.Id);
84+
85+
var expectedIdMapping = new Dictionary<string, AnalyzeBatchOperationDetails>()
86+
{
87+
{ operation0.Id, getResponse0.Value },
88+
{ operation1.Id, getResponse1.Value }
89+
};
90+
var idMapping = new Dictionary<string, AnalyzeBatchOperationDetails>();
91+
92+
await foreach (AnalyzeBatchOperationDetails operation in client.GetAnalyzeBatchResultsAsync("prebuilt-read"))
93+
{
94+
if (expectedIdMapping.ContainsKey(operation.ResultId))
95+
{
96+
idMapping.Add(operation.ResultId, operation);
97+
}
98+
99+
if (idMapping.Count == expectedIdMapping.Count)
100+
{
101+
break;
102+
}
103+
}
104+
105+
Assert.That(idMapping.Count, Is.EqualTo(expectedIdMapping.Count));
106+
107+
foreach (string id in expectedIdMapping.Keys)
108+
{
109+
Assert.That(idMapping, Contains.Key(id));
110+
111+
AnalyzeBatchOperationDetails expected = expectedIdMapping[id];
112+
AnalyzeBatchOperationDetails actual = idMapping[id];
113+
114+
Assert.That(actual.ResultId, Is.EqualTo(expected.ResultId));
115+
Assert.That(actual.Status, Is.EqualTo(expected.Status));
116+
Assert.That(actual.CreatedOn, Is.EqualTo(expected.CreatedOn));
117+
Assert.That(actual.LastUpdatedOn, Is.EqualTo(expected.LastUpdatedOn));
118+
Assert.That(actual.PercentCompleted, Is.Null);
119+
120+
DocumentAssert.AreEqual(actual.Error, expected.Error);
121+
}
122+
}
123+
124+
[Test]
125+
public async Task DeleteAnalyzeBatchResult()
126+
{
127+
var client = CreateDocumentIntelligenceClient();
128+
var sourceContainerUri = new Uri(TestEnvironment.BatchSourceBlobSasUrl);
129+
var resultContainerUri = new Uri(TestEnvironment.BatchResultBlobSasUrl);
130+
var blobSource = new BlobContentSource(sourceContainerUri);
131+
var options = new AnalyzeBatchDocumentsOptions("prebuilt-read", blobSource, resultContainerUri)
132+
{
133+
OverwriteExisting = true
134+
};
135+
136+
var operation = await client.AnalyzeBatchDocumentsAsync(WaitUntil.Completed, options);
137+
var response = await client.DeleteAnalyzeBatchResultAsync("prebuilt-read", operation.Id);
138+
139+
Assert.That(response.Status, Is.EqualTo((int)HttpStatusCode.NoContent));
140+
}
141+
142+
private void ValidateAcordAnalyzeBatchResult(AnalyzeBatchResult result)
143+
{
144+
Assert.That(result.SucceededCount, Is.EqualTo(6));
145+
Assert.That(result.FailedCount, Is.EqualTo(0));
146+
Assert.That(result.SkippedCount, Is.EqualTo(0));
147+
148+
string expectedSourcePrefix = string.Empty;
149+
string expectedResultPrefix = string.Empty;
150+
151+
// We can't validate this in Playback mode since these environment variables
152+
// are not stored when recording.
153+
154+
if (Mode == RecordedTestMode.Live)
155+
{
156+
int sourceQueryStart = TestEnvironment.BatchSourceBlobSasUrl.IndexOf('?');
157+
int resultQueryStart = TestEnvironment.BatchResultBlobSasUrl.IndexOf('?');
158+
159+
expectedSourcePrefix = (sourceQueryStart == -1)
160+
? TestEnvironment.BatchSourceBlobSasUrl
161+
: TestEnvironment.BatchSourceBlobSasUrl.Substring(0, sourceQueryStart);
162+
163+
expectedResultPrefix = (resultQueryStart == -1)
164+
? TestEnvironment.BatchResultBlobSasUrl
165+
: TestEnvironment.BatchResultBlobSasUrl.Substring(0, resultQueryStart);
166+
}
167+
168+
foreach (var details in result.Details)
169+
{
170+
Assert.That(details.SourceUri.AbsoluteUri, Does.StartWith(expectedSourcePrefix));
171+
Assert.That(details.ResultUri.AbsoluteUri, Does.StartWith(expectedResultPrefix));
172+
Assert.That(details.Status, Is.EqualTo(DocumentIntelligenceOperationStatus.Succeeded));
173+
Assert.That(details.Error, Is.Null);
174+
}
175+
}
176+
}
177+
}

sdk/documentintelligence/Azure.AI.DocumentIntelligence/tests/Infrastructure/DocumentIntelligenceLiveTestBase.cs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,14 @@ namespace Azure.AI.DocumentIntelligence.Tests
1111
{
1212
public class DocumentIntelligenceLiveTestBase : RecordedTestBase<DocumentIntelligenceTestEnvironment>
1313
{
14+
private const string SanitizedContainerUri = "https://sanitized.blob.core.windows.net";
15+
1416
public DocumentIntelligenceLiveTestBase(bool isAsync, RecordedTestMode? mode = null)
1517
: base(isAsync, mode)
1618
{
1719
JsonPathSanitizers.Add("$..accessToken");
18-
BodyKeySanitizers.Add(new BodyKeySanitizer("$..containerUrl") { Value = "https://sanitized.blob.core.windows.net" });
20+
BodyKeySanitizers.Add(new BodyKeySanitizer("$..containerUrl") { Value = SanitizedContainerUri });
21+
BodyKeySanitizers.Add(new BodyKeySanitizer("$..resultContainerUrl") { Value = SanitizedContainerUri });
1922
SanitizedHeaders.Add("Ocp-Apim-Subscription-Key");
2023
}
2124

sdk/documentintelligence/Azure.AI.DocumentIntelligence/tests/Infrastructure/DocumentIntelligenceTestEnvironment.cs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
using System.Reflection;
77
using System.Threading.Tasks;
88
using Azure.Core.TestFramework;
9-
using Azure.Identity;
109

1110
namespace Azure.AI.DocumentIntelligence.Tests
1211
{
@@ -34,6 +33,10 @@ public class DocumentIntelligenceTestEnvironment : TestEnvironment
3433

3534
public string ClassifierTrainingSasUrl => GetRecordedVariable("CLASSIFIER_BLOB_CONTAINER_SAS_URL", options => options.IsSecret(SanitizedSasUrl));
3635

36+
public string BatchSourceBlobSasUrl => GetRecordedVariable("BATCH_SOURCE_BLOB_CONTAINER_SAS_URL", options => options.IsSecret(SanitizedSasUrl));
37+
38+
public string BatchResultBlobSasUrl => GetRecordedVariable("BATCH_RESULT_BLOB_CONTAINER_SAS_URL", options => options.IsSecret(SanitizedSasUrl));
39+
3740
public static string CreatePath(string filename)
3841
{
3942
return Path.Combine(s_currentWorkingDirectory, AssetsFolderName, filename);

sdk/documentintelligence/test-resources.json

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,14 @@
4242
"type": "string",
4343
"defaultValue": "training-data-classifier"
4444
},
45+
"batchSourceContainer": {
46+
"type": "string",
47+
"defaultValue": "trainingdata-batch"
48+
},
49+
"batchResultContainer": {
50+
"type": "string",
51+
"defaultValue": "trainingdata-batch-result"
52+
},
4553
"trainingDataResourceId": {
4654
"type": "string",
4755
"defaultValue": "[resourceId('static-test-resources', 'Microsoft.Storage/storageAccounts', parameters('trainingDataAccount'))]"
@@ -63,6 +71,24 @@
6371
"signedPermission": "rl",
6472
"signedResource": "c"
6573
}
74+
},
75+
"batchSourceSasProperties": {
76+
"type": "object",
77+
"defaultValue": {
78+
"canonicalizedResource": "[concat('/blob/', parameters('trainingDataAccount'), '/', parameters('batchSourceContainer'))]",
79+
"signedExpiry": "[dateTimeAdd(utcNow('u'), 'PT2H')]",
80+
"signedPermission": "rwdl",
81+
"signedResource": "c"
82+
}
83+
},
84+
"batchResultSasProperties": {
85+
"type": "object",
86+
"defaultValue": {
87+
"canonicalizedResource": "[concat('/blob/', parameters('trainingDataAccount'), '/', parameters('batchResultContainer'))]",
88+
"signedExpiry": "[dateTimeAdd(utcNow('u'), 'PT2H')]",
89+
"signedPermission": "rwdl",
90+
"signedResource": "c"
91+
}
6692
}
6793
},
6894
"variables": {
@@ -118,6 +144,14 @@
118144
"CLASSIFIER_BLOB_CONTAINER_SAS_URL": {
119145
"type": "string",
120146
"value": "[concat(reference(parameters('trainingDataResourceId'), '2019-06-01').primaryEndpoints.blob, parameters('classifierTrainingDataContainer'), '?', listServiceSas(parameters('trainingDataResourceId'), '2019-06-01', parameters('classifierTrainingSasProperties')).serviceSasToken)]"
147+
},
148+
"BATCH_SOURCE_BLOB_CONTAINER_SAS_URL": {
149+
"type": "string",
150+
"value": "[concat(reference(parameters('trainingDataResourceId'), '2019-06-01').primaryEndpoints.blob, parameters('batchSourceContainer'), '?', listServiceSas(parameters('trainingDataResourceId'), '2019-06-01', parameters('batchSourceSasProperties')).serviceSasToken)]"
151+
},
152+
"BATCH_RESULT_BLOB_CONTAINER_SAS_URL": {
153+
"type": "string",
154+
"value": "[concat(reference(parameters('trainingDataResourceId'), '2019-06-01').primaryEndpoints.blob, parameters('batchResultContainer'), '?', listServiceSas(parameters('trainingDataResourceId'), '2019-06-01', parameters('batchResultSasProperties')).serviceSasToken)]"
121155
}
122156
}
123157
}

0 commit comments

Comments
 (0)