/* Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include #include "mock_logger.h" #include "file_io.h" #include "test_utils.h" #if defined(HAVE_PSI_INTERFACE) #if !defined(MERGE_UNITTESTS) namespace keyring { PSI_memory_key key_memory_KEYRING = PSI_NOT_INSTRUMENTED; PSI_memory_key key_LOCK_keyring = PSI_NOT_INSTRUMENTED; } #endif namespace keyring { extern PSI_file_key keyring_file_data_key; extern PSI_file_key keyring_backup_file_data_key; } #endif namespace keyring__file_io_unittest { using ::testing::StrEq; using ::testing::StartsWith; using keyring::Mock_logger; using my_testing::Server_initializer; class File_io_test : public ::testing::Test { protected: virtual void SetUp() { keyring::keyring_file_data_key = PSI_NOT_INSTRUMENTED; keyring::keyring_backup_file_data_key = PSI_NOT_INSTRUMENTED; logger= new Mock_logger(); initializer.SetUp(); //Set user as super Security_context* sec_ctx= current_thd->security_context(); sec_ctx->set_master_access(sec_ctx->master_access() | SUPER_ACL); } virtual void TearDown() { delete logger; initializer.TearDown(); } protected: Server_initializer initializer; //needed to initialize current_thd Mock_logger *logger; }; //Those tests are to check if methods inside File_io do not call my_error but //instead generate warnings for filesystem operations errors. If one of those //functions would call my_error then error would be set and we would have to call //initializer.set_expected_error. As we do not call this in any functions this //proves that my_error is not called. Also these tests make sure that correct //messages are generated TEST_F(File_io_test, OpenNotExistingFile) { keyring::File_io file_io(logger); remove("./some_funny_name"); //just to be sure some_funny_name does not exist EXPECT_CALL(*logger, log(MY_ERROR_LEVEL, StrEq("File './some_funny_name' not found " "(Errcode: 2 - No such file or directory)"))); File file= file_io.open(keyring::keyring_file_data_key, "./some_funny_name", O_RDONLY, MYF(MY_WME)); ASSERT_TRUE(file < 0); //could not open the file } TEST_F(File_io_test, CloseTwiceTheSame) { keyring::File_io file_io(logger); File file= file_io.open(keyring::keyring_file_data_key, "./some_funny_name", O_RDONLY | O_CREAT, MYF(MY_WME)); ASSERT_TRUE(file >= 0); //successfully created file_io.close(file, MYF(MY_WME)); EXPECT_CALL(*logger, log(MY_ERROR_LEVEL, StartsWith("Error on close of"))); ASSERT_TRUE(file_io.close(file, MYF(MY_WME)) != 0); remove("./some_funny_name"); } TEST_F(File_io_test, ReadFromInvalidFileDescriptor) { keyring::File_io file_io(logger); File file=2050; uchar buff[2]; EXPECT_CALL(*logger, log(MY_ERROR_LEVEL, StartsWith("Error reading file"))); ASSERT_TRUE(file_io.read(file, buff, 10, MYF(MY_WME)) != 10); } TEST_F(File_io_test, WriteToInvalidFileDescriptor) { keyring::File_io file_io(logger); File file=2050; EXPECT_CALL(*logger, log(MY_ERROR_LEVEL, StartsWith("Error writing file"))); ASSERT_TRUE(file_io.write(file, reinterpret_cast("123"), 10, MYF(MY_WME)) != 10); } TEST_F(File_io_test, SeekOnInvalidFileDescriptor) { keyring::File_io file_io(logger); File file=2050; EXPECT_CALL(*logger, log(MY_ERROR_LEVEL, StartsWith("Can't seek in file"))); ASSERT_TRUE(file_io.seek(file, 0, MY_SEEK_END, MYF(MY_WME)) == MY_FILEPOS_ERROR); } TEST_F(File_io_test, TellOnInvalidFileDescriptor) { keyring::File_io file_io(logger); File file=2050; EXPECT_CALL(*logger, log(MY_ERROR_LEVEL, StartsWith("Can't seek in file"))); ASSERT_TRUE(file_io.tell(file, MYF(MY_WME)) == ((my_off_t) -1)); } TEST_F(File_io_test, SyncOnInvalidFileDescriptor) { keyring::File_io file_io(logger); File file=2050; EXPECT_CALL(*logger, log(MY_ERROR_LEVEL, StartsWith("Can't sync file"))); ASSERT_TRUE(file_io.sync(file, MYF(MY_WME)) != 0); } TEST_F(File_io_test, FStatOnInvalidFileDescriptor) { keyring::File_io file_io(logger); File file=2050; EXPECT_CALL(*logger, log(MY_ERROR_LEVEL, StartsWith("Error while reading stat for"))); MY_STAT keyring_file_stat; ASSERT_TRUE(file_io.fstat(file, &keyring_file_stat, MYF(MY_WME)) != 0); } TEST_F(File_io_test, RemoveNotExistingFile) { keyring::File_io file_io(logger); remove("./some_funny_name"); //just to be sure some_funny_name does not exist EXPECT_CALL(*logger, log(MY_ERROR_LEVEL, StrEq("Could not remove file ./some_funny_name OS " "retuned this error: No such file or directory"))); ASSERT_TRUE(file_io.remove("./some_funny_name", MYF(MY_WME)) != 0); } TEST_F(File_io_test, TruncateOnNotExistingFile) { keyring::File_io file_io(logger); File file=2050; EXPECT_CALL(*logger, log(MY_ERROR_LEVEL, StartsWith("Could not truncate file"))); ASSERT_TRUE(file_io.truncate(file, MYF(MY_WME)) != 0); } } //namespace keyring__file_io_unittest