Skip to content

Commit 68094f3

Browse files
authored
Merge pull request #179 from Enmk/test_refactoring
Test refactoring
2 parents e4cc9a1 + fa9a93a commit 68094f3

14 files changed

+946
-475
lines changed

clickhouse/columns/date.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ ColumnRef ColumnDateTime::Slice(size_t begin, size_t len) const {
119119
}
120120

121121
ColumnRef ColumnDateTime::CloneEmpty() const {
122-
return std::make_shared<ColumnDate>();
122+
return std::make_shared<ColumnDateTime>();
123123
}
124124

125125
void ColumnDateTime::Swap(Column& other) {

ut/CMakeLists.txt

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,15 @@ SET ( clickhouse-cpp-ut-src
1414

1515
performance_tests.cpp
1616
tcp_server.cpp
17-
utils.cpp
1817
readonly_client_test.cpp
1918
connection_failed_client_test.cpp
20-
array_of_low_cardinality_tests.cpp)
19+
array_of_low_cardinality_tests.cpp
20+
CreateColumnByType_ut.cpp
21+
Column_ut.cpp
22+
23+
utils.cpp
24+
value_generators.cpp
25+
)
2126

2227
IF (WITH_OPENSSL)
2328
LIST (APPEND clickhouse-cpp-ut-src ssl_ut.cpp)

ut/Column_ut.cpp

