1 // Licensed to the Apache Software Foundation (ASF) under one
2 // or more contributor license agreements. See the NOTICE file
3 // distributed with this work for additional information
4 // regarding copyright ownership. The ASF licenses this file
5 // to you under the Apache License, Version 2.0 (the
6 // "License"); you may not use this file except in compliance
7 // with the License. You may obtain a copy of the License at
9 // http://www.apache.org/licenses/LICENSE-2.0
11 // Unless required by applicable law or agreed to in writing,
12 // software distributed under the License is distributed on an
13 // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14 // KIND, either express or implied. See the License for the
15 // specific language governing permissions and limitations
27 #include <type_traits>
31 #include <gtest/gtest.h>
33 #include "arrow/array/builder_binary.h"
34 #include "arrow/array/builder_primitive.h"
35 #include "arrow/array/builder_time.h"
36 #include "arrow/result.h"
37 #include "arrow/status.h"
38 #include "arrow/testing/gtest_compat.h"
39 #include "arrow/testing/util.h"
40 #include "arrow/testing/visibility.h"
41 #include "arrow/type_fwd.h"
42 #include "arrow/type_traits.h"
43 #include "arrow/util/bit_util.h"
44 #include "arrow/util/macros.h"
45 #include "arrow/util/string_builder.h"
46 #include "arrow/util/type_fwd.h"
48 // NOTE: failing must be inline in the macros below, to get correct file / line number
49 // reporting on test failures.
51 // NOTE: using a for loop for this macro allows extra failure messages to be
52 // appended with operator<<
53 #define ASSERT_RAISES(ENUM, expr) \
54 for (::arrow::Status _st = ::arrow::internal::GenericToStatus((expr)); \
56 FAIL() << "Expected '" ARROW_STRINGIFY(expr) "' to fail with " ARROW_STRINGIFY( \
60 #define ASSERT_RAISES_WITH_MESSAGE(ENUM, message, expr) \
63 ::arrow::Status _st = ::arrow::internal::GenericToStatus(_res); \
64 if (!_st.Is##ENUM()) { \
65 FAIL() << "Expected '" ARROW_STRINGIFY(expr) "' to fail with " ARROW_STRINGIFY( \
69 ASSERT_EQ((message), _st.ToString()); \
72 #define EXPECT_RAISES_WITH_MESSAGE_THAT(ENUM, matcher, expr) \
75 ::arrow::Status _st = ::arrow::internal::GenericToStatus(_res); \
76 EXPECT_TRUE(_st.Is##ENUM()) << "Expected '" ARROW_STRINGIFY(expr) "' to fail with " \
77 << ARROW_STRINGIFY(ENUM) ", but got " << _st.ToString(); \
78 EXPECT_THAT(_st.ToString(), (matcher)); \
81 #define EXPECT_RAISES_WITH_CODE_AND_MESSAGE_THAT(code, matcher, expr) \
84 ::arrow::Status _st = ::arrow::internal::GenericToStatus(_res); \
85 EXPECT_EQ(_st.CodeAsString(), Status::CodeAsString(code)); \
86 EXPECT_THAT(_st.ToString(), (matcher)); \
89 #define ASSERT_OK(expr) \
90 for (::arrow::Status _st = ::arrow::internal::GenericToStatus((expr)); !_st.ok();) \
91 FAIL() << "'" ARROW_STRINGIFY(expr) "' failed with " << _st.ToString()
93 #define ASSERT_OK_NO_THROW(expr) ASSERT_NO_THROW(ASSERT_OK(expr))
95 #define ARROW_EXPECT_OK(expr) \
98 ::arrow::Status _st = ::arrow::internal::GenericToStatus(_res); \
99 EXPECT_TRUE(_st.ok()) << "'" ARROW_STRINGIFY(expr) "' failed with " \
103 #define ASSERT_NOT_OK(expr) \
104 for (::arrow::Status _st = ::arrow::internal::GenericToStatus((expr)); _st.ok();) \
105 FAIL() << "'" ARROW_STRINGIFY(expr) "' did not failed" << _st.ToString()
107 #define ABORT_NOT_OK(expr) \
109 auto _res = (expr); \
110 ::arrow::Status _st = ::arrow::internal::GenericToStatus(_res); \
111 if (ARROW_PREDICT_FALSE(!_st.ok())) { \
116 #define ASSIGN_OR_HANDLE_ERROR_IMPL(handle_error, status_name, lhs, rexpr) \
117 auto&& status_name = (rexpr); \
118 handle_error(status_name.status()); \
119 lhs = std::move(status_name).ValueOrDie();
121 #define ASSERT_OK_AND_ASSIGN(lhs, rexpr) \
122 ASSIGN_OR_HANDLE_ERROR_IMPL( \
123 ASSERT_OK, ARROW_ASSIGN_OR_RAISE_NAME(_error_or_value, __COUNTER__), lhs, rexpr);
125 #define ASSIGN_OR_ABORT(lhs, rexpr) \
126 ASSIGN_OR_HANDLE_ERROR_IMPL(ABORT_NOT_OK, \
127 ARROW_ASSIGN_OR_RAISE_NAME(_error_or_value, __COUNTER__), \
130 #define EXPECT_OK_AND_ASSIGN(lhs, rexpr) \
131 ASSIGN_OR_HANDLE_ERROR_IMPL(ARROW_EXPECT_OK, \
132 ARROW_ASSIGN_OR_RAISE_NAME(_error_or_value, __COUNTER__), \
135 #define ASSERT_OK_AND_EQ(expected, expr) \
137 ASSERT_OK_AND_ASSIGN(auto _actual, (expr)); \
138 ASSERT_EQ(expected, _actual); \
141 // A generalized version of GTest's SCOPED_TRACE that takes arbitrary arguments.
142 // ARROW_SCOPED_TRACE("some variable = ", some_variable, ...)
144 #define ARROW_SCOPED_TRACE(...) SCOPED_TRACE(::arrow::util::StringBuilder(__VA_ARGS__))
148 // ----------------------------------------------------------------------
149 // Useful testing::Types declarations
151 inline void PrintTo(StatusCode code
, std::ostream
* os
) {
152 *os
<< Status::CodeAsString(code
);
155 using NumericArrowTypes
=
156 ::testing::Types
<UInt8Type
, UInt16Type
, UInt32Type
, UInt64Type
, Int8Type
, Int16Type
,
157 Int32Type
, Int64Type
, FloatType
, DoubleType
>;
159 using RealArrowTypes
= ::testing::Types
<FloatType
, DoubleType
>;
161 using IntegralArrowTypes
= ::testing::Types
<UInt8Type
, UInt16Type
, UInt32Type
, UInt64Type
,
162 Int8Type
, Int16Type
, Int32Type
, Int64Type
>;
164 using PhysicalIntegralArrowTypes
=
165 ::testing::Types
<UInt8Type
, UInt16Type
, UInt32Type
, UInt64Type
, Int8Type
, Int16Type
,
166 Int32Type
, Int64Type
, Date32Type
, Date64Type
, Time32Type
, Time64Type
,
167 TimestampType
, MonthIntervalType
>;
169 using PrimitiveArrowTypes
=
170 ::testing::Types
<BooleanType
, Int8Type
, UInt8Type
, Int16Type
, UInt16Type
, Int32Type
,
171 UInt32Type
, Int64Type
, UInt64Type
, FloatType
, DoubleType
>;
173 using TemporalArrowTypes
=
174 ::testing::Types
<Date32Type
, Date64Type
, TimestampType
, Time32Type
, Time64Type
>;
176 using DecimalArrowTypes
= ::testing::Types
<Decimal128Type
, Decimal256Type
>;
178 using BinaryArrowTypes
=
179 ::testing::Types
<BinaryType
, LargeBinaryType
, StringType
, LargeStringType
>;
181 using StringArrowTypes
= ::testing::Types
<StringType
, LargeStringType
>;
183 using ListArrowTypes
= ::testing::Types
<ListType
, LargeListType
>;
185 using UnionArrowTypes
= ::testing::Types
<SparseUnionType
, DenseUnionType
>;
194 std::vector
<Type::type
> AllTypeIds();
196 #define ASSERT_ARRAYS_EQUAL(lhs, rhs) AssertArraysEqual((lhs), (rhs))
197 #define ASSERT_BATCHES_EQUAL(lhs, rhs) AssertBatchesEqual((lhs), (rhs))
198 #define ASSERT_BATCHES_APPROX_EQUAL(lhs, rhs) AssertBatchesApproxEqual((lhs), (rhs))
199 #define ASSERT_TABLES_EQUAL(lhs, rhs) AssertTablesEqual((lhs), (rhs))
201 // If verbose is true, then the arrays will be pretty printed
202 ARROW_TESTING_EXPORT
void AssertArraysEqual(const Array
& expected
, const Array
& actual
,
203 bool verbose
= false,
204 const EqualOptions
& options
= {});
205 ARROW_TESTING_EXPORT
void AssertArraysApproxEqual(const Array
& expected
,
207 bool verbose
= false,
208 const EqualOptions
& options
= {});
209 // Returns true when values are both null
210 ARROW_TESTING_EXPORT
void AssertScalarsEqual(
211 const Scalar
& expected
, const Scalar
& actual
, bool verbose
= false,
212 const EqualOptions
& options
= EqualOptions::Defaults());
213 ARROW_TESTING_EXPORT
void AssertScalarsApproxEqual(
214 const Scalar
& expected
, const Scalar
& actual
, bool verbose
= false,
215 const EqualOptions
& options
= EqualOptions::Defaults());
216 ARROW_TESTING_EXPORT
void AssertBatchesEqual(const RecordBatch
& expected
,
217 const RecordBatch
& actual
,
218 bool check_metadata
= false);
219 ARROW_TESTING_EXPORT
void AssertBatchesApproxEqual(const RecordBatch
& expected
,
220 const RecordBatch
& actual
);
221 ARROW_TESTING_EXPORT
void AssertChunkedEqual(const ChunkedArray
& expected
,
222 const ChunkedArray
& actual
);
223 ARROW_TESTING_EXPORT
void AssertChunkedEqual(const ChunkedArray
& actual
,
224 const ArrayVector
& expected
);
225 // Like ChunkedEqual, but permits different chunk layout
226 ARROW_TESTING_EXPORT
void AssertChunkedEquivalent(const ChunkedArray
& expected
,
227 const ChunkedArray
& actual
);
228 ARROW_TESTING_EXPORT
void AssertChunkedApproxEquivalent(
229 const ChunkedArray
& expected
, const ChunkedArray
& actual
,
230 const EqualOptions
& equal_options
= EqualOptions::Defaults());
231 ARROW_TESTING_EXPORT
void AssertBufferEqual(const Buffer
& buffer
,
232 const std::vector
<uint8_t>& expected
);
233 ARROW_TESTING_EXPORT
void AssertBufferEqual(const Buffer
& buffer
,
234 const std::string
& expected
);
235 ARROW_TESTING_EXPORT
void AssertBufferEqual(const Buffer
& buffer
, const Buffer
& expected
);
237 ARROW_TESTING_EXPORT
void AssertTypeEqual(const DataType
& lhs
, const DataType
& rhs
,
238 bool check_metadata
= false);
239 ARROW_TESTING_EXPORT
void AssertTypeEqual(const std::shared_ptr
<DataType
>& lhs
,
240 const std::shared_ptr
<DataType
>& rhs
,
241 bool check_metadata
= false);
242 ARROW_TESTING_EXPORT
void AssertFieldEqual(const Field
& lhs
, const Field
& rhs
,
243 bool check_metadata
= false);
244 ARROW_TESTING_EXPORT
void AssertFieldEqual(const std::shared_ptr
<Field
>& lhs
,
245 const std::shared_ptr
<Field
>& rhs
,
246 bool check_metadata
= false);
247 ARROW_TESTING_EXPORT
void AssertSchemaEqual(const Schema
& lhs
, const Schema
& rhs
,
248 bool check_metadata
= false);
249 ARROW_TESTING_EXPORT
void AssertSchemaEqual(const std::shared_ptr
<Schema
>& lhs
,
250 const std::shared_ptr
<Schema
>& rhs
,
251 bool check_metadata
= false);
253 ARROW_TESTING_EXPORT
void AssertTypeNotEqual(const DataType
& lhs
, const DataType
& rhs
,
254 bool check_metadata
= false);
255 ARROW_TESTING_EXPORT
void AssertTypeNotEqual(const std::shared_ptr
<DataType
>& lhs
,
256 const std::shared_ptr
<DataType
>& rhs
,
257 bool check_metadata
= false);
258 ARROW_TESTING_EXPORT
void AssertFieldNotEqual(const Field
& lhs
, const Field
& rhs
,
259 bool check_metadata
= false);
260 ARROW_TESTING_EXPORT
void AssertFieldNotEqual(const std::shared_ptr
<Field
>& lhs
,
261 const std::shared_ptr
<Field
>& rhs
,
262 bool check_metadata
= false);
263 ARROW_TESTING_EXPORT
void AssertSchemaNotEqual(const Schema
& lhs
, const Schema
& rhs
,
264 bool check_metadata
= false);
265 ARROW_TESTING_EXPORT
void AssertSchemaNotEqual(const std::shared_ptr
<Schema
>& lhs
,
266 const std::shared_ptr
<Schema
>& rhs
,
267 bool check_metadata
= false);
269 ARROW_TESTING_EXPORT Result
<util::optional
<std::string
>> PrintArrayDiff(
270 const ChunkedArray
& expected
, const ChunkedArray
& actual
);
272 ARROW_TESTING_EXPORT
void AssertTablesEqual(const Table
& expected
, const Table
& actual
,
273 bool same_chunk_layout
= true,
274 bool flatten
= false);
276 ARROW_TESTING_EXPORT
void AssertDatumsEqual(const Datum
& expected
, const Datum
& actual
,
277 bool verbose
= false);
278 ARROW_TESTING_EXPORT
void AssertDatumsApproxEqual(
279 const Datum
& expected
, const Datum
& actual
, bool verbose
= false,
280 const EqualOptions
& options
= EqualOptions::Defaults());
282 template <typename C_TYPE
>
283 void AssertNumericDataEqual(const C_TYPE
* raw_data
,
284 const std::vector
<C_TYPE
>& expected_values
) {
285 for (auto expected
: expected_values
) {
286 ASSERT_EQ(expected
, *raw_data
);
291 ARROW_TESTING_EXPORT
void CompareBatch(const RecordBatch
& left
, const RecordBatch
& right
,
292 bool compare_metadata
= true);
294 ARROW_TESTING_EXPORT
void ApproxCompareBatch(const RecordBatch
& left
,
295 const RecordBatch
& right
,
296 bool compare_metadata
= true);
298 // Check if the padding of the buffers of the array is zero.
299 // Also cause valgrind warnings if the padding bytes are uninitialized.
300 ARROW_TESTING_EXPORT
void AssertZeroPadded(const Array
& array
);
302 // Check if the valid buffer bytes are initialized
303 // and cause valgrind warnings otherwise.
304 ARROW_TESTING_EXPORT
void TestInitialized(const ArrayData
& array
);
305 ARROW_TESTING_EXPORT
void TestInitialized(const Array
& array
);
307 template <typename BuilderType
>
308 void FinishAndCheckPadding(BuilderType
* builder
, std::shared_ptr
<Array
>* out
) {
309 ASSERT_OK_AND_ASSIGN(*out
, builder
->Finish());
310 AssertZeroPadded(**out
);
311 TestInitialized(**out
);
314 #define DECL_T() typedef typename TestFixture::T T;
316 #define DECL_TYPE() typedef typename TestFixture::Type Type;
318 // ArrayFromJSON: construct an Array from a simple JSON representation
321 std::shared_ptr
<Array
> ArrayFromJSON(const std::shared_ptr
<DataType
>&,
322 util::string_view json
);
325 std::shared_ptr
<Array
> DictArrayFromJSON(const std::shared_ptr
<DataType
>& type
,
326 util::string_view indices_json
,
327 util::string_view dictionary_json
);
330 std::shared_ptr
<RecordBatch
> RecordBatchFromJSON(const std::shared_ptr
<Schema
>&,
334 std::shared_ptr
<ChunkedArray
> ChunkedArrayFromJSON(const std::shared_ptr
<DataType
>&,
335 const std::vector
<std::string
>& json
);
338 std::shared_ptr
<Scalar
> ScalarFromJSON(const std::shared_ptr
<DataType
>&,
339 util::string_view json
);
342 std::shared_ptr
<Scalar
> DictScalarFromJSON(const std::shared_ptr
<DataType
>&,
343 util::string_view index_json
,
344 util::string_view dictionary_json
);
347 std::shared_ptr
<Table
> TableFromJSON(const std::shared_ptr
<Schema
>&,
348 const std::vector
<std::string
>& json
);
350 // ArrayFromVector: construct an Array from vectors of C values
352 template <typename TYPE
, typename C_TYPE
= typename
TYPE::c_type
>
353 void ArrayFromVector(const std::shared_ptr
<DataType
>& type
,
354 const std::vector
<bool>& is_valid
, const std::vector
<C_TYPE
>& values
,
355 std::shared_ptr
<Array
>* out
) {
356 auto type_id
= TYPE::type_id
;
357 ASSERT_EQ(type_id
, type
->id())
358 << "template parameter and concrete DataType instance don't agree";
360 std::unique_ptr
<ArrayBuilder
> builder_ptr
;
361 ASSERT_OK(MakeBuilder(default_memory_pool(), type
, &builder_ptr
));
362 // Get the concrete builder class to access its Append() specializations
363 auto& builder
= dynamic_cast<typename TypeTraits
<TYPE
>::BuilderType
&>(*builder_ptr
);
365 for (size_t i
= 0; i
< values
.size(); ++i
) {
367 ASSERT_OK(builder
.Append(values
[i
]));
369 ASSERT_OK(builder
.AppendNull());
372 ASSERT_OK(builder
.Finish(out
));
375 template <typename TYPE
, typename C_TYPE
= typename
TYPE::c_type
>
376 void ArrayFromVector(const std::shared_ptr
<DataType
>& type
,
377 const std::vector
<C_TYPE
>& values
, std::shared_ptr
<Array
>* out
) {
378 auto type_id
= TYPE::type_id
;
379 ASSERT_EQ(type_id
, type
->id())
380 << "template parameter and concrete DataType instance don't agree";
382 std::unique_ptr
<ArrayBuilder
> builder_ptr
;
383 ASSERT_OK(MakeBuilder(default_memory_pool(), type
, &builder_ptr
));
384 // Get the concrete builder class to access its Append() specializations
385 auto& builder
= dynamic_cast<typename TypeTraits
<TYPE
>::BuilderType
&>(*builder_ptr
);
387 for (size_t i
= 0; i
< values
.size(); ++i
) {
388 ASSERT_OK(builder
.Append(values
[i
]));
390 ASSERT_OK(builder
.Finish(out
));
393 // Overloads without a DataType argument, for parameterless types
395 template <typename TYPE
, typename C_TYPE
= typename
TYPE::c_type
>
396 void ArrayFromVector(const std::vector
<bool>& is_valid
, const std::vector
<C_TYPE
>& values
,
397 std::shared_ptr
<Array
>* out
) {
398 auto type
= TypeTraits
<TYPE
>::type_singleton();
399 ArrayFromVector
<TYPE
, C_TYPE
>(type
, is_valid
, values
, out
);
402 template <typename TYPE
, typename C_TYPE
= typename
TYPE::c_type
>
403 void ArrayFromVector(const std::vector
<C_TYPE
>& values
, std::shared_ptr
<Array
>* out
) {
404 auto type
= TypeTraits
<TYPE
>::type_singleton();
405 ArrayFromVector
<TYPE
, C_TYPE
>(type
, values
, out
);
408 // ChunkedArrayFromVector: construct a ChunkedArray from vectors of C values
410 template <typename TYPE
, typename C_TYPE
= typename
TYPE::c_type
>
411 void ChunkedArrayFromVector(const std::shared_ptr
<DataType
>& type
,
412 const std::vector
<std::vector
<bool>>& is_valid
,
413 const std::vector
<std::vector
<C_TYPE
>>& values
,
414 std::shared_ptr
<ChunkedArray
>* out
) {
416 ASSERT_EQ(is_valid
.size(), values
.size());
417 for (size_t i
= 0; i
< values
.size(); ++i
) {
418 std::shared_ptr
<Array
> array
;
419 ArrayFromVector
<TYPE
, C_TYPE
>(type
, is_valid
[i
], values
[i
], &array
);
420 chunks
.push_back(array
);
422 *out
= std::make_shared
<ChunkedArray
>(chunks
);
425 template <typename TYPE
, typename C_TYPE
= typename
TYPE::c_type
>
426 void ChunkedArrayFromVector(const std::shared_ptr
<DataType
>& type
,
427 const std::vector
<std::vector
<C_TYPE
>>& values
,
428 std::shared_ptr
<ChunkedArray
>* out
) {
430 for (size_t i
= 0; i
< values
.size(); ++i
) {
431 std::shared_ptr
<Array
> array
;
432 ArrayFromVector
<TYPE
, C_TYPE
>(type
, values
[i
], &array
);
433 chunks
.push_back(array
);
435 *out
= std::make_shared
<ChunkedArray
>(chunks
);
438 // Overloads without a DataType argument, for parameterless types
440 template <typename TYPE
, typename C_TYPE
= typename
TYPE::c_type
>
441 void ChunkedArrayFromVector(const std::vector
<std::vector
<bool>>& is_valid
,
442 const std::vector
<std::vector
<C_TYPE
>>& values
,
443 std::shared_ptr
<ChunkedArray
>* out
) {
444 auto type
= TypeTraits
<TYPE
>::type_singleton();
445 ChunkedArrayFromVector
<TYPE
, C_TYPE
>(type
, is_valid
, values
, out
);
448 template <typename TYPE
, typename C_TYPE
= typename
TYPE::c_type
>
449 void ChunkedArrayFromVector(const std::vector
<std::vector
<C_TYPE
>>& values
,
450 std::shared_ptr
<ChunkedArray
>* out
) {
451 auto type
= TypeTraits
<TYPE
>::type_singleton();
452 ChunkedArrayFromVector
<TYPE
, C_TYPE
>(type
, values
, out
);
455 template <typename T
>
456 static inline Status
GetBitmapFromVector(const std::vector
<T
>& is_valid
,
457 std::shared_ptr
<Buffer
>* result
) {
458 size_t length
= is_valid
.size();
460 ARROW_ASSIGN_OR_RAISE(auto buffer
, AllocateEmptyBitmap(length
));
462 uint8_t* bitmap
= buffer
->mutable_data();
463 for (size_t i
= 0; i
< static_cast<size_t>(length
); ++i
) {
465 BitUtil::SetBit(bitmap
, i
);
473 template <typename T
>
474 inline void BitmapFromVector(const std::vector
<T
>& is_valid
,
475 std::shared_ptr
<Buffer
>* out
) {
476 ASSERT_OK(GetBitmapFromVector(is_valid
, out
));
479 // Given an array, return a new identical array except for one validity bit
480 // set to a new value.
481 // This is useful to force the underlying "value" of null entries to otherwise
482 // invalid data and check that errors don't get reported.
484 std::shared_ptr
<Array
> TweakValidityBit(const std::shared_ptr
<Array
>& array
,
485 int64_t index
, bool validity
);
488 void SleepFor(double seconds
);
490 // Sleeps for a very small amount of time. The thread will be yielded
491 // at least once ensuring that context switches could happen. It is intended
492 // to be used for stress testing parallel code and shouldn't be assumed to do any
497 // Wait until predicate is true or timeout in seconds expires.
499 void BusyWait(double seconds
, std::function
<bool()> predicate
);
502 Future
<> SleepAsync(double seconds
);
506 Future
<> SleepABitAsync();
508 template <typename T
>
509 std::vector
<T
> IteratorToVector(Iterator
<T
> iterator
) {
510 EXPECT_OK_AND_ASSIGN(auto out
, iterator
.ToVector());
515 bool LocaleExists(const char* locale
);
517 // A RAII-style object that switches to a new locale, and switches back
518 // to the old locale when going out of scope. Doesn't do anything if the
519 // new locale doesn't exist on the local machine.
520 // ATTENTION: may crash with an assertion failure on Windows debug builds.
521 // See ARROW-6108, also https://gerrit.libreoffice.org/#/c/54110/
522 class ARROW_TESTING_EXPORT LocaleGuard
{
524 explicit LocaleGuard(const char* new_locale
);
529 std::unique_ptr
<Impl
> impl_
;
532 class ARROW_TESTING_EXPORT EnvVarGuard
{
534 EnvVarGuard(const std::string
& name
, const std::string
& value
);
538 const std::string name_
;
539 std::string old_value_
;
547 class ARROW_TESTING_EXPORT SignalHandlerGuard
{
549 typedef void (*Callback
)(int);
551 SignalHandlerGuard(int signum
, Callback cb
);
552 SignalHandlerGuard(int signum
, const internal::SignalHandler
& handler
);
553 ~SignalHandlerGuard();
557 std::unique_ptr
<Impl
> impl_
;
560 #ifndef ARROW_LARGE_MEMORY_TESTS
561 #define LARGE_MEMORY_TEST(name) DISABLED_##name
563 #define LARGE_MEMORY_TEST(name) name
566 inline void PrintTo(const Status
& st
, std::ostream
* os
) { *os
<< st
.ToString(); }
568 template <typename T
>
569 void PrintTo(const Result
<T
>& result
, std::ostream
* os
) {
571 ::testing::internal::UniversalPrint(result
.ValueOrDie(), os
);
573 *os
<< result
.status();
577 // A data type with only move constructors (no copy, no default).
578 struct MoveOnlyDataType
{
579 explicit MoveOnlyDataType(int x
) : data(new int(x
)) {}
581 MoveOnlyDataType(const MoveOnlyDataType
& other
) = delete;
582 MoveOnlyDataType
& operator=(const MoveOnlyDataType
& other
) = delete;
584 MoveOnlyDataType(MoveOnlyDataType
&& other
) { MoveFrom(&other
); }
585 MoveOnlyDataType
& operator=(MoveOnlyDataType
&& other
) {
590 MoveOnlyDataType
& operator=(int x
) {
591 if (data
!= nullptr) {
598 ~MoveOnlyDataType() { Destroy(); }
601 if (data
!= nullptr) {
608 void MoveFrom(MoveOnlyDataType
* other
) {
611 other
->data
= nullptr;
612 moves
= other
->moves
+ 1;
615 int ToInt() const { return data
== nullptr ? -42 : *data
; }
617 bool operator==(const MoveOnlyDataType
& other
) const {
618 return data
!= nullptr && other
.data
!= nullptr && *data
== *other
.data
;
620 bool operator<(const MoveOnlyDataType
& other
) const {
621 return data
== nullptr || (other
.data
!= nullptr && *data
< *other
.data
);
624 bool operator==(int other
) const { return data
!= nullptr && *data
== other
; }
625 friend bool operator==(int left
, const MoveOnlyDataType
& right
) {
626 return right
== left
;
633 // A task that blocks until unlocked. Useful for timing tests.
634 class ARROW_TESTING_EXPORT GatingTask
{
636 explicit GatingTask(double timeout_seconds
= 10);
637 /// \brief During destruction we wait for all pending tasks to finish
640 /// \brief Creates a new waiting task (presumably to spawn on a thread). It will return
641 /// invalid if the timeout arrived before the unlock. The task will not complete until
642 /// unlocked or timed out
644 /// Note: The GatingTask must outlive any Task instances
645 std::function
<void()> Task();
646 /// \brief Creates a new waiting task as a future. The future will not complete
648 Future
<> AsyncTask();
649 /// \brief Waits until at least count tasks are running.
650 Status
WaitForRunning(int count
);
651 /// \brief Unlocks all waiting tasks. Returns an invalid status if any waiting task has
655 static std::shared_ptr
<GatingTask
> Make(double timeout_seconds
= 10);
659 std::shared_ptr
<Impl
> impl_
;
667 // Without this hint, GTest will print string_views as a container of char
668 template <class Char
, class Traits
= std::char_traits
<Char
>>
669 void PrintTo(const basic_string_view
<Char
, Traits
>& view
, std::ostream
* os
) {
673 } // namespace sv_lite
675 namespace optional_lite
{
677 template <typename T
>
678 void PrintTo(const optional
<T
>& opt
, std::ostream
* os
) {
679 if (opt
.has_value()) {
681 ::testing::internal::UniversalPrint(*opt
, os
);
688 inline void PrintTo(const decltype(nullopt
)&, std::ostream
* os
) { *os
<< "nullopt"; }
690 } // namespace optional_lite
691 } // namespace nonstd