| OLD | NEW | 
 | (Empty) | 
|    1 // Copyright 2015 The Chromium Authors. All rights reserved. |  | 
|    2 // Use of this source code is governed by a BSD-style license that can be |  | 
|    3 // found in the LICENSE file. |  | 
|    4  |  | 
|    5 #include "files/public/c/lib/file_fd_impl.h" |  | 
|    6  |  | 
|    7 #include <errno.h> |  | 
|    8  |  | 
|    9 #include <string> |  | 
|   10  |  | 
|   11 #include "files/public/c/mojio_sys_stat.h" |  | 
|   12 #include "files/public/c/mojio_unistd.h" |  | 
|   13 #include "files/public/c/tests/mock_errno_impl.h" |  | 
|   14 #include "files/public/c/tests/mojio_impl_test_base.h" |  | 
|   15 #include "files/public/c/tests/test_utils.h" |  | 
|   16 #include "files/public/interfaces/files.mojom.h" |  | 
|   17 #include "files/public/interfaces/types.mojom.h" |  | 
|   18  |  | 
|   19 namespace mojio { |  | 
|   20 namespace { |  | 
|   21  |  | 
|   22 using FileFDImplTest = mojio::test::MojioImplTestBase; |  | 
|   23  |  | 
|   24 const int kLastErrorSentinel = -12345; |  | 
|   25  |  | 
|   26 TEST_F(FileFDImplTest, ConstructClose) { |  | 
|   27   test::MockErrnoImpl errno_impl(kLastErrorSentinel); |  | 
|   28   FileFDImpl ffdi(&errno_impl, |  | 
|   29                   test::OpenFileAt(&directory(), "my_file", |  | 
|   30                                    mojo::files::kOpenFlagWrite | |  | 
|   31                                        mojo::files::kOpenFlagCreate)); |  | 
|   32   EXPECT_EQ(kLastErrorSentinel, errno_impl.Get());  // No error. |  | 
|   33  |  | 
|   34   errno_impl.Reset(kLastErrorSentinel); |  | 
|   35   EXPECT_TRUE(ffdi.Close()); |  | 
|   36   EXPECT_EQ(kLastErrorSentinel, errno_impl.Get());  // No error. |  | 
|   37 } |  | 
|   38  |  | 
|   39 TEST_F(FileFDImplTest, Dup) { |  | 
|   40   test::CreateTestFileAt(&directory(), "my_file", 1000); |  | 
|   41  |  | 
|   42   test::MockErrnoImpl errno_impl(kLastErrorSentinel); |  | 
|   43   FileFDImpl ffdi(&errno_impl, test::OpenFileAt(&directory(), "my_file", |  | 
|   44                                                 mojo::files::kOpenFlagRead)); |  | 
|   45   EXPECT_EQ(kLastErrorSentinel, errno_impl.Get());  // No error. |  | 
|   46  |  | 
|   47   errno_impl.Reset(kLastErrorSentinel); |  | 
|   48   std::unique_ptr<FDImpl> duped_ffdi = ffdi.Dup(); |  | 
|   49   EXPECT_TRUE(duped_ffdi); |  | 
|   50   EXPECT_EQ(kLastErrorSentinel, errno_impl.Get());  // No error. |  | 
|   51  |  | 
|   52   // Seeking in one should change the position in the other. |  | 
|   53   errno_impl.Reset(kLastErrorSentinel); |  | 
|   54   EXPECT_EQ(123, ffdi.Lseek(123, MOJIO_SEEK_SET)); |  | 
|   55   EXPECT_EQ(kLastErrorSentinel, errno_impl.Get());  // No error. |  | 
|   56   errno_impl.Reset(kLastErrorSentinel); |  | 
|   57   EXPECT_EQ(123, duped_ffdi->Lseek(0, MOJIO_SEEK_CUR)); |  | 
|   58   EXPECT_EQ(kLastErrorSentinel, errno_impl.Get());  // No error. |  | 
|   59  |  | 
|   60   // And vice versa. |  | 
|   61   errno_impl.Reset(kLastErrorSentinel); |  | 
|   62   EXPECT_EQ(123 + 456, duped_ffdi->Lseek(456, MOJIO_SEEK_CUR)); |  | 
|   63   EXPECT_EQ(kLastErrorSentinel, errno_impl.Get());  // No error. |  | 
|   64   errno_impl.Reset(kLastErrorSentinel); |  | 
|   65   EXPECT_EQ(123 + 456, ffdi.Lseek(0, MOJIO_SEEK_CUR)); |  | 
|   66   EXPECT_EQ(kLastErrorSentinel, errno_impl.Get());  // No error. |  | 
|   67 } |  | 
|   68  |  | 
|   69 TEST_F(FileFDImplTest, Ftruncate) { |  | 
|   70   test::CreateTestFileAt(&directory(), "my_file", 1000); |  | 
|   71  |  | 
|   72   test::MockErrnoImpl errno_impl(kLastErrorSentinel); |  | 
|   73   FileFDImpl ffdi(&errno_impl, test::OpenFileAt(&directory(), "my_file", |  | 
|   74                                                 mojo::files::kOpenFlagWrite)); |  | 
|   75   EXPECT_EQ(kLastErrorSentinel, errno_impl.Get());  // No error. |  | 
|   76  |  | 
|   77   // Truncate. |  | 
|   78   errno_impl.Reset(kLastErrorSentinel); |  | 
|   79   EXPECT_TRUE(ffdi.Ftruncate(123)); |  | 
|   80   EXPECT_EQ(kLastErrorSentinel, errno_impl.Get());  // No error. |  | 
|   81   EXPECT_EQ(123, test::GetFileSize(&directory(), "my_file")); |  | 
|   82  |  | 
|   83   // Can also extend. |  | 
|   84   errno_impl.Reset(kLastErrorSentinel); |  | 
|   85   EXPECT_TRUE(ffdi.Ftruncate(456)); |  | 
|   86   EXPECT_EQ(kLastErrorSentinel, errno_impl.Get());  // No error. |  | 
|   87   EXPECT_EQ(456, test::GetFileSize(&directory(), "my_file")); |  | 
|   88  |  | 
|   89   // TODO(vtl): Check file position after |Ftruncate()|. |  | 
|   90  |  | 
|   91   // Invalid size. |  | 
|   92   errno_impl.Reset(kLastErrorSentinel); |  | 
|   93   EXPECT_FALSE(ffdi.Ftruncate(-1)); |  | 
|   94   EXPECT_EQ(EINVAL, errno_impl.Get()); |  | 
|   95 } |  | 
|   96  |  | 
|   97 TEST_F(FileFDImplTest, Lseek) { |  | 
|   98   test::CreateTestFileAt(&directory(), "my_file", 123); |  | 
|   99  |  | 
|  100   test::MockErrnoImpl errno_impl(kLastErrorSentinel); |  | 
|  101   FileFDImpl ffdi(&errno_impl, test::OpenFileAt(&directory(), "my_file", |  | 
|  102                                                 mojo::files::kOpenFlagWrite)); |  | 
|  103   EXPECT_EQ(kLastErrorSentinel, errno_impl.Get());  // No error. |  | 
|  104  |  | 
|  105   // Seek and write in various places. |  | 
|  106  |  | 
|  107   // 5 from beginning. |  | 
|  108   errno_impl.Reset(kLastErrorSentinel); |  | 
|  109   EXPECT_EQ(5, ffdi.Lseek(5, MOJIO_SEEK_SET)); |  | 
|  110   EXPECT_EQ(kLastErrorSentinel, errno_impl.Get());  // No error. |  | 
|  111  |  | 
|  112   // Write a byte. |  | 
|  113   errno_impl.Reset(kLastErrorSentinel); |  | 
|  114   char c = 42; |  | 
|  115   EXPECT_EQ(1, ffdi.Write(&c, 1)); |  | 
|  116   EXPECT_EQ(kLastErrorSentinel, errno_impl.Get());  // No error. |  | 
|  117  |  | 
|  118   // 42 from current. |  | 
|  119   errno_impl.Reset(kLastErrorSentinel); |  | 
|  120   EXPECT_EQ(5 + 1 + 42, ffdi.Lseek(42, MOJIO_SEEK_CUR)); |  | 
|  121   EXPECT_EQ(kLastErrorSentinel, errno_impl.Get());  // No error. |  | 
|  122  |  | 
|  123   // Write a byte. |  | 
|  124   errno_impl.Reset(kLastErrorSentinel); |  | 
|  125   c = 5; |  | 
|  126   EXPECT_EQ(1, ffdi.Write(&c, 1)); |  | 
|  127   EXPECT_EQ(kLastErrorSentinel, errno_impl.Get());  // No error. |  | 
|  128  |  | 
|  129   // 5 before end. |  | 
|  130   errno_impl.Reset(kLastErrorSentinel); |  | 
|  131   EXPECT_EQ(123 - 5, ffdi.Lseek(-5, MOJIO_SEEK_END)); |  | 
|  132   EXPECT_EQ(kLastErrorSentinel, errno_impl.Get());  // No error. |  | 
|  133  |  | 
|  134   // Write a byte. |  | 
|  135   errno_impl.Reset(kLastErrorSentinel); |  | 
|  136   c = 0; |  | 
|  137   EXPECT_EQ(1, ffdi.Write(&c, 1)); |  | 
|  138   EXPECT_EQ(kLastErrorSentinel, errno_impl.Get());  // No error. |  | 
|  139  |  | 
|  140   // Now read everything and check. |  | 
|  141   std::string expected_contents(123, '\0'); |  | 
|  142   for (size_t i = 0; i < 123; i++) { |  | 
|  143     unsigned char c = static_cast<unsigned char>(i); |  | 
|  144     expected_contents[i] = *reinterpret_cast<char*>(&c); |  | 
|  145   } |  | 
|  146   expected_contents[5] = 42; |  | 
|  147   expected_contents[5 + 1 + 42] = 5; |  | 
|  148   expected_contents[123 - 5] = 0; |  | 
|  149   EXPECT_EQ(expected_contents, test::GetFileContents(&directory(), "my_file")); |  | 
|  150 } |  | 
|  151  |  | 
|  152 TEST_F(FileFDImplTest, Read) { |  | 
|  153   test::CreateTestFileAt(&directory(), "my_file", 123); |  | 
|  154  |  | 
|  155   test::MockErrnoImpl errno_impl(kLastErrorSentinel); |  | 
|  156   FileFDImpl ffdi(&errno_impl, test::OpenFileAt(&directory(), "my_file", |  | 
|  157                                                 mojo::files::kOpenFlagRead)); |  | 
|  158   EXPECT_EQ(kLastErrorSentinel, errno_impl.Get());  // No error. |  | 
|  159  |  | 
|  160   // Read a bit. |  | 
|  161   errno_impl.Reset(kLastErrorSentinel); |  | 
|  162   unsigned char buffer[1000] = {}; |  | 
|  163   EXPECT_EQ(23, ffdi.Read(buffer, 23)); |  | 
|  164   EXPECT_EQ(kLastErrorSentinel, errno_impl.Get());  // No error. |  | 
|  165   for (size_t i = 0; i < 23; i++) |  | 
|  166     EXPECT_EQ(static_cast<unsigned char>(i), buffer[i]) << i; |  | 
|  167  |  | 
|  168   // Read too much. |  | 
|  169   errno_impl.Reset(kLastErrorSentinel); |  | 
|  170   EXPECT_EQ(100, ffdi.Read(buffer, sizeof(buffer))); |  | 
|  171   EXPECT_EQ(kLastErrorSentinel, errno_impl.Get());  // No error. |  | 
|  172   for (size_t i = 0; i < 100; i++) |  | 
|  173     EXPECT_EQ(static_cast<unsigned char>(23 + i), buffer[i]) << i; |  | 
|  174  |  | 
|  175   // Invalid |count| (must fit within |ssize_t|). |  | 
|  176   errno_impl.Reset(kLastErrorSentinel); |  | 
|  177   EXPECT_EQ(-1, ffdi.Read(buffer, static_cast<size_t>(-1))); |  | 
|  178   EXPECT_EQ(EINVAL, errno_impl.Get()); |  | 
|  179 } |  | 
|  180  |  | 
|  181 TEST_F(FileFDImplTest, Write) { |  | 
|  182   test::MockErrnoImpl errno_impl(kLastErrorSentinel); |  | 
|  183   FileFDImpl ffdi(&errno_impl, |  | 
|  184                   test::OpenFileAt(&directory(), "my_file", |  | 
|  185                                    mojo::files::kOpenFlagWrite | |  | 
|  186                                        mojo::files::kOpenFlagCreate | |  | 
|  187                                        mojo::files::kOpenFlagExclusive)); |  | 
|  188   EXPECT_EQ(kLastErrorSentinel, errno_impl.Get());  // No error. |  | 
|  189  |  | 
|  190   // Write something. |  | 
|  191   errno_impl.Reset(kLastErrorSentinel); |  | 
|  192   const char kHello[] = {'h', 'e', 'l', 'l', 'o', ' '}; |  | 
|  193   EXPECT_EQ(static_cast<mojio_off_t>(sizeof(kHello)), |  | 
|  194             ffdi.Write(kHello, sizeof(kHello))); |  | 
|  195  |  | 
|  196   // Write something else. |  | 
|  197   const char kMojio[] = {'m', 'o', 'j', 'i', 'o'}; |  | 
|  198   EXPECT_EQ(static_cast<mojio_off_t>(sizeof(kMojio)), |  | 
|  199             ffdi.Write(kMojio, sizeof(kMojio))); |  | 
|  200  |  | 
|  201   EXPECT_EQ(std::string("hello mojio"), |  | 
|  202             test::GetFileContents(&directory(), "my_file")); |  | 
|  203  |  | 
|  204   // Invalid |count| (must fit within |ssize_t|). |  | 
|  205   errno_impl.Reset(kLastErrorSentinel); |  | 
|  206   EXPECT_EQ(-1, ffdi.Write(kHello, static_cast<size_t>(-1))); |  | 
|  207   EXPECT_EQ(EINVAL, errno_impl.Get()); |  | 
|  208 } |  | 
|  209  |  | 
|  210 TEST_F(FileFDImplTest, Fstat) { |  | 
|  211   test::CreateTestFileAt(&directory(), "my_file_0", 0); |  | 
|  212   test::CreateTestFileAt(&directory(), "my_file_1", 512); |  | 
|  213   test::CreateTestFileAt(&directory(), "my_file_2", 513); |  | 
|  214  |  | 
|  215   test::MockErrnoImpl errno_impl(kLastErrorSentinel); |  | 
|  216   FileFDImpl ffdi0(&errno_impl, test::OpenFileAt(&directory(), "my_file_0", |  | 
|  217                                                  mojo::files::kOpenFlagRead)); |  | 
|  218   FileFDImpl ffdi1(&errno_impl, test::OpenFileAt(&directory(), "my_file_1", |  | 
|  219                                                  mojo::files::kOpenFlagRead)); |  | 
|  220   FileFDImpl ffdi2(&errno_impl, test::OpenFileAt(&directory(), "my_file_2", |  | 
|  221                                                  mojo::files::kOpenFlagRead)); |  | 
|  222   EXPECT_EQ(kLastErrorSentinel, errno_impl.Get());  // No error. |  | 
|  223  |  | 
|  224   errno_impl.Reset(kLastErrorSentinel); |  | 
|  225   struct mojio_stat buf0 = {}; |  | 
|  226   EXPECT_TRUE(ffdi0.Fstat(&buf0)); |  | 
|  227   EXPECT_EQ(kLastErrorSentinel, errno_impl.Get());  // No error. |  | 
|  228   // Note: Don't check the unfilled values. (Some of the checks may also be |  | 
|  229   // fragile, depending on our level of support.) |  | 
|  230   EXPECT_EQ(static_cast<mojio_mode_t>(MOJIO_S_IRWXU | MOJIO_S_IFREG), |  | 
|  231             buf0.st_mode);       // Fragile. |  | 
|  232   EXPECT_EQ(1u, buf0.st_nlink);  // Fragile. |  | 
|  233   EXPECT_EQ(0, buf0.st_size); |  | 
|  234   // Just check that |st_atim.tv_sec|, etc. are positive (a bit fragile). |  | 
|  235   EXPECT_GT(buf0.st_atim.tv_sec, 0); |  | 
|  236   EXPECT_GT(buf0.st_mtim.tv_sec, 0); |  | 
|  237   EXPECT_GT(buf0.st_ctim.tv_sec, 0); |  | 
|  238   EXPECT_EQ(1024, buf0.st_blksize);  // Fragile. |  | 
|  239   EXPECT_EQ(0u, buf0.st_blocks); |  | 
|  240  |  | 
|  241   errno_impl.Reset(kLastErrorSentinel); |  | 
|  242   struct mojio_stat buf1 = {}; |  | 
|  243   EXPECT_TRUE(ffdi1.Fstat(&buf1)); |  | 
|  244   EXPECT_EQ(kLastErrorSentinel, errno_impl.Get());  // No error. |  | 
|  245   // Only check the things that should be (interestingly) different. |  | 
|  246   EXPECT_EQ(512, buf1.st_size); |  | 
|  247   EXPECT_EQ(1u, buf1.st_blocks); |  | 
|  248  |  | 
|  249   errno_impl.Reset(kLastErrorSentinel); |  | 
|  250   struct mojio_stat buf2 = {}; |  | 
|  251   EXPECT_TRUE(ffdi2.Fstat(&buf2)); |  | 
|  252   EXPECT_EQ(kLastErrorSentinel, errno_impl.Get());  // No error. |  | 
|  253   // Only check the things that should be (interestingly) different. |  | 
|  254   EXPECT_EQ(513, buf2.st_size); |  | 
|  255   EXPECT_EQ(2u, buf2.st_blocks); |  | 
|  256 } |  | 
|  257  |  | 
|  258 TEST_F(FileFDImplTest, Efault) { |  | 
|  259   test::MockErrnoImpl errno_impl(kLastErrorSentinel); |  | 
|  260   FileFDImpl ffdi(&errno_impl, |  | 
|  261                   test::OpenFileAt(&directory(), "my_file", |  | 
|  262                                    mojo::files::kOpenFlagRead | |  | 
|  263                                        mojo::files::kOpenFlagWrite | |  | 
|  264                                        mojo::files::kOpenFlagCreate | |  | 
|  265                                        mojo::files::kOpenFlagExclusive)); |  | 
|  266   EXPECT_EQ(kLastErrorSentinel, errno_impl.Get());  // No error. |  | 
|  267  |  | 
|  268   errno_impl.Reset(kLastErrorSentinel); |  | 
|  269   EXPECT_EQ(-1, ffdi.Read(nullptr, 1)); |  | 
|  270   EXPECT_EQ(EFAULT, errno_impl.Get()); |  | 
|  271  |  | 
|  272   errno_impl.Reset(kLastErrorSentinel); |  | 
|  273   EXPECT_EQ(-1, ffdi.Write(nullptr, 1)); |  | 
|  274   EXPECT_EQ(EFAULT, errno_impl.Get()); |  | 
|  275  |  | 
|  276   errno_impl.Reset(kLastErrorSentinel); |  | 
|  277   EXPECT_FALSE(ffdi.Fstat(nullptr)); |  | 
|  278   EXPECT_EQ(EFAULT, errno_impl.Get()); |  | 
|  279 } |  | 
|  280  |  | 
|  281 }  // namespace |  | 
|  282 }  // namespace mojio |  | 
| OLD | NEW |