Lines changed: 213 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,213 @@
1+
#include <clickhouse/columns/array.h>
2+
#include <clickhouse/columns/tuple.h>
3+
#include <clickhouse/columns/date.h>
4+
#include <clickhouse/columns/enum.h>
5+
#include <clickhouse/columns/lowcardinality.h>
6+
#include <clickhouse/columns/nullable.h>
7+
#include <clickhouse/columns/numeric.h>
8+
#include <clickhouse/columns/string.h>
9+
#include <clickhouse/columns/uuid.h>
10+
#include <clickhouse/columns/ip4.h>
11+
#include <clickhouse/columns/ip6.h>
12+
#include <clickhouse/base/input.h>
13+
#include <clickhouse/base/output.h>
14+
#include <clickhouse/base/socket.h> // for ipv4-ipv6 platform-specific stuff
15+
16+
#include <gtest/gtest.h>
17+
18+
#include "utils.h"
19+
#include "value_generators.h"
20+
21+
namespace {
22+
using namespace clickhouse;
23+
}
24+
25+
26+
// Generic tests for a Column subclass against basic API:
27+
// 1. Constructor: Create, ensure that it is empty
28+
// 2. Append: Create, add some data one by one via Append, make sure that values inserted match extracted with At() and operator[]
29+
// 3. Slice: Create, add some data via Append, do Slice()
30+
// 4. CloneEmpty Create, invoke CloneEmplty, ensure that clone is Empty
31+
// 5. Clear: Create, add some data, invoke Clear(), make sure column is empty
32+
// 6. Swap: create two instances, populate one with data, swap with second, make sure has data was transferred
33+
// 7. Load/Save: create, append some data, save to buffer, load from same buffer into new column, make sure columns match.
34+
35+
template <typename T>
36+
class GenericColumnTest : public testing::Test {
37+
public:
38+
using ColumnType = std::decay_t<T>;
39+
40+
static auto MakeColumn() {
41+
if constexpr (std::is_same_v<ColumnType, ColumnFixedString>) {
42+
return std::make_shared<ColumnFixedString>(12);
43+
} else if constexpr (std::is_same_v<ColumnType, ColumnDateTime64>) {
44+
return std::make_shared<ColumnDateTime64>(3);
45+
} else if constexpr (std::is_same_v<ColumnType, ColumnDecimal>) {
46+
return std::make_shared<ColumnDecimal>(10, 5);
47+
} else {
48+
return std::make_shared<ColumnType>();
49+
}
50+
}
51+
52+
static auto GenerateValues(size_t values_size) {
53+
if constexpr (std::is_same_v<ColumnType, ColumnString>) {
54+
return GenerateVector(values_size, FooBarGenerator);
55+
} else if constexpr (std::is_same_v<ColumnType, ColumnFixedString>) {
56+
return GenerateVector(values_size, FromVectorGenerator{MakeFixedStrings(12)});
57+
} else if constexpr (std::is_same_v<ColumnType, ColumnDate>) {
58+
return GenerateVector(values_size, FromVectorGenerator{MakeDates()});
59+
} else if constexpr (std::is_same_v<ColumnType, ColumnDateTime>) {
60+
return GenerateVector(values_size, FromVectorGenerator{MakeDateTimes()});
61+
} else if constexpr (std::is_same_v<ColumnType, ColumnDateTime64>) {
62+
return MakeDateTime64s(3u, values_size);
63+
} else if constexpr (std::is_same_v<ColumnType, ColumnIPv4>) {
64+
return GenerateVector(values_size, FromVectorGenerator{MakeIPv4s()});
65+
} else if constexpr (std::is_same_v<ColumnType, ColumnIPv6>) {
66+
return GenerateVector(values_size, FromVectorGenerator{MakeIPv6s()});
67+
} else if constexpr (std::is_same_v<ColumnType, ColumnInt128>) {
68+
return GenerateVector(values_size, FromVectorGenerator{MakeInt128s()});
69+
} else if constexpr (std::is_same_v<ColumnType, ColumnDecimal>) {
70+
return GenerateVector(values_size, FromVectorGenerator{MakeDecimals(3, 10)});
71+
} else if constexpr (std::is_same_v<ColumnType, ColumnUUID>) {
72+
return GenerateVector(values_size, FromVectorGenerator{MakeUUIDs()});
73+
} else if constexpr (std::is_integral_v<typename ColumnType::ValueType>) {
74+
// ColumnUIntX and ColumnIntX
75+
return GenerateVector<typename ColumnType::ValueType>(values_size, RandomGenerator<int>());
76+
} else if constexpr (std::is_floating_point_v<typename ColumnType::ValueType>) {
77+
// OR ColumnFloatX
78+
return GenerateVector<typename ColumnType::ValueType>(values_size, RandomGenerator<typename ColumnType::ValueType>());
79+
}
80+
}
81+
82+
template <typename Values>
83+
static void AppendValues(std::shared_ptr<ColumnType> column, const Values& values) {
84+
for (const auto & v : values) {
85+
column->Append(v);
86+
}
87+
}
88+
89+
static auto MakeColumnWithValues(size_t values_size) {
90+
auto column = MakeColumn();
91+
auto values = GenerateValues(values_size);
92+
AppendValues(column, values);
93+
94+
return std::tuple{column, values};
95+
}
96+
};
97+
98+
using ValueColumns = ::testing::Types<
99+
ColumnUInt8, ColumnUInt16, ColumnUInt32, ColumnUInt64
100+
, ColumnInt8, ColumnInt16, ColumnInt32, ColumnInt64
101+
, ColumnFloat32, ColumnFloat64
102+
, ColumnString, ColumnFixedString
103+
, ColumnDate, ColumnDateTime, ColumnDateTime64
104+
, ColumnIPv4, ColumnIPv6
105+
, ColumnInt128
106+
, ColumnDecimal
107+
, ColumnUUID
108+
>;
109+
TYPED_TEST_SUITE(GenericColumnTest, ValueColumns);
110+
111+
TYPED_TEST(GenericColumnTest, Construct) {
112+
auto column = this->MakeColumn();
113+
ASSERT_EQ(0u, column->Size());
114+
}
115+
116+
TYPED_TEST(GenericColumnTest, EmptyColumn) {
117+
auto column = this->MakeColumn();
118+
ASSERT_EQ(0u, column->Size());
119+
120+
// verify that Column methods work as expected on empty column:
121+
// some throw exceptions, some return poper values (like CloneEmpty)
122+
123+
// Shouldn't be able to get items on empty column.
124+
ASSERT_ANY_THROW(column->At(0));
125+
126+
{
127+
auto slice = column->Slice(0, 0);
128+
ASSERT_NO_THROW(slice->template AsStrict<typename TestFixture::ColumnType>());
129+
ASSERT_EQ(0u, slice->Size());
130+
}
131+
132+
{
133+
auto clone = column->CloneEmpty();
134+
ASSERT_NO_THROW(clone->template AsStrict<typename TestFixture::ColumnType>());
135+
ASSERT_EQ(0u, clone->Size());
136+
}
137+
138+
ASSERT_NO_THROW(column->Clear());
139+
ASSERT_NO_THROW(column->Swap(*this->MakeColumn()));
140+
}
141+
142+
TYPED_TEST(GenericColumnTest, Append) {
143+
auto column = this->MakeColumn();
144+
const auto values = this->GenerateValues(100);
145+
146+
for (const auto & v : values) {
147+
EXPECT_NO_THROW(column->Append(v));
148+
}
149+
150+
EXPECT_TRUE(CompareRecursive(values, *column));
151+
}
152+
153+
TYPED_TEST(GenericColumnTest, Slice) {
154+
auto [column, values] = this->MakeColumnWithValues(100);
155+
156+
auto untyped_slice = column->Slice(0, column->Size());
157+
auto slice = untyped_slice->template AsStrict<typename TestFixture::ColumnType>();
158+
EXPECT_EQ(column->GetType(), slice->GetType());
159+
160+
EXPECT_TRUE(CompareRecursive(values, *slice));
161+
162+
// TODO: slices of different sizes
163+
}
164+
165+
TYPED_TEST(GenericColumnTest, CloneEmpty) {
166+
auto [column, values] = this->MakeColumnWithValues(100);
167+
EXPECT_EQ(values.size(), column->Size());
168+
169+
auto clone_untyped = column->CloneEmpty();
170+
// Check that type matches
171+
auto clone = clone_untyped->template AsStrict<typename TestFixture::ColumnType>();
172+
EXPECT_EQ(0u, clone->Size());
173+
174+
EXPECT_EQ(column->GetType(), clone->GetType());
175+
}
176+
177+
TYPED_TEST(GenericColumnTest, Clear) {
178+
auto [column, values] = this->MakeColumnWithValues(100);
179+
EXPECT_EQ(values.size(), column->Size());
180+
181+
column->Clear();
182+
EXPECT_EQ(0u, column->Size());
183+
}
184+
185+
TYPED_TEST(GenericColumnTest, Swap) {
186+
auto [column_A, values] = this->MakeColumnWithValues(100);
187+
auto column_B = this->MakeColumn();
188+
189+
column_A->Swap(*column_B);
190+
191+
EXPECT_EQ(0u, column_A->Size());
192+
EXPECT_TRUE(CompareRecursive(values, *column_B));
193+
}
194+
195+
TYPED_TEST(GenericColumnTest, LoadAndSave) {
196+
auto [column_A, values] = this->MakeColumnWithValues(100);
197+
198+
char buffer[4096] = {'\0'};
199+
{
200+
ArrayOutput output(buffer, sizeof(buffer));
201+
// Save
202+
EXPECT_NO_THROW(column_A->Save(&output));
203+
}
204+
205+
auto column_B = this->MakeColumn();
206+
{
207+
ArrayInput input(buffer, sizeof(buffer));
208+
// Load
209+
EXPECT_TRUE(column_B->Load(&input, values.size()));
210+
}
211+
212+
EXPECT_TRUE(CompareRecursive(*column_A, *column_B));
213+
}

