Index: third_party/crashpad/crashpad/util/file/file_io_test.cc |
diff --git a/third_party/crashpad/crashpad/util/file/file_io_test.cc b/third_party/crashpad/crashpad/util/file/file_io_test.cc |
index b8444d4140cceba6b2c0f724b99dd9899c283b73..c4e605858959db8186d36c799d163c00576a0583 100644 |
--- a/third_party/crashpad/crashpad/util/file/file_io_test.cc |
+++ b/third_party/crashpad/crashpad/util/file/file_io_test.cc |
@@ -14,9 +14,15 @@ |
#include "util/file/file_io.h" |
+#include <stdio.h> |
+ |
+#include <limits> |
+#include <type_traits> |
+ |
#include "base/atomicops.h" |
#include "base/files/file_path.h" |
#include "base/macros.h" |
+#include "gmock/gmock.h" |
#include "gtest/gtest.h" |
#include "test/errors.h" |
#include "test/file.h" |
@@ -28,6 +34,342 @@ namespace crashpad { |
namespace test { |
namespace { |
+using testing::_; |
+using testing::InSequence; |
+using testing::Return; |
+ |
+class MockReadExactly : public internal::ReadExactlyInternal { |
+ public: |
+ MockReadExactly() : ReadExactlyInternal() {} |
+ ~MockReadExactly() {} |
+ |
+ // Since it’s more convenient for the test to use uintptr_t than void*, |
+ // ReadExactlyInt() and ReadInt() adapt the types. |
+ |
+ bool ReadExactlyInt(uintptr_t data, size_t size, bool can_log) { |
+ return ReadExactly(reinterpret_cast<void*>(data), size, can_log); |
+ } |
+ |
+ MOCK_METHOD3(ReadInt, FileOperationResult(uintptr_t, size_t, bool)); |
+ |
+ // ReadExactlyInternal: |
+ FileOperationResult Read(void* data, size_t size, bool can_log) { |
+ return ReadInt(reinterpret_cast<uintptr_t>(data), size, can_log); |
+ } |
+ |
+ private: |
+ DISALLOW_COPY_AND_ASSIGN(MockReadExactly); |
+}; |
+ |
+TEST(FileIO, ReadExactly_Zero) { |
+ MockReadExactly read_exactly; |
+ InSequence in_sequence; |
+ EXPECT_CALL(read_exactly, ReadInt(_, _, false)).Times(0); |
+ EXPECT_TRUE(read_exactly.ReadExactlyInt(100, 0, false)); |
+} |
+ |
+TEST(FileIO, ReadExactly_SingleSmallSuccess) { |
+ MockReadExactly read_exactly; |
+ InSequence in_sequence; |
+ EXPECT_CALL(read_exactly, ReadInt(1000, 1, false)).WillOnce(Return(1)); |
+ EXPECT_TRUE(read_exactly.ReadExactlyInt(1000, 1, false)); |
+} |
+ |
+TEST(FileIO, ReadExactly_SingleSmallSuccessCanLog) { |
+ MockReadExactly read_exactly; |
+ InSequence in_sequence; |
+ EXPECT_CALL(read_exactly, ReadInt(1000, 1, true)).WillOnce(Return(1)); |
+ EXPECT_TRUE(read_exactly.ReadExactlyInt(1000, 1, true)); |
+} |
+ |
+TEST(FileIO, ReadExactly_SingleSmallFailure) { |
+ MockReadExactly read_exactly; |
+ InSequence in_sequence; |
+ EXPECT_CALL(read_exactly, ReadInt(1000, 1, false)).WillOnce(Return(-1)); |
+ EXPECT_FALSE(read_exactly.ReadExactlyInt(1000, 1, false)); |
+} |
+ |
+TEST(FileIO, ReadExactly_SingleSmallFailureCanLog) { |
+ MockReadExactly read_exactly; |
+ InSequence in_sequence; |
+ EXPECT_CALL(read_exactly, ReadInt(1000, 1, true)).WillOnce(Return(-1)); |
+ EXPECT_FALSE(read_exactly.ReadExactlyInt(1000, 1, true)); |
+} |
+ |
+TEST(FileIO, ReadExactly_DoubleSmallSuccess) { |
+ MockReadExactly read_exactly; |
+ InSequence in_sequence; |
+ EXPECT_CALL(read_exactly, ReadInt(0x1000, 2, false)).WillOnce(Return(1)); |
+ EXPECT_CALL(read_exactly, ReadInt(0x1001, 1, false)).WillOnce(Return(1)); |
+ EXPECT_TRUE(read_exactly.ReadExactlyInt(0x1000, 2, false)); |
+} |
+ |
+TEST(FileIO, ReadExactly_DoubleSmallShort) { |
+ MockReadExactly read_exactly; |
+ InSequence in_sequence; |
+ EXPECT_CALL(read_exactly, ReadInt(0x20000, 2, false)).WillOnce(Return(1)); |
+ EXPECT_CALL(read_exactly, ReadInt(0x20001, 1, false)).WillOnce(Return(0)); |
+ EXPECT_FALSE(read_exactly.ReadExactlyInt(0x20000, 2, false)); |
+} |
+ |
+TEST(FileIO, ReadExactly_DoubleSmallShortCanLog) { |
+ MockReadExactly read_exactly; |
+ InSequence in_sequence; |
+ EXPECT_CALL(read_exactly, ReadInt(0x20000, 2, true)).WillOnce(Return(1)); |
+ EXPECT_CALL(read_exactly, ReadInt(0x20001, 1, true)).WillOnce(Return(0)); |
+ EXPECT_FALSE(read_exactly.ReadExactlyInt(0x20000, 2, true)); |
+} |
+ |
+TEST(FileIO, ReadExactly_Medium) { |
+ MockReadExactly read_exactly; |
+ InSequence in_sequence; |
+ EXPECT_CALL(read_exactly, ReadInt(0x80000000, 0x20000000, false)) |
+ .WillOnce(Return(0x10000000)); |
+ EXPECT_CALL(read_exactly, ReadInt(0x90000000, 0x10000000, false)) |
+ .WillOnce(Return(0x8000000)); |
+ EXPECT_CALL(read_exactly, ReadInt(0x98000000, 0x8000000, false)) |
+ .WillOnce(Return(0x4000000)); |
+ EXPECT_CALL(read_exactly, ReadInt(0x9c000000, 0x4000000, false)) |
+ .WillOnce(Return(0x2000000)); |
+ EXPECT_CALL(read_exactly, ReadInt(0x9e000000, 0x2000000, false)) |
+ .WillOnce(Return(0x1000000)); |
+ EXPECT_CALL(read_exactly, ReadInt(0x9f000000, 0x1000000, false)) |
+ .WillOnce(Return(0x800000)); |
+ EXPECT_CALL(read_exactly, ReadInt(0x9f800000, 0x800000, false)) |
+ .WillOnce(Return(0x400000)); |
+ EXPECT_CALL(read_exactly, ReadInt(0x9fc00000, 0x400000, false)) |
+ .WillOnce(Return(0x200000)); |
+ EXPECT_CALL(read_exactly, ReadInt(0x9fe00000, 0x200000, false)) |
+ .WillOnce(Return(0x100000)); |
+ EXPECT_CALL(read_exactly, ReadInt(0x9ff00000, 0x100000, false)) |
+ .WillOnce(Return(0x80000)); |
+ EXPECT_CALL(read_exactly, ReadInt(0x9ff80000, 0x80000, false)) |
+ .WillOnce(Return(0x40000)); |
+ EXPECT_CALL(read_exactly, ReadInt(0x9ffc0000, 0x40000, false)) |
+ .WillOnce(Return(0x20000)); |
+ EXPECT_CALL(read_exactly, ReadInt(0x9ffe0000, 0x20000, false)) |
+ .WillOnce(Return(0x10000)); |
+ EXPECT_CALL(read_exactly, ReadInt(0x9fff0000, 0x10000, false)) |
+ .WillOnce(Return(0x8000)); |
+ EXPECT_CALL(read_exactly, ReadInt(0x9fff8000, 0x8000, false)) |
+ .WillOnce(Return(0x4000)); |
+ EXPECT_CALL(read_exactly, ReadInt(0x9fffc000, 0x4000, false)) |
+ .WillOnce(Return(0x2000)); |
+ EXPECT_CALL(read_exactly, ReadInt(0x9fffe000, 0x2000, false)) |
+ .WillOnce(Return(0x1000)); |
+ EXPECT_CALL(read_exactly, ReadInt(0x9ffff000, 0x1000, false)) |
+ .WillOnce(Return(0x800)); |
+ EXPECT_CALL(read_exactly, ReadInt(0x9ffff800, 0x800, false)) |
+ .WillOnce(Return(0x400)); |
+ EXPECT_CALL(read_exactly, ReadInt(0x9ffffc00, 0x400, false)) |
+ .WillOnce(Return(0x200)); |
+ EXPECT_CALL(read_exactly, ReadInt(0x9ffffe00, 0x200, false)) |
+ .WillOnce(Return(0x100)); |
+ EXPECT_CALL(read_exactly, ReadInt(0x9fffff00, 0x100, false)) |
+ .WillOnce(Return(0x80)); |
+ EXPECT_CALL(read_exactly, ReadInt(0x9fffff80, 0x80, false)) |
+ .WillOnce(Return(0x40)); |
+ EXPECT_CALL(read_exactly, ReadInt(0x9fffffc0, 0x40, false)) |
+ .WillOnce(Return(0x20)); |
+ EXPECT_CALL(read_exactly, ReadInt(0x9fffffe0, 0x20, false)) |
+ .WillOnce(Return(0x10)); |
+ EXPECT_CALL(read_exactly, ReadInt(0x9ffffff0, 0x10, false)) |
+ .WillOnce(Return(0x8)); |
+ EXPECT_CALL(read_exactly, ReadInt(0x9ffffff8, 0x8, false)) |
+ .WillOnce(Return(0x4)); |
+ EXPECT_CALL(read_exactly, ReadInt(0x9ffffffc, 0x4, false)) |
+ .WillOnce(Return(0x2)); |
+ EXPECT_CALL(read_exactly, ReadInt(0x9ffffffe, 0x2, false)) |
+ .WillOnce(Return(0x1)); |
+ EXPECT_CALL(read_exactly, ReadInt(0x9fffffff, 0x1, false)) |
+ .WillOnce(Return(0x1)); |
+ EXPECT_TRUE(read_exactly.ReadExactlyInt(0x80000000, 0x20000000, false)); |
+} |
+ |
+TEST(FileIO, ReadExactly_LargeSuccess) { |
+ MockReadExactly read_exactly; |
+ InSequence in_sequence; |
+ constexpr size_t max = std::numeric_limits<uint32_t>::max(); |
+ constexpr size_t increment = std::numeric_limits<int32_t>::max(); |
+ EXPECT_CALL(read_exactly, ReadInt(0, max, false)).WillOnce(Return(increment)); |
+ EXPECT_CALL(read_exactly, ReadInt(increment, max - increment, false)) |
+ .WillOnce(Return(increment)); |
+ EXPECT_CALL(read_exactly, ReadInt(2 * increment, 1, false)) |
+ .WillOnce(Return(1)); |
+ EXPECT_TRUE(read_exactly.ReadExactlyInt(0, max, false)); |
+} |
+ |
+TEST(FileIO, ReadExactly_LargeShort) { |
+ MockReadExactly read_exactly; |
+ InSequence in_sequence; |
+ EXPECT_CALL(read_exactly, ReadInt(0, 0xffffffff, false)) |
+ .WillOnce(Return(0x7fffffff)); |
+ EXPECT_CALL(read_exactly, ReadInt(0x7fffffff, 0x80000000, false)) |
+ .WillOnce(Return(0x10000000)); |
+ EXPECT_CALL(read_exactly, ReadInt(0x8fffffff, 0x70000000, false)) |
+ .WillOnce(Return(0)); |
+ EXPECT_FALSE(read_exactly.ReadExactlyInt(0, 0xffffffff, false)); |
+} |
+ |
+TEST(FileIO, ReadExactly_LargeFailure) { |
+ MockReadExactly read_exactly; |
+ InSequence in_sequence; |
+ EXPECT_CALL(read_exactly, ReadInt(0, 0xffffffff, false)) |
+ .WillOnce(Return(0x7fffffff)); |
+ EXPECT_CALL(read_exactly, ReadInt(0x7fffffff, 0x80000000, false)) |
+ .WillOnce(Return(-1)); |
+ EXPECT_FALSE(read_exactly.ReadExactlyInt(0, 0xffffffff, false)); |
+} |
+ |
+TEST(FileIO, ReadExactly_TripleMax) { |
+ MockReadExactly read_exactly; |
+ InSequence in_sequence; |
+ constexpr size_t max = std::numeric_limits<size_t>::max(); |
+ constexpr size_t increment = |
+ std::numeric_limits<std::make_signed<size_t>::type>::max(); |
+ EXPECT_CALL(read_exactly, ReadInt(0, max, false)).WillOnce(Return(increment)); |
+ EXPECT_CALL(read_exactly, ReadInt(increment, max - increment, false)) |
+ .WillOnce(Return(increment)); |
+ EXPECT_CALL(read_exactly, ReadInt(2 * increment, 1, false)) |
+ .WillOnce(Return(1)); |
+ EXPECT_TRUE(read_exactly.ReadExactlyInt(0, max, false)); |
+} |
+ |
+class MockWriteAll : public internal::WriteAllInternal { |
+ public: |
+ MockWriteAll() : WriteAllInternal() {} |
+ ~MockWriteAll() {} |
+ |
+ // Since it’s more convenient for the test to use uintptr_t than const void*, |
+ // WriteAllInt() and WriteInt() adapt the types. |
+ |
+ bool WriteAllInt(uintptr_t data, size_t size) { |
+ return WriteAll(reinterpret_cast<const void*>(data), size); |
+ } |
+ |
+ MOCK_METHOD2(WriteInt, FileOperationResult(uintptr_t, size_t)); |
+ |
+ // WriteAllInternal: |
+ FileOperationResult Write(const void* data, size_t size) { |
+ return WriteInt(reinterpret_cast<uintptr_t>(data), size); |
+ } |
+ |
+ private: |
+ DISALLOW_COPY_AND_ASSIGN(MockWriteAll); |
+}; |
+ |
+TEST(FileIO, WriteAll_Zero) { |
+ MockWriteAll write_all; |
+ InSequence in_sequence; |
+ EXPECT_CALL(write_all, WriteInt(_, _)).Times(0); |
+ EXPECT_TRUE(write_all.WriteAllInt(100, 0)); |
+} |
+ |
+TEST(FileIO, WriteAll_SingleSmallSuccess) { |
+ MockWriteAll write_all; |
+ InSequence in_sequence; |
+ EXPECT_CALL(write_all, WriteInt(1000, 1)).WillOnce(Return(1)); |
+ EXPECT_TRUE(write_all.WriteAllInt(1000, 1)); |
+} |
+ |
+TEST(FileIO, WriteAll_SingleSmallFailure) { |
+ MockWriteAll write_all; |
+ InSequence in_sequence; |
+ EXPECT_CALL(write_all, WriteInt(1000, 1)).WillOnce(Return(-1)); |
+ EXPECT_FALSE(write_all.WriteAllInt(1000, 1)); |
+} |
+ |
+TEST(FileIO, WriteAll_DoubleSmall) { |
+ MockWriteAll write_all; |
+ InSequence in_sequence; |
+ EXPECT_CALL(write_all, WriteInt(0x1000, 2)).WillOnce(Return(1)); |
+ EXPECT_CALL(write_all, WriteInt(0x1001, 1)).WillOnce(Return(1)); |
+ EXPECT_TRUE(write_all.WriteAllInt(0x1000, 2)); |
+} |
+ |
+TEST(FileIO, WriteAll_Medium) { |
+ MockWriteAll write_all; |
+ InSequence in_sequence; |
+ EXPECT_CALL(write_all, WriteInt(0x80000000, 0x20000000)) |
+ .WillOnce(Return(0x10000000)); |
+ EXPECT_CALL(write_all, WriteInt(0x90000000, 0x10000000)) |
+ .WillOnce(Return(0x8000000)); |
+ EXPECT_CALL(write_all, WriteInt(0x98000000, 0x8000000)) |
+ .WillOnce(Return(0x4000000)); |
+ EXPECT_CALL(write_all, WriteInt(0x9c000000, 0x4000000)) |
+ .WillOnce(Return(0x2000000)); |
+ EXPECT_CALL(write_all, WriteInt(0x9e000000, 0x2000000)) |
+ .WillOnce(Return(0x1000000)); |
+ EXPECT_CALL(write_all, WriteInt(0x9f000000, 0x1000000)) |
+ .WillOnce(Return(0x800000)); |
+ EXPECT_CALL(write_all, WriteInt(0x9f800000, 0x800000)) |
+ .WillOnce(Return(0x400000)); |
+ EXPECT_CALL(write_all, WriteInt(0x9fc00000, 0x400000)) |
+ .WillOnce(Return(0x200000)); |
+ EXPECT_CALL(write_all, WriteInt(0x9fe00000, 0x200000)) |
+ .WillOnce(Return(0x100000)); |
+ EXPECT_CALL(write_all, WriteInt(0x9ff00000, 0x100000)) |
+ .WillOnce(Return(0x80000)); |
+ EXPECT_CALL(write_all, WriteInt(0x9ff80000, 0x80000)) |
+ .WillOnce(Return(0x40000)); |
+ EXPECT_CALL(write_all, WriteInt(0x9ffc0000, 0x40000)) |
+ .WillOnce(Return(0x20000)); |
+ EXPECT_CALL(write_all, WriteInt(0x9ffe0000, 0x20000)) |
+ .WillOnce(Return(0x10000)); |
+ EXPECT_CALL(write_all, WriteInt(0x9fff0000, 0x10000)) |
+ .WillOnce(Return(0x8000)); |
+ EXPECT_CALL(write_all, WriteInt(0x9fff8000, 0x8000)).WillOnce(Return(0x4000)); |
+ EXPECT_CALL(write_all, WriteInt(0x9fffc000, 0x4000)).WillOnce(Return(0x2000)); |
+ EXPECT_CALL(write_all, WriteInt(0x9fffe000, 0x2000)).WillOnce(Return(0x1000)); |
+ EXPECT_CALL(write_all, WriteInt(0x9ffff000, 0x1000)).WillOnce(Return(0x800)); |
+ EXPECT_CALL(write_all, WriteInt(0x9ffff800, 0x800)).WillOnce(Return(0x400)); |
+ EXPECT_CALL(write_all, WriteInt(0x9ffffc00, 0x400)).WillOnce(Return(0x200)); |
+ EXPECT_CALL(write_all, WriteInt(0x9ffffe00, 0x200)).WillOnce(Return(0x100)); |
+ EXPECT_CALL(write_all, WriteInt(0x9fffff00, 0x100)).WillOnce(Return(0x80)); |
+ EXPECT_CALL(write_all, WriteInt(0x9fffff80, 0x80)).WillOnce(Return(0x40)); |
+ EXPECT_CALL(write_all, WriteInt(0x9fffffc0, 0x40)).WillOnce(Return(0x20)); |
+ EXPECT_CALL(write_all, WriteInt(0x9fffffe0, 0x20)).WillOnce(Return(0x10)); |
+ EXPECT_CALL(write_all, WriteInt(0x9ffffff0, 0x10)).WillOnce(Return(0x8)); |
+ EXPECT_CALL(write_all, WriteInt(0x9ffffff8, 0x8)).WillOnce(Return(0x4)); |
+ EXPECT_CALL(write_all, WriteInt(0x9ffffffc, 0x4)).WillOnce(Return(0x2)); |
+ EXPECT_CALL(write_all, WriteInt(0x9ffffffe, 0x2)).WillOnce(Return(0x1)); |
+ EXPECT_CALL(write_all, WriteInt(0x9fffffff, 0x1)).WillOnce(Return(0x1)); |
+ EXPECT_TRUE(write_all.WriteAllInt(0x80000000, 0x20000000)); |
+} |
+ |
+TEST(FileIO, WriteAll_LargeSuccess) { |
+ MockWriteAll write_all; |
+ InSequence in_sequence; |
+ constexpr size_t max = std::numeric_limits<uint32_t>::max(); |
+ constexpr size_t increment = std::numeric_limits<int32_t>::max(); |
+ EXPECT_CALL(write_all, WriteInt(0, max)).WillOnce(Return(increment)); |
+ EXPECT_CALL(write_all, WriteInt(increment, max - increment)) |
+ .WillOnce(Return(increment)); |
+ EXPECT_CALL(write_all, WriteInt(2 * increment, 1)).WillOnce(Return(1)); |
+ EXPECT_TRUE(write_all.WriteAllInt(0, max)); |
+} |
+ |
+TEST(FileIO, WriteAll_LargeFailure) { |
+ MockWriteAll write_all; |
+ InSequence in_sequence; |
+ EXPECT_CALL(write_all, WriteInt(0, 0xffffffff)).WillOnce(Return(0x7fffffff)); |
+ EXPECT_CALL(write_all, WriteInt(0x7fffffff, 0x80000000)).WillOnce(Return(-1)); |
+ EXPECT_FALSE(write_all.WriteAllInt(0, 0xffffffff)); |
+} |
+ |
+TEST(FileIO, WriteAll_TripleMax) { |
+ MockWriteAll write_all; |
+ InSequence in_sequence; |
+ constexpr size_t max = std::numeric_limits<size_t>::max(); |
+ constexpr size_t increment = |
+ std::numeric_limits<std::make_signed<size_t>::type>::max(); |
+ EXPECT_CALL(write_all, WriteInt(0, max)).WillOnce(Return(increment)); |
+ EXPECT_CALL(write_all, WriteInt(increment, max - increment)) |
+ .WillOnce(Return(increment)); |
+ EXPECT_CALL(write_all, WriteInt(2 * increment, 1)).WillOnce(Return(1)); |
+ EXPECT_TRUE(write_all.WriteAllInt(0, max)); |
+} |
+ |
void TestOpenFileForWrite(FileHandle (*opener)(const base::FilePath&, |
FileWriteMode, |
FilePermissions)) { |
@@ -324,6 +666,26 @@ TEST(FileIO, FileSizeByHandle) { |
EXPECT_EQ(9, LoggingFileSizeByHandle(file_handle.get())); |
} |
+FileHandle FileHandleForFILE(FILE* file) { |
+ int fd = fileno(file); |
+#if defined(OS_POSIX) |
+ return fd; |
+#elif defined(OS_WIN) |
+ return reinterpret_cast<HANDLE>(_get_osfhandle(fd)); |
+#else |
+#error Port |
+#endif |
+} |
+ |
+TEST(FileIO, StdioFileHandle) { |
+ EXPECT_EQ(FileHandleForFILE(stdin), |
+ StdioFileHandle(StdioStream::kStandardInput)); |
+ EXPECT_EQ(FileHandleForFILE(stdout), |
+ StdioFileHandle(StdioStream::kStandardOutput)); |
+ EXPECT_EQ(FileHandleForFILE(stderr), |
+ StdioFileHandle(StdioStream::kStandardError)); |
+} |
+ |
} // namespace |
} // namespace test |
} // namespace crashpad |