Skip to content

Commit 7753056

Browse files
committed
test: CosmosExtension for long values
Added unittests with a Cosmos DB connection. Defaults to use a local Cosmos DB emulator connection with a github action to spin one up.
1 parent 8a40d00 commit 7753056

File tree

4 files changed

+155
-8
lines changed

4 files changed

+155
-8
lines changed
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
name: .NET test with Cosmos DB Emulator
2+
on:
3+
workflow_dispatch:
4+
jobs:
5+
unit_tests:
6+
name: Run .NET unit tests
7+
runs-on: windows-latest
8+
steps:
9+
- name: Checkout (GitHub)
10+
uses: actions/checkout@v4
11+
- name: Start Azure Cosmos DB emulator
12+
run: |
13+
Write-Host "Launching Cosmos DB Emulator"
14+
Import-Module "$env:ProgramFiles\Azure Cosmos DB Emulator\PSModules\Microsoft.Azure.CosmosDB.Emulator"
15+
Start-CosmosDbEmulator
16+
- name: Run .NET tests
17+
run: dotnet test -graphBuild:True

Extensions/Cosmos/Cosmos.DataTransfer.CosmosExtension.UnitTests/Cosmos.DataTransfer.CosmosExtension.UnitTests.csproj

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,29 +6,31 @@
66
<Nullable>enable</Nullable>
77

88
<IsPackable>false</IsPackable>
9+
<CollectCoverage>true</CollectCoverage>
10+
<CoverletOutputFormat>cobertura</CoverletOutputFormat>
11+
<CoverletOutput>../Cosmos.DataTransfer.CosmosExtension/coverage.cobertura.xml</CoverletOutput>
912
</PropertyGroup>
1013

1114
<ItemGroup>
1215
<PackageReference Include="Microsoft.Extensions.Configuration" Version="6.0.1" />
1316
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.2.0" />
1417
<PackageReference Include="MSTest.TestAdapter" Version="2.2.10" />
1518
<PackageReference Include="MSTest.TestFramework" Version="2.2.10" />
16-
<PackageReference Include="coverlet.collector" Version="3.1.2" />
1719
<PackageReference Include="System.Linq.Async" Version="6.0.1" />
20+
<PackageReference Include="coverlet.collector" Version="3.1.2" />
21+
<PackageReference Include="coverlet.msbuild" Version="2.8.0">
22+
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
23+
<PrivateAssets>all</PrivateAssets>
24+
</PackageReference>
1825
</ItemGroup>
1926

2027
<ItemGroup>
2128
<ProjectReference Include="..\Cosmos.DataTransfer.CosmosExtension\Cosmos.DataTransfer.CosmosExtension.csproj" />
29+
<ProjectReference Include="..\..\Json\Cosmos.DataTransfer.JsonExtension.UnitTests\Cosmos.DataTransfer.JsonExtension.UnitTests.csproj" />
2230
</ItemGroup>
2331

