winfsp unit tests and fixes
	
		
			
	
		
	
	
		
	
		
			Some checks failed
		
		
	
	
		
			
				
	
				BlockStorage/repertory/pipeline/head There was a failure building this commit
				
			
		
		
	
	
				
					
				
			
		
			Some checks failed
		
		
	
	BlockStorage/repertory/pipeline/head There was a failure building this commit
				
			This commit is contained in:
		| @@ -258,6 +258,189 @@ static void test_append_file(auto mount_location, auto &&file_path, | |||||||
|   EXPECT_EQ(ERROR_FILE_NOT_FOUND, ::GetLastError()); |   EXPECT_EQ(ERROR_FILE_NOT_FOUND, ::GetLastError()); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | static void test_overlapped_file(auto mount_location, auto &&file_path, | ||||||
|  |                                  auto &&flags) { | ||||||
|  |   SYSTEM_INFO sys_info{}; | ||||||
|  |   ::GetSystemInfo(&sys_info); | ||||||
|  |  | ||||||
|  |   DWORD bytes_per_sector{}; | ||||||
|  |   DWORD free_clusters{}; | ||||||
|  |   DWORD sectors_per_cluster{}; | ||||||
|  |   DWORD total_clusters{}; | ||||||
|  |   EXPECT_TRUE(::GetDiskFreeSpaceA(mount_location.c_str(), §ors_per_cluster, | ||||||
|  |                                   &bytes_per_sector, &free_clusters, | ||||||
|  |                                   &total_clusters)); | ||||||
|  |   const auto buffer_size = 16U * sys_info.dwPageSize; | ||||||
|  |   auto write_buffer = utils::generate_secure_random<data_buffer>(buffer_size); | ||||||
|  |  | ||||||
|  |   OVERLAPPED overlapped{}; | ||||||
|  |   overlapped.hEvent = ::CreateEvent(nullptr, TRUE, FALSE, nullptr); | ||||||
|  |   ASSERT_NE(nullptr, overlapped.hEvent); | ||||||
|  |  | ||||||
|  |   auto handle = ::CreateFileA( | ||||||
|  |       file_path.c_str(), GENERIC_READ | GENERIC_WRITE, | ||||||
|  |       FILE_SHARE_READ | FILE_SHARE_WRITE, nullptr, CREATE_NEW, | ||||||
|  |       FILE_ATTRIBUTE_NORMAL | flags | FILE_FLAG_OVERLAPPED, nullptr); | ||||||
|  |   ASSERT_NE(INVALID_HANDLE_VALUE, handle); | ||||||
|  |  | ||||||
|  |   overlapped.Offset = 0U; | ||||||
|  |   DWORD bytes_written{}; | ||||||
|  |   auto ret = ::WriteFile(handle, write_buffer.data(), bytes_per_sector, | ||||||
|  |                          &bytes_written, &overlapped); | ||||||
|  |   EXPECT_TRUE(ret || ERROR_IO_PENDING == ::GetLastError()); | ||||||
|  |   EXPECT_TRUE(::GetOverlappedResult(handle, &overlapped, &bytes_written, TRUE)); | ||||||
|  |   EXPECT_EQ(bytes_per_sector, bytes_written); | ||||||
|  |   // | ||||||
|  |   // Overlapped.Offset = 2 * BytesPerSector; | ||||||
|  |   // Success = WriteFile(Handle, Buffer[0], BytesPerSector, &BytesTransferred, | ||||||
|  |   //                     &Overlapped); | ||||||
|  |   // ASSERT(Success || ERROR_IO_PENDING == GetLastError()); | ||||||
|  |   // Success = GetOverlappedResult(Handle, &Overlapped, &BytesTransferred, | ||||||
|  |   // TRUE); ASSERT(Success); ASSERT(BytesPerSector == BytesTransferred); | ||||||
|  |   // | ||||||
|  |   // Overlapped.Offset = 0; | ||||||
|  |   // memset(AllocBuffer[1], 0, AllocBufferSize); | ||||||
|  |   // Success = ReadFile(Handle, Buffer[1], BytesPerSector, &BytesTransferred, | ||||||
|  |   //                    &Overlapped); | ||||||
|  |   // ASSERT(Success || ERROR_IO_PENDING == GetLastError()); | ||||||
|  |   // Success = GetOverlappedResult(Handle, &Overlapped, &BytesTransferred, | ||||||
|  |   // TRUE); ASSERT(Success); ASSERT(BytesPerSector == BytesTransferred); | ||||||
|  |   // ASSERT(0 == memcmp(Buffer[0], Buffer[1], BytesTransferred)); | ||||||
|  |   // | ||||||
|  |   // Overlapped.Offset = 2 * BytesPerSector; | ||||||
|  |   // memset(AllocBuffer[1], 0, AllocBufferSize); | ||||||
|  |   // Success = ReadFile(Handle, Buffer[1], BytesPerSector, &BytesTransferred, | ||||||
|  |   //                    &Overlapped); | ||||||
|  |   // ASSERT(Success || ERROR_IO_PENDING == GetLastError()); | ||||||
|  |   // Success = GetOverlappedResult(Handle, &Overlapped, &BytesTransferred, | ||||||
|  |   // TRUE); ASSERT(Success); ASSERT(BytesPerSector == BytesTransferred); | ||||||
|  |   // ASSERT(0 == memcmp(Buffer[0], Buffer[1], BytesTransferred)); | ||||||
|  |   // | ||||||
|  |   // Overlapped.Offset = 2 * BytesPerSector; | ||||||
|  |   // memset(AllocBuffer[1], 0, AllocBufferSize); | ||||||
|  |   // Success = ReadFile(Handle, Buffer[1], 2 * BytesPerSector, | ||||||
|  |   // &BytesTransferred, | ||||||
|  |   //                    &Overlapped); | ||||||
|  |   // ASSERT(Success || ERROR_IO_PENDING == GetLastError()); | ||||||
|  |   // Success = GetOverlappedResult(Handle, &Overlapped, &BytesTransferred, | ||||||
|  |   // TRUE); ASSERT(Success); ASSERT(BytesPerSector == BytesTransferred); | ||||||
|  |   // ASSERT(0 == memcmp(Buffer[0], Buffer[1], BytesTransferred)); | ||||||
|  |   // | ||||||
|  |   // Overlapped.Offset = 3 * BytesPerSector; | ||||||
|  |   // memset(AllocBuffer[1], 0, AllocBufferSize); | ||||||
|  |   // Success = ReadFile(Handle, Buffer[1], BytesPerSector, &BytesTransferred, | ||||||
|  |   //                    &Overlapped); | ||||||
|  |   // ASSERT(Success || ERROR_IO_PENDING == GetLastError() || | ||||||
|  |   //        ERROR_HANDLE_EOF == GetLastError()); | ||||||
|  |   // if (ERROR_HANDLE_EOF != GetLastError()) { | ||||||
|  |   //   Success = GetOverlappedResult(Handle, &Overlapped, &BytesTransferred, | ||||||
|  |   //   TRUE); ASSERT(!Success && ERROR_HANDLE_EOF == GetLastError()); | ||||||
|  |   // } | ||||||
|  |   // ASSERT(0 == BytesTransferred); | ||||||
|  |   // ASSERT(0 == memcmp(Buffer[0], Buffer[1], BytesTransferred)); | ||||||
|  |   // | ||||||
|  |   // Overlapped.Offset = 0; | ||||||
|  |   // Success = WriteFile(Handle, Buffer[0], 2 * SystemInfo.dwPageSize, | ||||||
|  |   //                     &BytesTransferred, &Overlapped); | ||||||
|  |   // ASSERT(Success || ERROR_IO_PENDING == GetLastError()); | ||||||
|  |   // Success = GetOverlappedResult(Handle, &Overlapped, &BytesTransferred, | ||||||
|  |   // TRUE); ASSERT(Success); ASSERT(2 * SystemInfo.dwPageSize == | ||||||
|  |   // BytesTransferred); | ||||||
|  |   // | ||||||
|  |   // Overlapped.Offset = 0; | ||||||
|  |   // memset(AllocBuffer[1], 0, AllocBufferSize); | ||||||
|  |   // Success = ReadFile(Handle, Buffer[1], 2 * SystemInfo.dwPageSize, | ||||||
|  |   //                    &BytesTransferred, &Overlapped); | ||||||
|  |   // ASSERT(Success || ERROR_IO_PENDING == GetLastError()); | ||||||
|  |   // Success = GetOverlappedResult(Handle, &Overlapped, &BytesTransferred, | ||||||
|  |   // TRUE); ASSERT(Success); ASSERT(2 * SystemInfo.dwPageSize == | ||||||
|  |   // BytesTransferred); ASSERT(0 == memcmp(Buffer[0], Buffer[1], | ||||||
|  |   // BytesTransferred)); | ||||||
|  |   // | ||||||
|  |   // Buffer[0] = AllocBuffer[0]; | ||||||
|  |   // Buffer[1] = AllocBuffer[0]; | ||||||
|  |   // | ||||||
|  |   // Overlapped.Offset = 0; | ||||||
|  |   // Success = WriteFile(Handle, Buffer[0], 2 * SystemInfo.dwPageSize, | ||||||
|  |   //                     &BytesTransferred, &Overlapped); | ||||||
|  |   // ASSERT(Success || ERROR_IO_PENDING == GetLastError()); | ||||||
|  |   // Success = GetOverlappedResult(Handle, &Overlapped, &BytesTransferred, | ||||||
|  |   // TRUE); ASSERT(Success); ASSERT(2 * SystemInfo.dwPageSize == | ||||||
|  |   // BytesTransferred); | ||||||
|  |   // | ||||||
|  |   // Overlapped.Offset = 0; | ||||||
|  |   // memset(AllocBuffer[1], 0, AllocBufferSize); | ||||||
|  |   // Success = ReadFile(Handle, Buffer[1], 2 * SystemInfo.dwPageSize, | ||||||
|  |   //                    &BytesTransferred, &Overlapped); | ||||||
|  |   // ASSERT(Success || ERROR_IO_PENDING == GetLastError()); | ||||||
|  |   // Success = GetOverlappedResult(Handle, &Overlapped, &BytesTransferred, | ||||||
|  |   // TRUE); ASSERT(Success); ASSERT(2 * SystemInfo.dwPageSize == | ||||||
|  |   // BytesTransferred); ASSERT(0 == memcmp(Buffer[0], Buffer[1], | ||||||
|  |   // BytesTransferred)); | ||||||
|  |   // | ||||||
|  |   // Overlapped.Offset = 0; | ||||||
|  |   // Success = | ||||||
|  |   //     WriteFile(Handle, Buffer[0], 2 * SystemInfo.dwPageSize + | ||||||
|  |   //     BytesPerSector, | ||||||
|  |   //               &BytesTransferred, &Overlapped); | ||||||
|  |   // ASSERT(Success || ERROR_IO_PENDING == GetLastError()); | ||||||
|  |   // Success = GetOverlappedResult(Handle, &Overlapped, &BytesTransferred, | ||||||
|  |   // TRUE); ASSERT(Success); ASSERT(2 * SystemInfo.dwPageSize + BytesPerSector | ||||||
|  |   // == BytesTransferred); | ||||||
|  |   // | ||||||
|  |   // Overlapped.Offset = 0; | ||||||
|  |   // memset(AllocBuffer[1], 0, AllocBufferSize); | ||||||
|  |   // Success = | ||||||
|  |   //     ReadFile(Handle, Buffer[1], 2 * SystemInfo.dwPageSize + BytesPerSector, | ||||||
|  |   //              &BytesTransferred, &Overlapped); | ||||||
|  |   // ASSERT(Success || ERROR_IO_PENDING == GetLastError()); | ||||||
|  |   // Success = GetOverlappedResult(Handle, &Overlapped, &BytesTransferred, | ||||||
|  |   // TRUE); ASSERT(Success); ASSERT(2 * SystemInfo.dwPageSize + BytesPerSector | ||||||
|  |   // == BytesTransferred); ASSERT(0 == memcmp(Buffer[0], Buffer[1], | ||||||
|  |   // BytesTransferred)); | ||||||
|  |   // | ||||||
|  |   EXPECT_TRUE(::CloseHandle(handle)); | ||||||
|  |  | ||||||
|  |   handle = ::CreateFileA(file_path.c_str(), GENERIC_READ | GENERIC_WRITE, | ||||||
|  |                          FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_EXISTING, | ||||||
|  |                          FILE_ATTRIBUTE_NORMAL | flags | FILE_FLAG_OVERLAPPED | | ||||||
|  |                              FILE_FLAG_DELETE_ON_CLOSE, | ||||||
|  |                          nullptr); | ||||||
|  |   ASSERT_NE(INVALID_HANDLE_VALUE, handle); | ||||||
|  |  | ||||||
|  |   // Overlapped.Offset = 0; | ||||||
|  |   // memset(AllocBuffer[1], 0, AllocBufferSize); | ||||||
|  |   // Success = | ||||||
|  |   //     ReadFile(Handle, Buffer[1], 2 * SystemInfo.dwPageSize + BytesPerSector, | ||||||
|  |   //              &BytesTransferred, &Overlapped); | ||||||
|  |   // ASSERT(Success || ERROR_IO_PENDING == GetLastError()); | ||||||
|  |   // Success = GetOverlappedResult(Handle, &Overlapped, &BytesTransferred, | ||||||
|  |   // TRUE); ASSERT(Success); ASSERT(2 * SystemInfo.dwPageSize + BytesPerSector | ||||||
|  |   // == BytesTransferred); ASSERT(0 == memcmp(Buffer[0], Buffer[1], | ||||||
|  |   // BytesTransferred)); | ||||||
|  |   // | ||||||
|  |   // Success = CloseHandle(Handle); | ||||||
|  |   // ASSERT(Success); | ||||||
|  |   // | ||||||
|  |   // Handle = | ||||||
|  |   //     CreateFileW(FilePath, GENERIC_READ | GENERIC_WRITE, | ||||||
|  |   //                 FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_EXISTING, 0, | ||||||
|  |   //                 0); | ||||||
|  |   // ASSERT(INVALID_HANDLE_VALUE == Handle); | ||||||
|  |   // ASSERT(ERROR_FILE_NOT_FOUND == GetLastError()); | ||||||
|  |   // | ||||||
|  |   // Success = CloseHandle(Overlapped.hEvent); | ||||||
|  |   // ASSERT(Success); | ||||||
|  |  | ||||||
|  |   EXPECT_TRUE(::CloseHandle(handle)); | ||||||
|  |  | ||||||
|  |   handle = ::CreateFileA(file_path.c_str(), GENERIC_READ | GENERIC_WRITE, | ||||||
|  |                          FILE_SHARE_READ | FILE_SHARE_WRITE, nullptr, | ||||||
|  |                          OPEN_EXISTING, 0, nullptr); | ||||||
|  |   EXPECT_EQ(INVALID_HANDLE_VALUE, handle); | ||||||
|  |   EXPECT_EQ(ERROR_FILE_NOT_FOUND, ::GetLastError()); | ||||||
|  | } | ||||||
|  |  | ||||||
| TYPED_TEST(winfsp_test, rdrw_can_read_and_write_file_no_flags) { | TYPED_TEST(winfsp_test, rdrw_can_read_and_write_file_no_flags) { | ||||||
|   auto file_path{ |   auto file_path{ | ||||||
|       utils::path::combine(this->mount_location, {"test_file_5"}), |       utils::path::combine(this->mount_location, {"test_file_5"}), | ||||||
| @@ -300,6 +483,28 @@ TYPED_TEST(winfsp_test, rdrw_can_append_file_write_through) { | |||||||
|   }; |   }; | ||||||
|   test_append_file(this->mount_location, file_path, FILE_FLAG_WRITE_THROUGH); |   test_append_file(this->mount_location, file_path, FILE_FLAG_WRITE_THROUGH); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | TYPED_TEST(winfsp_test, rdrw_can_read_and_write_overlapped_file_no_flags) { | ||||||
|  |   auto file_path{ | ||||||
|  |       utils::path::combine(this->mount_location, {"test_file_5"}), | ||||||
|  |   }; | ||||||
|  |   test_overlapped_file(this->mount_location, file_path, 0U); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | TYPED_TEST(winfsp_test, rdrw_can_read_and_write_overlapped_file_no_buffering) { | ||||||
|  |   auto file_path{ | ||||||
|  |       utils::path::combine(this->mount_location, {"test_file_5"}), | ||||||
|  |   }; | ||||||
|  |   test_overlapped_file(this->mount_location, file_path, FILE_FLAG_NO_BUFFERING); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | TYPED_TEST(winfsp_test, rdrw_can_read_and_write_file_overlapped_write_through) { | ||||||
|  |   auto file_path{ | ||||||
|  |       utils::path::combine(this->mount_location, {"test_file_5"}), | ||||||
|  |   }; | ||||||
|  |   test_overlapped_file(this->mount_location, file_path, | ||||||
|  |                        FILE_FLAG_WRITE_THROUGH); | ||||||
|  | } | ||||||
| } // namespace repertory | } // namespace repertory | ||||||
|  |  | ||||||
| #endif // defined(_WIN32) | #endif // defined(_WIN32) | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user