ut/CreateColumnByType_ut.cpp

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
#include <clickhouse/columns/factory.h>
2+
#include <clickhouse/columns/date.h>
3+
#include <clickhouse/columns/numeric.h>
4+
#include <clickhouse/columns/string.h>
5+
6+
#include <gtest/gtest.h>
7+
8+
namespace {
9+
using namespace clickhouse;
10+
}
11+
12+
TEST(CreateColumnByType, CreateSimpleAggregateFunction) {
13+
auto col = CreateColumnByType("SimpleAggregateFunction(funt, Int32)");
14+
15+
ASSERT_EQ("Int32", col->Type()->GetName());
16+
ASSERT_EQ(Type::Int32, col->Type()->GetCode());
17+
ASSERT_NE(nullptr, col->As<ColumnInt32>());
18+
}
19+
20+
TEST(CreateColumnByType, UnmatchedBrackets) {
21+
// When type string has unmatched brackets, CreateColumnByType must return nullptr.
22+
ASSERT_EQ(nullptr, CreateColumnByType("FixedString(10"));
23+
ASSERT_EQ(nullptr, CreateColumnByType("Nullable(FixedString(10000"));
24+
ASSERT_EQ(nullptr, CreateColumnByType("Nullable(FixedString(10000)"));
25+
ASSERT_EQ(nullptr, CreateColumnByType("LowCardinality(Nullable(FixedString(10000"));
26+
ASSERT_EQ(nullptr, CreateColumnByType("LowCardinality(Nullable(FixedString(10000)"));
27+
ASSERT_EQ(nullptr, CreateColumnByType("LowCardinality(Nullable(FixedString(10000))"));
28+
ASSERT_EQ(nullptr, CreateColumnByType("Array(LowCardinality(Nullable(FixedString(10000"));
29+
ASSERT_EQ(nullptr, CreateColumnByType("Array(LowCardinality(Nullable(FixedString(10000)"));
30+
ASSERT_EQ(nullptr, CreateColumnByType("Array(LowCardinality(Nullable(FixedString(10000))"));
31+
ASSERT_EQ(nullptr, CreateColumnByType("Array(LowCardinality(Nullable(FixedString(10000)))"));
32+
}
33+
34+
TEST(CreateColumnByType, LowCardinalityAsWrappedColumn) {
35+
CreateColumnByTypeSettings create_column_settings;
36+
create_column_settings.low_cardinality_as_wrapped_column = true;
37+
38+
ASSERT_EQ(Type::String, CreateColumnByType("LowCardinality(String)", create_column_settings)->GetType().GetCode());
39+
ASSERT_EQ(Type::String, CreateColumnByType("LowCardinality(String)", create_column_settings)->As<ColumnString>()->GetType().GetCode());
40+
41+
ASSERT_EQ(Type::FixedString, CreateColumnByType("LowCardinality(FixedString(10000))", create_column_settings)->GetType().GetCode());
42+
ASSERT_EQ(Type::FixedString, CreateColumnByType("LowCardinality(FixedString(10000))", create_column_settings)->As<ColumnFixedString>()->GetType().GetCode());
43+
}
44+
45+
TEST(CreateColumnByType, DateTime) {
46+
ASSERT_NE(nullptr, CreateColumnByType("DateTime"));
47+
ASSERT_NE(nullptr, CreateColumnByType("DateTime('Europe/Moscow')"));
48+
49+
ASSERT_EQ(CreateColumnByType("DateTime('UTC')")->As<ColumnDateTime>()->Timezone(), "UTC");
50+
ASSERT_EQ(CreateColumnByType("DateTime64(3, 'UTC')")->As<ColumnDateTime64>()->Timezone(), "UTC");
51+
}
52+
53+
class CreateColumnByTypeWithName : public ::testing::TestWithParam<const char* /*Column Type String*/>
54+
{};
55+
56+
TEST_P(CreateColumnByTypeWithName, CreateColumnByType)
57+
{
58+
const auto col = CreateColumnByType(GetParam());
59+
ASSERT_NE(nullptr, col);
60+
EXPECT_EQ(col->GetType().GetName(), GetParam());
61+
}
62+
63+
INSTANTIATE_TEST_SUITE_P(Basic, CreateColumnByTypeWithName, ::testing::Values(
64+
"Int8", "Int16", "Int32", "Int64",
65+
"UInt8", "UInt16", "UInt32", "UInt64",
66+
"String", "Date", "DateTime",
67+
"UUID", "Int128"
68+
));
69+
70+
INSTANTIATE_TEST_SUITE_P(Parametrized, CreateColumnByTypeWithName, ::testing::Values(
71+
"FixedString(0)", "FixedString(10000)",
72+
"DateTime('UTC')", "DateTime64(3, 'UTC')",
73+
"Decimal(9,3)", "Decimal(18,3)",
74+
"Enum8('ONE' = 1, 'TWO' = 2)",
75+
"Enum16('ONE' = 1, 'TWO' = 2, 'THREE' = 3, 'FOUR' = 4)"
76+
));
77+
78+
79+
INSTANTIATE_TEST_SUITE_P(Nested, CreateColumnByTypeWithName, ::testing::Values(
80+
"Nullable(FixedString(10000))",
81+
"Nullable(LowCardinality(FixedString(10000)))",
82+
"Array(Nullable(LowCardinality(FixedString(10000))))",
83+
"Array(Enum8('ONE' = 1, 'TWO' = 2))"
84+
));

ut/client_ut.cpp

Lines changed: 1 addition & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -12,17 +12,6 @@
1212

1313
using namespace clickhouse;
1414

15-
namespace clickhouse {
16-
std::ostream & operator<<(std::ostream & ostr, const ServerInfo & server_info) {
17-
return ostr << server_info.name << "/" << server_info.display_name
18-
<< " ver "
19-
<< server_info.version_major << "."
20-
<< server_info.version_minor << "."
21-
<< server_info.version_patch
22-
<< " (" << server_info.revision << ")";
23-
}
24-
}
25-
2615
namespace {
2716

2817
uint64_t versionNumber(
@@ -1013,7 +1002,7 @@ ColumnRef RoundtripColumnValues(Client& client, ColumnRef expected) {
10131002
result->Append(b[0]);
10141003
});
10151004

1016-
EXPECT_EQ(expected->Type(), result->Type());
1005+
EXPECT_EQ(expected->GetType(), result->GetType());
10171006
EXPECT_EQ(expected->Size(), result->Size());
10181007
return result;
10191008
}

0 commit comments

Comments
 (0)