Skip to content

Commit

Permalink
feat(csharp/test): implement DuckDb test fixture (apache#1781)
Browse files Browse the repository at this point in the history
Adds support for running tests against DuckDb and implements a simple
smoke test.
  • Loading branch information
CurtHagenlocher authored and cocoa-xu committed May 8, 2024
1 parent 26bddc5 commit fa8c249
Show file tree
Hide file tree
Showing 3 changed files with 154 additions and 0 deletions.
17 changes: 17 additions & 0 deletions csharp/test/Apache.Arrow.Adbc.Tests/Apache.Arrow.Adbc.Tests.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,35 @@
<IsPackable>false</IsPackable>
<IsTestProject>true</IsTestProject>
<SignAssembly>True</SignAssembly>
<ProcessArchitecture>$([System.Runtime.InteropServices.RuntimeInformation]::ProcessArchitecture.ToString().ToLowerInvariant())</ProcessArchitecture>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.9.0" />
<PackageReference Include="Moq" Version="4.20.70" />
<PackageReference Include="System.Text.Json" Version="7.0.4" />
<PackageReference Include="xunit" Version="2.7.0" />
<PackageReference Include="DuckDB.NET.Bindings.Full" Version="0.10.2" GeneratePathProperty="true" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\..\src\Apache.Arrow.Adbc\Apache.Arrow.Adbc.csproj" />
<ProjectReference Include="..\..\src\Client\Apache.Arrow.Adbc.Client.csproj" />
</ItemGroup>

<Target Name="CopyDuckDb" AfterTargets="Build" Condition="'$(PkgDuckDB_NET_Bindings_Full)' != ''">
<Copy
Condition="'$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::Windows)))' == 'true'"
SourceFiles="$(PkgDuckDB_NET_Bindings_Full)\runtimes\win-$(ProcessArchitecture)\native\duckdb.dll"
DestinationFolder="$(OutputPath)" />
<Copy
Condition="'$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::Linux)))' == 'true'"
SourceFiles="$(PkgDuckDB_NET_Bindings_Full)\runtimes\linux-$(ProcessArchitecture)\native\libduckdb.so"
DestinationFolder="$(OutputPath)" />
<Copy
Condition="'$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::OSX)))' == 'true'"
SourceFiles="$(PkgDuckDB_NET_Bindings_Full)\runtimes\osx\native\libduckdb.dylib"
DestinationFolder="$(OutputPath)" />
</Target>

</Project>
72 changes: 72 additions & 0 deletions csharp/test/Apache.Arrow.Adbc.Tests/DuckDbFixture.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

using System;
using System.Collections.Generic;
using System.IO;
using System.Runtime.InteropServices;
using Apache.Arrow.Adbc.C;

namespace Apache.Arrow.Adbc.Tests
{
public class DuckDbFixture : IDisposable
{
readonly string _dataDirectory;
AdbcDriver _driver;

public DuckDbFixture()
{
_dataDirectory = Path.Combine(Path.GetTempPath(), "AdbcTest_DuckDb", Guid.NewGuid().ToString("D"));
Directory.CreateDirectory(_dataDirectory);

string root = Directory.GetCurrentDirectory();
string file;
if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
file = Path.Combine(root, "libduckdb.so");
else if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
file = Path.Combine(root, "duckdb.dll");
else
file = Path.Combine(root, "libduckdb.dylib");

_driver = CAdbcDriverImporter.Load(file, "duckdb_adbc_init");
}

public AdbcDatabase OpenDatabase(string name)
{
if (_driver == null) throw new ObjectDisposedException("DuckDbFixture");

return _driver.Open(new Dictionary<string, string> { { "path", Path.Combine(_dataDirectory, name) } });
}

public void Dispose()
{
if (_driver != null)
{
_driver.Dispose();
_driver = null;

try
{
Directory.Delete(_dataDirectory, true);
}
catch
{
}
}
}
}
}
65 changes: 65 additions & 0 deletions csharp/test/Apache.Arrow.Adbc.Tests/ImportedDuckDbTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

using Apache.Arrow.Types;
using Xunit;

namespace Apache.Arrow.Adbc.Tests
{
public class ImportedDuckDbTests : IClassFixture<DuckDbFixture>
{
readonly DuckDbFixture _duckDb;

public ImportedDuckDbTests(DuckDbFixture duckDb)
{
_duckDb = duckDb;
}

[Fact]
public void SimpleEndToEndTest()
{
using var database = _duckDb.OpenDatabase("test.db");
using var connection = database.Connect(null);
using var statement = connection.CreateStatement();

statement.SqlQuery = "CREATE TABLE integers(foo INTEGER, bar INTEGER);";
statement.ExecuteUpdate();

statement.SqlQuery = "INSERT INTO integers VALUES (3, 4), (5, 6), (7, 8);";
statement.ExecuteUpdate();

statement.SqlQuery = "SELECT * from integers";
var results = statement.ExecuteQuery();

using var stream = results.Stream;

var schema = stream.Schema;
Assert.Equal(2, schema.FieldsList.Count);
Assert.Equal(ArrowTypeId.Int32, schema.FieldsList[0].DataType.TypeId);
Assert.Equal(ArrowTypeId.Int32, schema.FieldsList[1].DataType.TypeId);

var firstBatch = stream.ReadNextRecordBatchAsync().Result;
Assert.Equal(3, firstBatch.Length);
Assert.Equal(3, (firstBatch.Column(0) as Int32Array).Values[0]);
Assert.Equal(5, (firstBatch.Column(0) as Int32Array).Values[1]);
Assert.Equal(7, (firstBatch.Column(0) as Int32Array).Values[2]);

var secondBatch = stream.ReadNextRecordBatchAsync().Result;
Assert.Null(secondBatch);
}
}
}

0 comments on commit fa8c249

Please sign in to comment.