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
8//
9// http://www.apache.org/licenses/LICENSE-2.0
10//
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
16// under the License.
17
18#ifndef ARROW_IO_TEST_COMMON_H
19#define ARROW_IO_TEST_COMMON_H
20
21#include <algorithm>
22#include <cstdint>
23#include <fstream> // IWYU pragma: keep
24#include <memory>
25#include <string>
26#include <vector>
27
28#ifdef _WIN32
29#include <crtdbg.h>
30#include <io.h>
31#else
32#include <fcntl.h>
33#endif
34
35#include "arrow/buffer.h"
36#include "arrow/io/file.h"
37#include "arrow/io/memory.h"
38#include "arrow/memory_pool.h"
39#include "arrow/test-util.h"
40
41namespace arrow {
42namespace io {
43
44static inline void AssertFileContents(const std::string& path,
45 const std::string& contents) {
46 std::shared_ptr<ReadableFile> rf;
47 int64_t size;
48
49 ASSERT_OK(ReadableFile::Open(path, &rf));
50 ASSERT_OK(rf->GetSize(&size));
51 ASSERT_EQ(size, contents.size());
52
53 std::shared_ptr<Buffer> actual_data;
54 ASSERT_OK(rf->Read(size, &actual_data));
55 ASSERT_TRUE(actual_data->Equals(Buffer(contents)));
56}
57
58static inline bool FileExists(const std::string& path) {
59 return std::ifstream(path.c_str()).good();
60}
61
62#if defined(_WIN32)
63static inline void InvalidParamHandler(const wchar_t* expr, const wchar_t* func,
64 const wchar_t* source_file,
65 unsigned int source_line, uintptr_t reserved) {
66 wprintf(L"Invalid parameter in function '%s'. Source: '%s' line %d expression '%s'\n",
67 func, source_file, source_line, expr);
68}
69#endif
70
71static inline bool FileIsClosed(int fd) {
72#if defined(_WIN32)
73 // Disables default behavior on wrong params which causes the application to crash
74 // https://msdn.microsoft.com/en-us/library/ksazx244.aspx
75 _set_invalid_parameter_handler(InvalidParamHandler);
76
77 // Disables possible assertion alert box on invalid input arguments
78 _CrtSetReportMode(_CRT_ASSERT, 0);
79
80 int new_fd = _dup(fd);
81 if (new_fd == -1) {
82 return errno == EBADF;
83 }
84 _close(new_fd);
85 return false;
86#else
87 if (-1 != fcntl(fd, F_GETFD)) {
88 return false;
89 }
90 return errno == EBADF;
91#endif
92}
93
94static inline Status ZeroMemoryMap(MemoryMappedFile* file) {
95 constexpr int64_t kBufferSize = 512;
96 static constexpr uint8_t kZeroBytes[kBufferSize] = {0};
97
98 RETURN_NOT_OK(file->Seek(0));
99 int64_t position = 0;
100 int64_t file_size;
101 RETURN_NOT_OK(file->GetSize(&file_size));
102
103 int64_t chunksize;
104 while (position < file_size) {
105 chunksize = std::min(kBufferSize, file_size - position);
106 RETURN_NOT_OK(file->Write(kZeroBytes, chunksize));
107 position += chunksize;
108 }
109 return Status::OK();
110}
111
112class MemoryMapFixture {
113 public:
114 void TearDown() {
115 for (auto path : tmp_files_) {
116 ARROW_UNUSED(std::remove(path.c_str()));
117 }
118 }
119
120 void CreateFile(const std::string& path, int64_t size) {
121 std::shared_ptr<MemoryMappedFile> file;
122 ASSERT_OK(MemoryMappedFile::Create(path, size, &file));
123 tmp_files_.push_back(path);
124 }
125
126 Status InitMemoryMap(int64_t size, const std::string& path,
127 std::shared_ptr<MemoryMappedFile>* mmap) {
128 RETURN_NOT_OK(MemoryMappedFile::Create(path, size, mmap));
129 tmp_files_.push_back(path);
130 return Status::OK();
131 }
132
133 void AppendFile(const std::string& path) { tmp_files_.push_back(path); }
134
135 private:
136 std::vector<std::string> tmp_files_;
137};
138
139} // namespace io
140} // namespace arrow
141
142#endif // ARROW_IO_TEST_COMMON_H
143