Skip to content

Commit dbc6aab

Browse files
committed
Add unit tests for the integration validator
Change-Id: Ie39ca80405bad788f306c38853fbb5e768b5a3ef
1 parent ca1eade commit dbc6aab

File tree

3 files changed

+165
-3
lines changed

3 files changed

+165
-3
lines changed

ci/travis_script_cpp.sh

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,4 +34,7 @@ make lint
3434

3535
ctest -VV -L unittest
3636

37+
# Also run the integration tests self tests
38+
debug/json-integration-test --unittest --verbose
39+
3740
popd

cpp/src/arrow/ipc/CMakeLists.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,8 @@ if (APPLE)
9494
arrow_ipc
9595
gflags
9696
gtest
97+
boost_filesystem_static
98+
boost_system_static
9799
dl)
98100
set_target_properties(json-integration-test
99101
PROPERTIES LINK_FLAGS "-undefined dynamic_lookup")
@@ -105,6 +107,8 @@ else()
105107
gflags
106108
gtest
107109
pthread
110+
boost_filesystem_static
111+
boost_system_static
108112
dl)
109113
endif()
110114

cpp/src/arrow/ipc/json-integration-test.cc

Lines changed: 158 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,18 +26,24 @@
2626
#include "gflags/gflags.h"
2727
#include "gtest/gtest.h"
2828

29+
#include <boost/filesystem.hpp> // NOLINT
30+
2931
#include "arrow/io/file.h"
3032
#include "arrow/ipc/file.h"
3133
#include "arrow/ipc/json.h"
3234
#include "arrow/schema.h"
3335
#include "arrow/table.h"
36+
#include "arrow/test-util.h"
3437
#include "arrow/util/status.h"
3538

3639
DEFINE_string(arrow, "", "Arrow file name");
3740
DEFINE_string(json, "", "JSON file name");
3841
DEFINE_string(mode, "VALIDATE",
3942
"Mode of integration testing tool (ARROW_TO_JSON, JSON_TO_ARROW, VALIDATE)");
4043
DEFINE_bool(unittest, false, "Run integration test self unit tests");
44+
DEFINE_bool(verbose, false, "Verbose output");
45+
46+
namespace fs = boost::filesystem;
4147

