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
3639DEFINE_string (arrow, " " , " Arrow file name" );
3740DEFINE_string (json, " " , " JSON file name" );
3841DEFINE_string (mode, " VALIDATE" ,
3942 " Mode of integration testing tool (ARROW_TO_JSON, JSON_TO_ARROW, VALIDATE)" );
4043DEFINE_bool (unittest, false , " Run integration test self unit tests" );
44+ DEFINE_bool (verbose, false , " Verbose output" );
45+
46+ namespace fs = boost::filesystem;
4147
4248namespace 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
208363int main (int argc, char ** argv) {
0 commit comments