]> git.proxmox.com Git - ceph.git/blame - ceph/src/arrow/csharp/test/Apache.Arrow.Tests/ArrowReaderVerifier.cs
import quincy 17.2.0
[ceph.git] / ceph / src / arrow / csharp / test / Apache.Arrow.Tests / ArrowReaderVerifier.cs
CommitLineData
1d09f67e
TL
1// Licensed to the Apache Software Foundation (ASF) under one or more
2// contributor license agreements. See the NOTICE file distributed with
3// this work for additional information regarding copyright ownership.
4// The ASF licenses this file to You under the Apache License, Version 2.0
5// (the "License"); you may not use this file except in compliance with
6// the License. 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 implied.
13// See the License for the specific language governing permissions and
14// limitations under the License.
15
16using Apache.Arrow.Ipc;
17using Apache.Arrow.Types;
18using System;
19using System.Linq;
20using System.Threading.Tasks;
21using Apache.Arrow.Arrays;
22using Xunit;
23
24namespace Apache.Arrow.Tests
25{
26 public static class ArrowReaderVerifier
27 {
28 public static void VerifyReader(ArrowStreamReader reader, RecordBatch originalBatch)
29 {
30 RecordBatch readBatch = reader.ReadNextRecordBatch();
31 CompareBatches(originalBatch, readBatch);
32
33 // There should only be one batch - calling ReadNextRecordBatch again should return null.
34 Assert.Null(reader.ReadNextRecordBatch());
35 Assert.Null(reader.ReadNextRecordBatch());
36 }
37
38 public static async Task VerifyReaderAsync(ArrowStreamReader reader, RecordBatch originalBatch)
39 {
40 RecordBatch readBatch = await reader.ReadNextRecordBatchAsync();
41 CompareBatches(originalBatch, readBatch);
42
43 // There should only be one batch - calling ReadNextRecordBatchAsync again should return null.
44 Assert.Null(await reader.ReadNextRecordBatchAsync());
45 Assert.Null(await reader.ReadNextRecordBatchAsync());
46 }
47
48 public static void CompareBatches(RecordBatch expectedBatch, RecordBatch actualBatch, bool strictCompare = true)
49 {
50 SchemaComparer.Compare(expectedBatch.Schema, actualBatch.Schema);
51 Assert.Equal(expectedBatch.Length, actualBatch.Length);
52 Assert.Equal(expectedBatch.ColumnCount, actualBatch.ColumnCount);
53
54 for (int i = 0; i < expectedBatch.ColumnCount; i++)
55 {
56 IArrowArray expectedArray = expectedBatch.Arrays.ElementAt(i);
57 IArrowArray actualArray = actualBatch.Arrays.ElementAt(i);
58
59 CompareArrays(expectedArray, actualArray, strictCompare);
60 }
61 }
62
63 public static void CompareArrays(IArrowArray expectedArray, IArrowArray actualArray, bool strictCompare = true)
64 {
65 actualArray.Accept(new ArrayComparer(expectedArray, strictCompare));
66 }
67
68 private class ArrayComparer :
69 IArrowArrayVisitor<Int8Array>,
70 IArrowArrayVisitor<Int16Array>,
71 IArrowArrayVisitor<Int32Array>,
72 IArrowArrayVisitor<Int64Array>,
73 IArrowArrayVisitor<UInt8Array>,
74 IArrowArrayVisitor<UInt16Array>,
75 IArrowArrayVisitor<UInt32Array>,
76 IArrowArrayVisitor<UInt64Array>,
77 IArrowArrayVisitor<FloatArray>,
78 IArrowArrayVisitor<DoubleArray>,
79 IArrowArrayVisitor<BooleanArray>,
80 IArrowArrayVisitor<TimestampArray>,
81 IArrowArrayVisitor<Date32Array>,
82 IArrowArrayVisitor<Date64Array>,
83 IArrowArrayVisitor<ListArray>,
84 IArrowArrayVisitor<StringArray>,
85 IArrowArrayVisitor<FixedSizeBinaryArray>,
86 IArrowArrayVisitor<BinaryArray>,
87 IArrowArrayVisitor<StructArray>,
88 IArrowArrayVisitor<Decimal128Array>,
89 IArrowArrayVisitor<Decimal256Array>,
90 IArrowArrayVisitor<DictionaryArray>
91 {
92 private readonly IArrowArray _expectedArray;
93 private readonly ArrayTypeComparer _arrayTypeComparer;
94 private readonly bool _strictCompare;
95
96 public ArrayComparer(IArrowArray expectedArray, bool strictCompare)
97 {
98 _expectedArray = expectedArray;
99 _arrayTypeComparer = new ArrayTypeComparer(expectedArray.Data.DataType);
100 _strictCompare = strictCompare;
101 }
102
103 public void Visit(Int8Array array) => CompareArrays(array);
104 public void Visit(Int16Array array) => CompareArrays(array);
105 public void Visit(Int32Array array) => CompareArrays(array);
106 public void Visit(Int64Array array) => CompareArrays(array);
107 public void Visit(UInt8Array array) => CompareArrays(array);
108 public void Visit(UInt16Array array) => CompareArrays(array);
109 public void Visit(UInt32Array array) => CompareArrays(array);
110 public void Visit(UInt64Array array) => CompareArrays(array);
111 public void Visit(FloatArray array) => CompareArrays(array);
112 public void Visit(DoubleArray array) => CompareArrays(array);
113 public void Visit(BooleanArray array) => CompareArrays(array);
114 public void Visit(TimestampArray array) => CompareArrays(array);
115 public void Visit(Date32Array array) => CompareArrays(array);
116 public void Visit(Date64Array array) => CompareArrays(array);
117 public void Visit(ListArray array) => CompareArrays(array);
118 public void Visit(FixedSizeBinaryArray array) => CompareArrays(array);
119 public void Visit(Decimal128Array array) => CompareArrays(array);
120 public void Visit(Decimal256Array array) => CompareArrays(array);
121 public void Visit(StringArray array) => CompareBinaryArrays<StringArray>(array);
122 public void Visit(BinaryArray array) => CompareBinaryArrays<BinaryArray>(array);
123
124 public void Visit(StructArray array)
125 {
126 Assert.IsAssignableFrom<StructArray>(_expectedArray);
127 StructArray expectedArray = (StructArray)_expectedArray;
128
129 Assert.Equal(expectedArray.Length, array.Length);
130 Assert.Equal(expectedArray.NullCount, array.NullCount);
131 Assert.Equal(expectedArray.Offset, array.Offset);
132 Assert.Equal(expectedArray.Data.Children.Length, array.Data.Children.Length);
133 Assert.Equal(expectedArray.Fields.Count, array.Fields.Count);
134
135 for (int i = 0; i < array.Fields.Count; i++)
136 {
137 array.Fields[i].Accept(new ArrayComparer(expectedArray.Fields[i], _strictCompare));
138 }
139 }
140
141 public void Visit(DictionaryArray array)
142 {
143 Assert.IsAssignableFrom<DictionaryArray>(_expectedArray);
144 DictionaryArray expectedArray = (DictionaryArray)_expectedArray;
145 var indicesComparer = new ArrayComparer(expectedArray.Indices, _strictCompare);
146 var dictionaryComparer = new ArrayComparer(expectedArray.Dictionary, _strictCompare);
147 array.Indices.Accept(indicesComparer);
148 array.Dictionary.Accept(dictionaryComparer);
149 }
150
151 public void Visit(IArrowArray array) => throw new NotImplementedException();
152
153 private void CompareBinaryArrays<T>(BinaryArray actualArray)
154 where T : IArrowArray
155 {
156 Assert.IsAssignableFrom<T>(_expectedArray);
157 Assert.IsAssignableFrom<T>(actualArray);
158
159 var expectedArray = (BinaryArray)_expectedArray;
160
161 actualArray.Data.DataType.Accept(_arrayTypeComparer);
162
163 Assert.Equal(expectedArray.Length, actualArray.Length);
164 Assert.Equal(expectedArray.NullCount, actualArray.NullCount);
165 Assert.Equal(expectedArray.Offset, actualArray.Offset);
166
167 CompareValidityBuffer(expectedArray.NullCount, _expectedArray.Length, expectedArray.NullBitmapBuffer, actualArray.NullBitmapBuffer);
168
169 if (_strictCompare)
170 {
171 Assert.True(expectedArray.ValueOffsetsBuffer.Span.SequenceEqual(actualArray.ValueOffsetsBuffer.Span));
172 Assert.True(expectedArray.Values.Slice(0, expectedArray.Length).SequenceEqual(actualArray.Values.Slice(0, actualArray.Length)));
173 }
174 else
175 {
176 for (int i = 0; i < expectedArray.Length; i++)
177 {
178 Assert.True(
179 expectedArray.GetBytes(i).SequenceEqual(actualArray.GetBytes(i)),
180 $"BinaryArray values do not match at index {i}.");
181 }
182 }
183 }
184
185 private void CompareArrays(FixedSizeBinaryArray actualArray)
186 {
187 Assert.IsAssignableFrom<FixedSizeBinaryArray>(_expectedArray);
188 Assert.IsAssignableFrom<FixedSizeBinaryArray>(actualArray);
189
190 var expectedArray = (FixedSizeBinaryArray)_expectedArray;
191
192 actualArray.Data.DataType.Accept(_arrayTypeComparer);
193
194 Assert.Equal(expectedArray.Length, actualArray.Length);
195 Assert.Equal(expectedArray.NullCount, actualArray.NullCount);
196 Assert.Equal(expectedArray.Offset, actualArray.Offset);
197
198 CompareValidityBuffer(expectedArray.NullCount, _expectedArray.Length, expectedArray.NullBitmapBuffer, actualArray.NullBitmapBuffer);
199
200 if (_strictCompare)
201 {
202 Assert.True(expectedArray.ValueBuffer.Span.Slice(0, expectedArray.Length).SequenceEqual(actualArray.ValueBuffer.Span.Slice(0, actualArray.Length)));
203 }
204 else
205 {
206 for (int i = 0; i < expectedArray.Length; i++)
207 {
208 Assert.True(
209 expectedArray.GetBytes(i).SequenceEqual(actualArray.GetBytes(i)),
210 $"FixedSizeBinaryArray values do not match at index {i}.");
211 }
212 }
213 }
214
215 private void CompareArrays<T>(PrimitiveArray<T> actualArray)
216 where T : struct, IEquatable<T>
217 {
218 Assert.IsAssignableFrom<PrimitiveArray<T>>(_expectedArray);
219 PrimitiveArray<T> expectedArray = (PrimitiveArray<T>)_expectedArray;
220
221 actualArray.Data.DataType.Accept(_arrayTypeComparer);
222
223 Assert.Equal(expectedArray.Length, actualArray.Length);
224 Assert.Equal(expectedArray.NullCount, actualArray.NullCount);
225 Assert.Equal(expectedArray.Offset, actualArray.Offset);
226
227 CompareValidityBuffer(expectedArray.NullCount, _expectedArray.Length, expectedArray.NullBitmapBuffer, actualArray.NullBitmapBuffer);
228
229 if (_strictCompare)
230 {
231 Assert.True(expectedArray.Values.Slice(0, expectedArray.Length).SequenceEqual(actualArray.Values.Slice(0, actualArray.Length)));
232 }
233 else
234 {
235 for (int i = 0; i < expectedArray.Length; i++)
236 {
237 Assert.Equal(expectedArray.GetValue(i), actualArray.GetValue(i));
238 }
239 }
240 }
241
242 private void CompareArrays(BooleanArray actualArray)
243 {
244 Assert.IsAssignableFrom<BooleanArray>(_expectedArray);
245 BooleanArray expectedArray = (BooleanArray)_expectedArray;
246
247 actualArray.Data.DataType.Accept(_arrayTypeComparer);
248
249 Assert.Equal(expectedArray.Length, actualArray.Length);
250 Assert.Equal(expectedArray.NullCount, actualArray.NullCount);
251 Assert.Equal(expectedArray.Offset, actualArray.Offset);
252
253 CompareValidityBuffer(expectedArray.NullCount, _expectedArray.Length, expectedArray.NullBitmapBuffer, actualArray.NullBitmapBuffer);
254
255 if (_strictCompare)
256 {
257 int booleanByteCount = BitUtility.ByteCount(expectedArray.Length);
258 Assert.True(expectedArray.Values.Slice(0, booleanByteCount).SequenceEqual(actualArray.Values.Slice(0, booleanByteCount)));
259 }
260 else
261 {
262 for (int i = 0; i < expectedArray.Length; i++)
263 {
264 Assert.Equal(expectedArray.GetValue(i), actualArray.GetValue(i));
265 }
266 }
267 }
268
269 private void CompareArrays(ListArray actualArray)
270 {
271 Assert.IsAssignableFrom<ListArray>(_expectedArray);
272 ListArray expectedArray = (ListArray)_expectedArray;
273
274 actualArray.Data.DataType.Accept(_arrayTypeComparer);
275
276 Assert.Equal(expectedArray.Length, actualArray.Length);
277 Assert.Equal(expectedArray.NullCount, actualArray.NullCount);
278 Assert.Equal(expectedArray.Offset, actualArray.Offset);
279
280 CompareValidityBuffer(expectedArray.NullCount, _expectedArray.Length, expectedArray.NullBitmapBuffer, actualArray.NullBitmapBuffer);
281 Assert.True(expectedArray.ValueOffsetsBuffer.Span.SequenceEqual(actualArray.ValueOffsetsBuffer.Span));
282
283 actualArray.Values.Accept(new ArrayComparer(expectedArray.Values, _strictCompare));
284 }
285
286 private void CompareValidityBuffer(int nullCount, int arrayLength, ArrowBuffer expectedValidityBuffer, ArrowBuffer actualValidityBuffer)
287 {
288 if (_strictCompare)
289 {
290 Assert.True(expectedValidityBuffer.Span.SequenceEqual(actualValidityBuffer.Span));
291 }
292 else if (nullCount != 0)
293 {
294 int validityBitmapByteCount = BitUtility.ByteCount(arrayLength);
295 Assert.True(
296 expectedValidityBuffer.Span.Slice(0, validityBitmapByteCount).SequenceEqual(actualValidityBuffer.Span.Slice(0, validityBitmapByteCount)),
297 "Validity buffers do not match.");
298 }
299 }
300 }
301 }
302}