4248
namespace arrow {
4349

@@ -64,7 +70,9 @@ static Status ConvertJsonToArrow(
6470
std::unique_ptr<ipc::JsonReader> reader;
6571
RETURN_NOT_OK(ipc::JsonReader::Open(json_buffer, &reader));
6672

67-
std::cout << "Found schema: " << reader->schema()->ToString() << std::endl;
73+
if (FLAGS_verbose) {
74+
std::cout << "Found schema: " << reader->schema()->ToString() << std::endl;
75+
}
6876

6977
std::shared_ptr<ipc::FileWriter> writer;
7078
RETURN_NOT_OK(ipc::FileWriter::Open(out_file.get(), reader->schema(), &writer));
@@ -89,7 +97,9 @@ static Status ConvertArrowToJson(
8997
std::shared_ptr<ipc::FileReader> reader;
9098
RETURN_NOT_OK(ipc::FileReader::Open(in_file, &reader));
9199

92-
std::cout << "Found schema: " << reader->schema()->ToString() << std::endl;
100+
if (FLAGS_verbose) {
101+
std::cout << "Found schema: " << reader->schema()->ToString() << std::endl;
102+
}
93103

94104
std::unique_ptr<ipc::JsonWriter> writer;
95105
RETURN_NOT_OK(ipc::JsonWriter::Open(reader->schema(), &writer));
@@ -138,7 +148,9 @@ static Status ValidateArrowVsJson(
138148
<< "Arrow schema: \n"
139149
<< arrow_schema->ToString();
140150

141-
std::cout << ss.str() << std::endl;
151+
if (FLAGS_verbose) {
152+
std::cout << ss.str() << std::endl;
153+
}
142154
return Status::Invalid("Schemas did not match");
143155
}
144156

@@ -203,6 +215,149 @@ Status RunCommand(const std::string& json_path, const std::string& arrow_path,
203215
}
204216
}
205217

218+
static std::string temp_path() {
219+
return (fs::temp_directory_path() / fs::unique_path()).native();
220+
}
221+
222+
class TestJSONIntegration : public ::testing::Test {
223+
public:
224+
void SetUp() {}
225+
226+
std::string mkstemp() {
227+
auto path = temp_path();
228+
tmp_paths_.push_back(path);
229+
return path;
230+
}
231+
232+
Status WriteJson(const char* data, const std::string& path) {
233+
do {
234+
std::shared_ptr<io::FileOutputStream> out;
235+
RETURN_NOT_OK(io::FileOutputStream::Open(path, &out));
236+
RETURN_NOT_OK(out->Write(reinterpret_cast<const uint8_t*>(data),
237+
static_cast<int64_t>(strlen(data))));
238+
} while (0);
239+
return Status::OK();
240+
}
241+
242+
void TearDown() {
243+
for (const std::string path : tmp_paths_) {
244+
std::remove(path.c_str());
245+
}
246+
}
247+
248+
protected:
249+
std::vector<std::string> tmp_paths_;
250+
};
251+
252+
static const char* JSON_EXAMPLE = R"example(
253+
{
254+
"schema": {
255+
"fields": [
256+
{
257+
"name": "foo",
258+
"type": {"name": "int", "isSigned": true, "bitWidth": 32},
259+
"nullable": true, "children": [],
260+
"typeLayout": [
261+
{"type": "VALIDITY", "typeBitWidth": 1},
262+
{"type": "DATA", "typeBitWidth": 32}
263+
]
264+
},
265+
{
266+
"name": "bar",
267+
"type": {"name": "floatingpoint", "precision": "DOUBLE"},
268+
"nullable": true, "children": [],
269+
"typeLayout": [
270+
{"type": "VALIDITY", "typeBitWidth": 1},
271+
{"type": "DATA", "typeBitWidth": 64}
272+
]
273+
}
274+
]
275+
},
276+
"batches": [
277+
{
278+
"count": 5,
279+
"columns": [
280+
{
281+
"name": "foo",
282+
"count": 5,
283+
"DATA": [1, 2, 3, 4, 5],
284+
"VALIDITY": [1, 0, 1, 1, 1]
285+
},
286+
{
287+
"name": "bar",
288+
"count": 5,
289+
"DATA": [1.0, 2.0, 3.0, 4.0, 5.0],
290+
"VALIDITY": [1, 0, 0, 1, 1]
291+
}
292+
]
293+
}
294+
]
295+
}
296+
)example";
297+
298+
static const char* JSON_EXAMPLE2 = R"example(
299+
{
300+
"schema": {
301+
"fields": [
302+
{
303+
"name": "foo",
304+
"type": {"name": "int", "isSigned": true, "bitWidth": 32},
305+
"nullable": true, "children": [],
306+
"typeLayout": [
307+
{"type": "VALIDITY", "typeBitWidth": 1},
308+
{"type": "DATA", "typeBitWidth": 32}
309+
]
310+
}
311+
]
312+
},
313+
"batches": [
314+
{
315+
"count": 5,
316+
"columns": [
317+
{
318+
"name": "foo",
319+
"count": 5,
320+
"DATA": [1, 2, 3, 4, 5],
321+
"VALIDITY": [1, 0, 1, 1, 1]
322+
}
323+
]
324+
}
325+
]
326+
}
327+
)example";
328+
329+
TEST_F(TestJSONIntegration, ConvertAndValidate) {
330+
std::string json_path = this->mkstemp();
331+
std::string arrow_path = this->mkstemp();
332+
333+
ASSERT_OK(WriteJson(JSON_EXAMPLE, json_path));
334+
335+
ASSERT_OK(ConvertJsonToArrow(json_path, arrow_path));
336+
ASSERT_OK(ValidateArrowVsJson(arrow_path, json_path));
337+
338+
// Convert and overwrite
339+
ASSERT_OK(ConvertArrowToJson(arrow_path, json_path));
340+
341+
// Convert back to arrow, and validate
342+
ASSERT_OK(ConvertJsonToArrow(json_path, arrow_path));
343+
ASSERT_OK(ValidateArrowVsJson(arrow_path, json_path));
344+
}
345+
346+
TEST_F(TestJSONIntegration, ErrorStates) {
347+
std::string json_path = this->mkstemp();
348+
std::string json_path2 = this->mkstemp();
349+
std::string arrow_path = this->mkstemp();
350+
351+
ASSERT_OK(WriteJson(JSON_EXAMPLE, json_path));
352+
ASSERT_OK(WriteJson(JSON_EXAMPLE2, json_path2));
353+
354+
ASSERT_OK(ConvertJsonToArrow(json_path, arrow_path));
355+
ASSERT_RAISES(Invalid, ValidateArrowVsJson(arrow_path, json_path2));
356+
357+
ASSERT_RAISES(IOError, ValidateArrowVsJson("does_not_exist-1234", json_path2));
358+
ASSERT_RAISES(IOError, ValidateArrowVsJson(arrow_path, "does_not_exist-1234"));
359+
}
360+
206361
} // namespace arrow
207362

208363
int main(int argc, char** argv) {

0 commit comments

Comments
 (0)