2432
<ItemGroup>
25-
<None Update="Data\Nested.json">
26-
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
27-
</None>
28-
<None Update="Data\IdName.json">
29-
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
30-
</None>
31-
<None Update="Data\MixedTypes.json">
33+
<None Update="Data\*.json">
3234
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
3335
</None>
3436
</ItemGroup>
Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
using System.Text;
2+
using Cosmos.DataTransfer.Interfaces;
3+
using Cosmos.DataTransfer.JsonExtension.UnitTests;
4+
using Microsoft.Extensions.Logging.Abstractions;
5+
using Microsoft.Azure.Cosmos;
6+
using System.Net;
7+
using System.Net.Sockets;
8+
9+
10+
namespace Cosmos.DataTransfer.CosmosExtension.UnitTests;
11+
12+
[TestClass]
13+
public class CosmosDataSourceExtensionTests : IDisposable
14+
{
15+
readonly CosmosClient cosmosClient;
16+
readonly Database testDatabase;
17+
readonly string connectionString;
18+
readonly Action dismantleTestDb;
19+
20+
// Sets up a connection to CosmosDB.
21+
// Default values here are to a local Cosmos DB emulator.
22+
// Use the two environment variables to pass a custom connection.
23+
public CosmosDataSourceExtensionTests() {
24+
string endpoint = Environment.GetEnvironmentVariable("Cosmos_Endpoint") ?? "https://localhost:8081/";
25+
string accountKey = Environment.GetEnvironmentVariable("Cosmos_Key") ?? "C2y6yDjf5/R+ob0N8A7Cgv30VRDJIWEHLM+4QDU5DE2nQ9nDuVTqobD4b8mGGyPMbIZnqyMsEcaGQy67XIw/Jw==";
26+
this.connectionString = $"AccountEndpoint={endpoint};AccountKey={accountKey};";
27+
28+
var fullname = this.GetType().Assembly.ManifestModule.Name;
29+
var dbname = this.GetType().Name + "-" + Guid.NewGuid().ToString().Substring(0, 8);
30+
31+
CosmosClient client = new(
32+
accountEndpoint: endpoint,
33+
authKeyOrResourceToken: accountKey,
34+
new CosmosClientOptions {
35+
ApplicationName = fullname
36+
}
37+
);
38+
this.cosmosClient = client;
39+
40+
//var account = client.ReadAccountAsync().Result;
41+
42+
var db = client.CreateDatabaseAsync(dbname, (int?)null, new RequestOptions()).Result;
43+
this.testDatabase = db.Database;
44+
this.dismantleTestDb = () => {
45+
try {
46+
db.Database.DeleteAsync().Wait();
47+
} catch (CosmosException e) when (e.StatusCode == HttpStatusCode.NotFound) {
48+
// Do nothing.
49+
}
50+
};
51+
}
52+
53+
public void Dispose()
54+
{
55+
dismantleTestDb();
56+
}
57+
58+
[TestMethod]
59+
public async Task Test_Json_RoundTrip_WithLongValues() {
60+
var config = TestHelpers.CreateConfig(new Dictionary<string,string>() {
61+
{ "UseRbacAuth", "false" },
62+
{ "ConnectionString", this.connectionString },
63+
{ "Database", this.testDatabase.Id },
64+
{ "Container", "Test_Json_RoundTrip_WithLongValues" },
65+
{ "RecreateContainer", "true" },
66+
{ "PartitionKeyPath", "/partitionKey" }
67+
});
68+
69+
var sourceExtension = new CosmosDataSourceExtension();
70+
var sinkExtension = new CosmosDataSinkExtension();
71+
var items = new CosmosDictionaryDataItem[] {
72+
new CosmosDictionaryDataItem(new Dictionary<string, object?> {
73+
{ "partitionKey", "pk" },
74+
{ "id", "1" },
75+
{ "long", 638676324052177500L }
76+
})
77+
};
78+
79+
await sinkExtension.WriteAsync(items.ToAsyncEnumerable(), config,
80+
sourceExtension, NullLogger.Instance);
81+
82+
var fetched = await sourceExtension.ReadAsync(config, NullLogger.Instance).ToArrayAsync();
83+
Assert.AreEqual(1, fetched.Length);
84+
Assert.IsInstanceOfType(fetched[0].GetValue("long"), typeof(long));
85+
Assert.AreEqual(items[0].Items["long"], fetched[0].GetValue("long"));
86+
87+
var jsonSink = new JsonExtension.JsonFormatWriter();
88+
89+
var writer = new MemoryStream(500);
90+
await jsonSink.FormatDataAsync(fetched.ToAsyncEnumerable(), writer, config, NullLogger.Instance);
91+
var res = Encoding.UTF8.GetString(writer.ToArray());
92+
Assert.AreEqual("[{\"partitionKey\":\"pk\",\"id\":\"1\",\"long\":638676324052177500}]", res);
93+
}
94+
95+
[TestMethod]
96+
public async Task Test_FromJson_WithLongValues() {
97+
var config = TestHelpers.CreateConfig(new Dictionary<string,string>() {
98+
{ "UseRbacAuth", "false" },
99+
{ "ConnectionString", this.connectionString },
100+
{ "Database", this.testDatabase.Id },
101+
{ "Container", "Test_FromJson_WithLongValues" },
102+
{ "RecreateContainer", "true" },
103+
{ "PartitionKeyPath", "/partitionKey" },
104+
{ "FilePath", "Data/LongValue.json" }
105+
});
106+
107+
var jsonSource = new JsonExtension.JsonFormatReader();
108+
var cosmosSink = new CosmosDataSinkExtension();
109+
var cosmosSource = new CosmosDataSourceExtension();
110+
111+
var fileSource = new Common.FileDataSource();
112+
113+
await cosmosSink.WriteAsync(jsonSource.ParseDataAsync(fileSource, config, NullLogger.Instance),
114+
config, new JsonExtension.JsonFileSource(), NullLogger.Instance);
115+
116+
var fetched = await cosmosSource.ReadAsync(config, NullLogger.Instance).ToArrayAsync();
117+
Assert.IsInstanceOfType(fetched[0].GetValue("long"), typeof(long));
118+
Assert.AreEqual(638676324052177500, fetched[0].GetValue("long"));
119+
}
120+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
[
2+
{
3+
"id": "1",
4+
"partitionKey": "1",
5+
"string": "Hello world!",
6+
"long": 638676324052177500
7+
}
8+
]

0 commit comments

Comments
 (0)