Skip to content

Commit 6608390

Browse files
jadewang-dbJade Wangclaude
authored
fix(csharp): add solution file for c# (#12)
## 🥞 Stacked PR Use this [link](https://github.com/adbc-drivers/databricks/pull/12/files) to review incremental changes. - [**stack/test-pujsh**](#12) [[Files changed](https://github.com/adbc-drivers/databricks/pull/12/files)] --------- ## What's Changed add C# solution file --------- Co-authored-by: Jade Wang <jade.wang+data@databricks.com> Co-authored-by: Claude <noreply@anthropic.com>
1 parent 8811e95 commit 6608390

File tree

2 files changed

+131
-12
lines changed

2 files changed

+131
-12
lines changed
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
/*
2+
* Copyright (c) 2025 ADBC Drivers Contributors
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
13+
implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
Microsoft Visual Studio Solution File, Format Version 12.00
19+
# Visual Studio Version 17
20+
VisualStudioVersion = 17.14.36623.8 d17.14
21+
MinimumVisualStudioVersion = 10.0.40219.1
22+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Apache.Arrow.Adbc.Drivers.Databricks", "src\Apache.Arrow.Adbc.Drivers.Databricks.csproj", "{4E0FE818-971A-BA28-4FFB-16E05499B3B5}"
23+
EndProject
24+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Apache.Arrow.Adbc.Drivers.Apache", "arrow-adbc\csharp\src\Drivers\Apache\Apache.Arrow.Adbc.Drivers.Apache.csproj", "{F1FD5D2D-B4F9-DFC5-FB32-EA5FE5640A81}"
25+
EndProject
26+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Apache.Arrow.Adbc.Telemetry.Traces.Listeners", "arrow-adbc\csharp\src\Telemetry\Traces\Listeners\Apache.Arrow.Adbc.Telemetry.Traces.Listeners.csproj", "{BFE03B71-6E4A-9FCC-3A82-0FEA82BEEA97}"
27+
EndProject
28+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Apache.Arrow.Adbc", "arrow-adbc\csharp\src\Apache.Arrow.Adbc\Apache.Arrow.Adbc.csproj", "{147C9F86-54C4-5572-B0F8-D48DFDAAF667}"
29+
EndProject
30+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Apache.Arrow.Adbc.Tests.Drivers.Databricks", "test\Apache.Arrow.Adbc.Tests.Drivers.Databricks.csproj", "{38222237-0B30-A05A-368A-6BBBBF0BBA30}"
31+
EndProject
32+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Apache.Arrow.Adbc.Tests", "arrow-adbc\csharp\test\Apache.Arrow.Adbc.Tests\Apache.Arrow.Adbc.Tests.csproj", "{7B96FF6C-E8BA-3E7D-850C-951EAC24BD6B}"
33+
EndProject
34+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Apache.Arrow.Adbc.Tests.Drivers.Apache", "arrow-adbc\csharp\test\Drivers\Apache\Apache.Arrow.Adbc.Tests.Drivers.Apache.csproj", "{DCFAC829-4278-219B-AAA9-BCFEEED23300}"
35+
EndProject
36+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Apache.Arrow.Adbc.Client", "arrow-adbc\csharp\src\Client\Apache.Arrow.Adbc.Client.csproj", "{D329B649-FFF3-6E1D-008A-A29291295470}"
37+
EndProject
38+
Global
39+
GlobalSection(SolutionConfigurationPlatforms) = preSolution
40+
Debug|Any CPU = Debug|Any CPU
41+
Release|Any CPU = Release|Any CPU
42+
EndGlobalSection
43+
GlobalSection(ProjectConfigurationPlatforms) = postSolution
44+
{4E0FE818-971A-BA28-4FFB-16E05499B3B5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
45+
{4E0FE818-971A-BA28-4FFB-16E05499B3B5}.Debug|Any CPU.Build.0 = Debug|Any CPU
46+
{4E0FE818-971A-BA28-4FFB-16E05499B3B5}.Release|Any CPU.ActiveCfg = Release|Any CPU
47+
{4E0FE818-971A-BA28-4FFB-16E05499B3B5}.Release|Any CPU.Build.0 = Release|Any CPU
48+
{F1FD5D2D-B4F9-DFC5-FB32-EA5FE5640A81}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
49+
{F1FD5D2D-B4F9-DFC5-FB32-EA5FE5640A81}.Debug|Any CPU.Build.0 = Debug|Any CPU
50+
{F1FD5D2D-B4F9-DFC5-FB32-EA5FE5640A81}.Release|Any CPU.ActiveCfg = Release|Any CPU
51+
{F1FD5D2D-B4F9-DFC5-FB32-EA5FE5640A81}.Release|Any CPU.Build.0 = Release|Any CPU
52+
{BFE03B71-6E4A-9FCC-3A82-0FEA82BEEA97}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
53+
{BFE03B71-6E4A-9FCC-3A82-0FEA82BEEA97}.Debug|Any CPU.Build.0 = Debug|Any CPU
54+
{BFE03B71-6E4A-9FCC-3A82-0FEA82BEEA97}.Release|Any CPU.ActiveCfg = Release|Any CPU
55+
{BFE03B71-6E4A-9FCC-3A82-0FEA82BEEA97}.Release|Any CPU.Build.0 = Release|Any CPU
56+
{147C9F86-54C4-5572-B0F8-D48DFDAAF667}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
57+
{147C9F86-54C4-5572-B0F8-D48DFDAAF667}.Debug|Any CPU.Build.0 = Debug|Any CPU
58+
{147C9F86-54C4-5572-B0F8-D48DFDAAF667}.Release|Any CPU.ActiveCfg = Release|Any CPU
59+
{147C9F86-54C4-5572-B0F8-D48DFDAAF667}.Release|Any CPU.Build.0 = Release|Any CPU
60+
{38222237-0B30-A05A-368A-6BBBBF0BBA30}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
61+
{38222237-0B30-A05A-368A-6BBBBF0BBA30}.Debug|Any CPU.Build.0 = Debug|Any CPU
62+
{38222237-0B30-A05A-368A-6BBBBF0BBA30}.Release|Any CPU.ActiveCfg = Release|Any CPU
63+
{38222237-0B30-A05A-368A-6BBBBF0BBA30}.Release|Any CPU.Build.0 = Release|Any CPU
64+
{7B96FF6C-E8BA-3E7D-850C-951EAC24BD6B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
65+
{7B96FF6C-E8BA-3E7D-850C-951EAC24BD6B}.Debug|Any CPU.Build.0 = Debug|Any CPU
66+
{7B96FF6C-E8BA-3E7D-850C-951EAC24BD6B}.Release|Any CPU.ActiveCfg = Release|Any CPU
67+
{7B96FF6C-E8BA-3E7D-850C-951EAC24BD6B}.Release|Any CPU.Build.0 = Release|Any CPU
68+
{DCFAC829-4278-219B-AAA9-BCFEEED23300}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
69+
{DCFAC829-4278-219B-AAA9-BCFEEED23300}.Debug|Any CPU.Build.0 = Debug|Any CPU
70+
{DCFAC829-4278-219B-AAA9-BCFEEED23300}.Release|Any CPU.ActiveCfg = Release|Any CPU
71+
{DCFAC829-4278-219B-AAA9-BCFEEED23300}.Release|Any CPU.Build.0 = Release|Any CPU
72+
{D329B649-FFF3-6E1D-008A-A29291295470}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
73+
{D329B649-FFF3-6E1D-008A-A29291295470}.Debug|Any CPU.Build.0 = Debug|Any CPU
74+
{D329B649-FFF3-6E1D-008A-A29291295470}.Release|Any CPU.ActiveCfg = Release|Any CPU
75+
{D329B649-FFF3-6E1D-008A-A29291295470}.Release|Any CPU.Build.0 = Release|Any CPU
76+
EndGlobalSection
77+
GlobalSection(SolutionProperties) = preSolution
78+
HideSolutionNode = FALSE
79+
EndGlobalSection
80+
GlobalSection(ExtensibilityGlobals) = postSolution
81+
SolutionGuid = {3E328445-1459-42C6-91C2-4F806ED141D5}
82+
EndGlobalSection
83+
EndGlobal

csharp/test/E2E/CloudFetch/CloudFetchDownloaderTest.cs

Lines changed: 48 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -31,20 +31,22 @@
3131
using System.Threading.Tasks;
3232
using Apache.Arrow.Adbc.Drivers.Apache.Hive2;
3333
using Apache.Arrow.Adbc.Drivers.Databricks.Reader.CloudFetch;
34+
using Apache.Arrow.Adbc.Tracing;
3435
using Apache.Hive.Service.Rpc.Thrift;
3536
using Moq;
3637
using Moq.Protected;
3738
using Xunit;
3839

3940
namespace Apache.Arrow.Adbc.Tests.Drivers.Databricks.CloudFetch
4041
{
41-
public class CloudFetchDownloaderTest
42+
public class CloudFetchDownloaderTest : IDisposable
4243
{
4344
private readonly BlockingCollection<IDownloadResult> _downloadQueue;
4445
private readonly BlockingCollection<IDownloadResult> _resultQueue;
4546
private readonly Mock<ICloudFetchMemoryBufferManager> _mockMemoryManager;
4647
private readonly Mock<IHiveServer2Statement> _mockStatement;
4748
private readonly Mock<ICloudFetchResultFetcher> _mockResultFetcher;
49+
private readonly ActivityTrace _activityTrace;
4850

4951
public CloudFetchDownloaderTest()
5052
{
@@ -54,6 +56,13 @@ public CloudFetchDownloaderTest()
5456
_mockStatement = new Mock<IHiveServer2Statement>();
5557
_mockResultFetcher = new Mock<ICloudFetchResultFetcher>();
5658

59+
// Set up activity trace for tracing support
60+
_activityTrace = new ActivityTrace("TestActivitySource");
61+
_mockStatement.Setup(s => s.Trace).Returns(_activityTrace);
62+
_mockStatement.Setup(s => s.TraceParent).Returns((string?)null);
63+
_mockStatement.Setup(s => s.AssemblyVersion).Returns("1.0.0");
64+
_mockStatement.Setup(s => s.AssemblyName).Returns("TestAssembly");
65+
5766
// Set up memory manager defaults
5867
_mockMemoryManager.Setup(m => m.TryAcquireMemory(It.IsAny<long>())).Returns(true);
5968
_mockMemoryManager.Setup(m => m.AcquireMemoryAsync(It.IsAny<long>(), It.IsAny<CancellationToken>()))
@@ -296,7 +305,10 @@ public async Task DownloadFileAsync_WithError_StopsProcessingRemainingFiles()
296305
// Create test download results
297306
var mockDownloadResult = new Mock<IDownloadResult>();
298307
var resultLink = new TSparkArrowResultLink {
308+
StartRowOffset = 0,
299309
FileLink = "http://test.com/file1",
310+
RowCount = 100,
311+
BytesNum = 100,
300312
ExpiryTime = DateTimeOffset.UtcNow.AddMinutes(30).ToUnixTimeMilliseconds() // Set expiry 30 minutes in the future
301313
};
302314
mockDownloadResult.Setup(r => r.Link).Returns(resultLink);
@@ -306,8 +318,13 @@ public async Task DownloadFileAsync_WithError_StopsProcessingRemainingFiles()
306318

307319
// Capture when SetFailed is called
308320
Exception? capturedException = null;
321+
bool setFailedCalled = false;
309322
mockDownloadResult.Setup(r => r.SetFailed(It.IsAny<Exception>()))
310-
.Callback<Exception>(ex => capturedException = ex);
323+
.Callback<Exception>(ex => {
324+
capturedException = ex;
325+
setFailedCalled = true;
326+
Console.WriteLine($"SetFailed called with exception: {ex.Message}");
327+
});
311328

312329
// Create the downloader
313330
var downloader = new CloudFetchDownloader(
@@ -324,30 +341,42 @@ public async Task DownloadFileAsync_WithError_StopsProcessingRemainingFiles()
324341

325342
// Act
326343
await downloader.StartAsync(CancellationToken.None);
344+
Console.WriteLine("Downloader started");
327345
_downloadQueue.Add(mockDownloadResult.Object);
346+
Console.WriteLine("Added download result to queue");
328347

329-
// Wait for the download to be processed and fail
330-
await Task.Delay(200);
331-
332-
// Add the end of results guard
348+
// Add the end of results guard immediately
333349
_downloadQueue.Add(EndOfResultsGuard.Instance);
350+
Console.WriteLine("Added end guard");
334351

335-
// Wait for all processing to complete
336-
await Task.Delay(200);
352+
// Wait for the download to fail - use a timeout to avoid hanging
353+
int maxWaitMs = 2000;
354+
int waitedMs = 0;
355+
while (!downloader.HasError && !setFailedCalled && waitedMs < maxWaitMs)
356+
{
357+
await Task.Delay(50);
358+
waitedMs += 50;
359+
}
360+
361+
Console.WriteLine($"Finished waiting: HasError={downloader.HasError}, SetFailedCalled={setFailedCalled}, WaitedMs={waitedMs}");
337362

338363
// Assert
339364
// Verify the download failed
365+
Assert.True(setFailedCalled, $"SetFailed was not called. Downloader HasError={downloader.HasError}");
340366
mockDownloadResult.Verify(r => r.SetFailed(It.IsAny<Exception>()), Times.Once);
341367

368+
// Verify GetNextDownloadedFileAsync throws an exception
369+
await Assert.ThrowsAsync<AdbcException>(() => downloader.GetNextDownloadedFileAsync(CancellationToken.None));
370+
342371
// Verify the downloader has an error
343372
Assert.True(downloader.HasError);
344373
Assert.NotNull(downloader.Error);
345374

346-
// Verify GetNextDownloadedFileAsync throws an exception
347-
await Assert.ThrowsAsync<AdbcException>(() => downloader.GetNextDownloadedFileAsync(CancellationToken.None));
375+
// Cleanup with timeout and verify task completed
376+
var stopTask = downloader.StopAsync();
377+
var completedTask = await Task.WhenAny(stopTask, Task.Delay(2000));
378+
Assert.Same(stopTask, completedTask); // Ensure that StopAsync completed before the timeout
348379

349-
// Cleanup
350-
await downloader.StopAsync();
351380
}
352381

353382
[Fact]
@@ -680,5 +709,12 @@ private static Mock<HttpMessageHandler> CreateMockHttpMessageHandler(
680709

681710
return mockHandler;
682711
}
712+
713+
public void Dispose()
714+
{
715+
_activityTrace?.Dispose();
716+
_downloadQueue?.Dispose();
717+
_resultQueue?.Dispose();
718+
}
683719
}
684720
}

0 commit comments

Comments
 (0)