From fa8c249cd39a8f9480ac32480dbba6dfb4332b9b Mon Sep 17 00:00:00 2001 From: Curt Hagenlocher Date: Fri, 26 Apr 2024 14:38:40 -0700 Subject: [PATCH] feat(csharp/test): implement DuckDb test fixture (#1781) Adds support for running tests against DuckDb and implements a simple smoke test. --- .../Apache.Arrow.Adbc.Tests.csproj | 17 +++++ .../Apache.Arrow.Adbc.Tests/DuckDbFixture.cs | 72 +++++++++++++++++++ .../ImportedDuckDbTests.cs | 65 +++++++++++++++++ 3 files changed, 154 insertions(+) create mode 100644 csharp/test/Apache.Arrow.Adbc.Tests/DuckDbFixture.cs create mode 100644 csharp/test/Apache.Arrow.Adbc.Tests/ImportedDuckDbTests.cs diff --git a/csharp/test/Apache.Arrow.Adbc.Tests/Apache.Arrow.Adbc.Tests.csproj b/csharp/test/Apache.Arrow.Adbc.Tests/Apache.Arrow.Adbc.Tests.csproj index 52383b9584..688805cc21 100644 --- a/csharp/test/Apache.Arrow.Adbc.Tests/Apache.Arrow.Adbc.Tests.csproj +++ b/csharp/test/Apache.Arrow.Adbc.Tests/Apache.Arrow.Adbc.Tests.csproj @@ -6,6 +6,7 @@ false true True + $([System.Runtime.InteropServices.RuntimeInformation]::ProcessArchitecture.ToString().ToLowerInvariant()) @@ -13,6 +14,7 @@ + @@ -20,4 +22,19 @@ + + + + + + diff --git a/csharp/test/Apache.Arrow.Adbc.Tests/DuckDbFixture.cs b/csharp/test/Apache.Arrow.Adbc.Tests/DuckDbFixture.cs new file mode 100644 index 0000000000..99925325d0 --- /dev/null +++ b/csharp/test/Apache.Arrow.Adbc.Tests/DuckDbFixture.cs @@ -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 { { "path", Path.Combine(_dataDirectory, name) } }); + } + + public void Dispose() + { + if (_driver != null) + { + _driver.Dispose(); + _driver = null; + + try + { + Directory.Delete(_dataDirectory, true); + } + catch + { + } + } + } + } +} diff --git a/csharp/test/Apache.Arrow.Adbc.Tests/ImportedDuckDbTests.cs b/csharp/test/Apache.Arrow.Adbc.Tests/ImportedDuckDbTests.cs new file mode 100644 index 0000000000..2bb67777f7 --- /dev/null +++ b/csharp/test/Apache.Arrow.Adbc.Tests/ImportedDuckDbTests.cs @@ -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 + { + 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); + } + } +}