• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* Copyright 2019 The TensorFlow Authors. All Rights Reserved.
2 
3 Licensed under the Apache License, Version 2.0 (the "License");
4 you may not use this file except in compliance with the License.
5 You may obtain a copy of the License at
6 
7     http://www.apache.org/licenses/LICENSE-2.0
8 
9 Unless required by applicable law or agreed to in writing, software
10 distributed under the License is distributed on an "AS IS" BASIS,
11 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 See the License for the specific language governing permissions and
13 limitations under the License.
14 ==============================================================================*/
15 #include "tensorflow/c/experimental/filesystem/modular_filesystem.h"
16 
17 #include <memory>
18 #include <random>
19 #include <string>
20 
21 #include "tensorflow/core/lib/io/path.h"
22 #include "tensorflow/core/platform/env.h"
23 #include "tensorflow/core/platform/error.h"
24 #include "tensorflow/core/platform/stacktrace_handler.h"
25 #include "tensorflow/core/platform/test.h"
26 #include "tensorflow/core/util/command_line_flags.h"
27 
28 #if defined(PLATFORM_WINDOWS)
29 // Make mkdir resolve to _mkdir to create the test temporary directory.
30 #include <direct.h>
31 #define mkdir(name, mode) _mkdir(name)
32 
33 // Windows defines the following macros to convert foo to fooA or fooW,
34 // depending on the type of the string argument. We don't use these macros, so
35 // undefine them here.
36 #undef CopyFile
37 #undef DeleteFile
38 #undef TranslateName
39 #endif  // defined(PLATFORM_WINDOWS)
40 
41 // The tests defined here test the compliance of filesystems with the API
42 // defined by `filesystem_interface.h`.
43 //
44 // As some filesystems require special setup, these tests are run manually.
45 //
46 // Each filesystem implementation can be provided by DSOs, so we provide the
47 // `--dsos` flag to specify a list of shared objects to be loaded in order.
48 // If the flag is not used, no shared objects are loaded.
49 //
50 // Every filesystem provides support for accessing URIs of form
51 // `[<scheme>://]<path>` where `<scheme>` is optional (if missing, we are
52 // accessing local paths). This test suite tests exactly one scheme for each
53 // invocation. By default, we are testing all schemes available but this can be
54 // restricted by using `--schemes` to specify a set of schemes to test.
55 //
56 // Example invocation:
57 //  bazel test //tensorflow/c/experimental/filesystem:modular_filesystem_test \\
58 //  --test_arg=--dso=/path/to/one.so --test_arg=--dso=/path/to/another.so \\
59 //  --test_arg=--scheme= --test_arg=--scheme=file
60 //
61 // Note that to test the local filesystem we use an empty value.
62 
63 namespace tensorflow {
64 namespace {
65 
66 using ::tensorflow::error::Code;
67 
68 // As we need to test multiple URI schemes we need a parameterized test.
69 // Furthermore, since each test creates and deletes files, we will use the same
70 // fixture to create new directories in `SetUp`. Each directory will reside in
71 // `::testing::TempDir()`, will use a RNG component and the test name. This
72 // ensures that two consecutive runs are unlikely to clash.
73 class ModularFileSystemTest : public ::testing::TestWithParam<std::string> {
74  public:
75   // Initializes `root_dir_` to a unique value made of `::testing::TempDir()`, a
76   // static random value unique for all the tests in one invocation, and the
77   // current test name.
78   //
79   // Since the test name contains `/` (due to parameters), this function
80   // replaces `/` with `_`.
81   //
82   // We trade in one extra initialization for readability.
ModularFileSystemTest()83   ModularFileSystemTest() {
84     const std::string test_name = tensorflow::str_util::StringReplace(
85         ::testing::UnitTest::GetInstance()->current_test_info()->name(), "/",
86         "_", /*replace_all=*/true);
87     if (!cloud_path_.empty()) {
88       // We have to join path for non-local filesystem manually to make sure
89       // that this test will run on Windows since `tensorflow::io::JoinPath`
90       // behaves differently on Windows. `tmp_dir` should be something like
91       // `path/to/tmp/dir/`. After joining path, we will have
92       // /path/to/tmp/dir/tf_fs_rng_name/`
93       root_dir_ = tensorflow::strings::StrCat(
94           "/", tmp_dir_,
95           tensorflow::strings::StrCat("tf_fs_", rng_val_, "_", test_name), "/");
96     } else {
97       root_dir_ = tensorflow::io::JoinPath(
98           tmp_dir_,
99           tensorflow::strings::StrCat("tf_fs_", rng_val_, "_", test_name));
100     }
101     if (!GetParam().empty()) {
102       root_dir_ = tensorflow::strings::StrCat(GetParam(), "://", cloud_path_,
103                                               root_dir_);
104     }
105     env_ = Env::Default();
106   }
107 
SetUp()108   void SetUp() override {
109     FileSystem* fs = nullptr;
110     Status s = env_->GetFileSystemForFile(root_dir_, &fs);
111     if (fs == nullptr || !s.ok())
112       GTEST_SKIP() << "No filesystem registered: " << s;
113 
114     s = fs->CreateDir(root_dir_);
115     if (!s.ok()) {
116       GTEST_SKIP() << "Cannot create working directory: " << s;
117     }
118   }
119 
120   // Converts path reference to URI reference.
121   //
122   // If URI scheme is empty, URI reference is `path` relative to current test
123   // root directory. Otherwise, we need to add the `<scheme>://` in front of
124   // this path.
125   //
126   // TODO(mihaimaruseac): Note that some filesystem might require a different
127   // approach here, for example they might require the root directory path to
128   // be in a special format, etc. When we get there, we might decide to move
129   // this class to `modular_filesystem_test.h` and extend the instantiation to
130   // also take as argument an implementation for this method/a subclass factory
131   // (see
132   // https://github.com/google/googletest/blob/master/googletest/docs/advanced.md#creating-value-parameterized-abstract-tests)
GetURIForPath(StringPiece path)133   std::string GetURIForPath(StringPiece path) {
134     const std::string translated_name =
135         tensorflow::io::JoinPath(root_dir_, path);
136     // We have already checked `GetParam().empty()` in
137     // `ModularFileSystemTest()`. root_dir_ should contain `GetParam() + "://"`
138     // if it isn't empty.
139     return translated_name;
140   }
141 
142   // Converts absolute paths to paths relative to root_dir_.
GetRelativePath(StringPiece absolute_path)143   StringPiece GetRelativePath(StringPiece absolute_path) {
144     return tensorflow::str_util::StripPrefix(absolute_path, root_dir_);
145   }
146 
147   // Initializes the randomness used to ensure test isolation.
InitializeTestRNG()148   static void InitializeTestRNG() {
149     std::random_device rd;
150     std::mt19937 gen(rd());
151     std::uniform_int_distribution<> distribution;
152     rng_val_ = distribution(gen);
153   }
154 
SetCloudPath(const std::string & cloud_path)155   static void SetCloudPath(const std::string& cloud_path) {
156     cloud_path_ = cloud_path;
157     if (cloud_path_.back() == '/') cloud_path_.pop_back();
158   }
159 
SetTmpDir(const std::string & tmp_dir)160   static void SetTmpDir(const std::string& tmp_dir) {
161     tmp_dir_ = tmp_dir.empty() ? ::testing::TempDir() : tmp_dir;
162   }
163 
164  protected:
165   Env* env_;
166 
167  private:
168   std::string root_dir_;
169   static int rng_val_;
170   static std::string cloud_path_;
171   static std::string tmp_dir_;
172 };
173 
174 int ModularFileSystemTest::rng_val_;
175 std::string ModularFileSystemTest::cloud_path_;
176 std::string ModularFileSystemTest::tmp_dir_;
177 
178 // As some of the implementations might be missing, the tests should still pass
179 // if the returned `Status` signals the unimplemented state.
UnimplementedOrReturnsCode(Status actual_status,Code expected_code)180 bool UnimplementedOrReturnsCode(Status actual_status, Code expected_code) {
181   Code actual_code = actual_status.code();
182   return (actual_code == Code::UNIMPLEMENTED) || (actual_code == expected_code);
183 }
184 
TEST_P(ModularFileSystemTest,TestTranslateName)185 TEST_P(ModularFileSystemTest, TestTranslateName) {
186   const std::string generic_path = GetURIForPath("some_path");
187   FileSystem* fs = nullptr;
188   Status s = env_->GetFileSystemForFile(generic_path, &fs);
189   if (fs == nullptr || !s.ok())
190     GTEST_SKIP() << "No filesystem registered: " << s;
191 
192   // First, test some interesting corner cases concerning empty URIs
193   if (GetParam().empty()) {
194     EXPECT_EQ(fs->TranslateName(""), "");
195     EXPECT_EQ(fs->TranslateName("/"), "/");
196     EXPECT_EQ(fs->TranslateName("//"), "/");
197     // Empty scheme also allows relative paths
198     EXPECT_EQ(fs->TranslateName("a_file"), "a_file");
199     EXPECT_EQ(fs->TranslateName("a_dir/.."), ".");
200   } else {
201     EXPECT_EQ(fs->TranslateName(tensorflow::strings::StrCat(GetParam(), "://")),
202               "/");
203     EXPECT_EQ(
204         fs->TranslateName(tensorflow::strings::StrCat(GetParam(), ":///")),
205         "/");
206     EXPECT_EQ(
207         fs->TranslateName(tensorflow::strings::StrCat(GetParam(), ":////")),
208         "/");
209   }
210 
211   // Now test several paths/URIs
212   EXPECT_EQ(GetRelativePath(fs->TranslateName(GetURIForPath("a_file"))),
213             "/a_file");
214   EXPECT_EQ(GetRelativePath(fs->TranslateName(GetURIForPath("a_dir/a_file"))),
215             "/a_dir/a_file");
216   EXPECT_EQ(GetRelativePath(fs->TranslateName(GetURIForPath("./a_file"))),
217             "/a_file");
218   EXPECT_EQ(GetRelativePath(fs->TranslateName(
219                 GetURIForPath("a/convoluted/../path/./to/.//.///a/file"))),
220             "/a/path/to/a/file");
221 }
222 
TEST_P(ModularFileSystemTest,TestCreateFile)223 TEST_P(ModularFileSystemTest, TestCreateFile) {
224   const std::string filepath = GetURIForPath("a_file");
225   std::unique_ptr<WritableFile> new_file;
226   Status status = env_->NewWritableFile(filepath, &new_file);
227   EXPECT_PRED2(UnimplementedOrReturnsCode, status, Code::OK);
228 }
229 
TEST_P(ModularFileSystemTest,TestCreateFileNonExisting)230 TEST_P(ModularFileSystemTest, TestCreateFileNonExisting) {
231   const std::string filepath = GetURIForPath("dir_not_found/a_file");
232   std::unique_ptr<WritableFile> new_file;
233   Status status = env_->NewWritableFile(filepath, &new_file);
234   EXPECT_PRED2(UnimplementedOrReturnsCode, status, Code::NOT_FOUND);
235 }
236 
TEST_P(ModularFileSystemTest,TestCreateFileExistingDir)237 TEST_P(ModularFileSystemTest, TestCreateFileExistingDir) {
238   const std::string filepath = GetURIForPath("a_file");
239   Status status = env_->CreateDir(filepath);
240   if (!status.ok()) GTEST_SKIP() << "CreateDir() not supported: " << status;
241 
242   std::unique_ptr<WritableFile> new_file;
243   status = env_->NewWritableFile(filepath, &new_file);
244   EXPECT_PRED2(UnimplementedOrReturnsCode, status, Code::FAILED_PRECONDITION);
245 }
246 
TEST_P(ModularFileSystemTest,TestCreateFilePathIsInvalid)247 TEST_P(ModularFileSystemTest, TestCreateFilePathIsInvalid) {
248   const std::string filepath = GetURIForPath("a_file");
249   std::unique_ptr<WritableFile> file;
250   Status status = env_->NewWritableFile(filepath, &file);
251   if (!status.ok()) GTEST_SKIP() << "CreateDir() not supported: " << status;
252 
253   const std::string new_path = GetURIForPath("a_file/a_file");
254   std::unique_ptr<WritableFile> new_file;
255   status = env_->NewWritableFile(new_path, &new_file);
256   EXPECT_PRED2(UnimplementedOrReturnsCode, status, Code::FAILED_PRECONDITION);
257 }
258 
TEST_P(ModularFileSystemTest,TestAppendFile)259 TEST_P(ModularFileSystemTest, TestAppendFile) {
260   const std::string filepath = GetURIForPath("a_file");
261   std::unique_ptr<WritableFile> new_file;
262   Status status = env_->NewAppendableFile(filepath, &new_file);
263   EXPECT_PRED2(UnimplementedOrReturnsCode, status, Code::OK);
264 }
265 
TEST_P(ModularFileSystemTest,TestAppendFileNonExisting)266 TEST_P(ModularFileSystemTest, TestAppendFileNonExisting) {
267   const std::string filepath = GetURIForPath("dir_not_found/a_file");
268   std::unique_ptr<WritableFile> new_file;
269   Status status = env_->NewAppendableFile(filepath, &new_file);
270   EXPECT_PRED2(UnimplementedOrReturnsCode, status, Code::NOT_FOUND);
271 }
272 
TEST_P(ModularFileSystemTest,TestAppendFileExistingDir)273 TEST_P(ModularFileSystemTest, TestAppendFileExistingDir) {
274   const std::string filepath = GetURIForPath("a_file");
275   Status status = env_->CreateDir(filepath);
276   if (!status.ok()) GTEST_SKIP() << "CreateDir() not supported: " << status;
277 
278   std::unique_ptr<WritableFile> new_file;
279   status = env_->NewAppendableFile(filepath, &new_file);
280   EXPECT_PRED2(UnimplementedOrReturnsCode, status, Code::FAILED_PRECONDITION);
281 }
282 
TEST_P(ModularFileSystemTest,TestCreateThenAppendFile)283 TEST_P(ModularFileSystemTest, TestCreateThenAppendFile) {
284   const std::string filepath = GetURIForPath("a_file");
285   std::unique_ptr<WritableFile> new_file;
286   Status status = env_->NewWritableFile(filepath, &new_file);
287   if (!status.ok())
288     GTEST_SKIP() << "NewWritableFile() not supported: " << status;
289 
290   std::unique_ptr<WritableFile> same_file;
291   status = env_->NewAppendableFile(filepath, &same_file);
292   EXPECT_PRED2(UnimplementedOrReturnsCode, status, Code::OK);
293 }
294 
TEST_P(ModularFileSystemTest,TestAppendFilePathIsInvalid)295 TEST_P(ModularFileSystemTest, TestAppendFilePathIsInvalid) {
296   const std::string filepath = GetURIForPath("a_file");
297   std::unique_ptr<WritableFile> file;
298   Status status = env_->NewWritableFile(filepath, &file);
299   if (!status.ok())
300     GTEST_SKIP() << "NewWritableFile() not supported: " << status;
301 
302   const std::string new_path = GetURIForPath("a_file/a_file");
303   std::unique_ptr<WritableFile> same_file;
304   status = env_->NewAppendableFile(new_path, &same_file);
305   EXPECT_PRED2(UnimplementedOrReturnsCode, status, Code::FAILED_PRECONDITION);
306 }
307 
TEST_P(ModularFileSystemTest,TestReadFile)308 TEST_P(ModularFileSystemTest, TestReadFile) {
309   const std::string filepath = GetURIForPath("a_file");
310   std::unique_ptr<RandomAccessFile> new_file;
311   Status status = env_->NewRandomAccessFile(filepath, &new_file);
312   EXPECT_PRED2(UnimplementedOrReturnsCode, status, Code::NOT_FOUND);
313 }
314 
TEST_P(ModularFileSystemTest,TestReadFileNonExisting)315 TEST_P(ModularFileSystemTest, TestReadFileNonExisting) {
316   const std::string filepath = GetURIForPath("dir_not_found/a_file");
317   std::unique_ptr<RandomAccessFile> new_file;
318   Status status = env_->NewRandomAccessFile(filepath, &new_file);
319   EXPECT_PRED2(UnimplementedOrReturnsCode, status, Code::NOT_FOUND);
320 }
321 
TEST_P(ModularFileSystemTest,TestReadFileExistingDir)322 TEST_P(ModularFileSystemTest, TestReadFileExistingDir) {
323   const std::string filepath = GetURIForPath("a_file");
324   Status status = env_->CreateDir(filepath);
325   if (!status.ok()) GTEST_SKIP() << "CreateDir() not supported: " << status;
326 
327   std::unique_ptr<RandomAccessFile> new_file;
328   status = env_->NewRandomAccessFile(filepath, &new_file);
329   EXPECT_PRED2(UnimplementedOrReturnsCode, status, Code::FAILED_PRECONDITION);
330 }
331 
TEST_P(ModularFileSystemTest,TestCreateThenReadFile)332 TEST_P(ModularFileSystemTest, TestCreateThenReadFile) {
333   const std::string filepath = GetURIForPath("a_file");
334   std::unique_ptr<WritableFile> new_file;
335   Status status = env_->NewWritableFile(filepath, &new_file);
336   if (!status.ok())
337     GTEST_SKIP() << "NewWritableFile() not supported: " << status;
338 
339   std::unique_ptr<RandomAccessFile> same_file;
340   status = env_->NewRandomAccessFile(filepath, &same_file);
341   EXPECT_PRED2(UnimplementedOrReturnsCode, status, Code::OK);
342 }
343 
TEST_P(ModularFileSystemTest,TestReadFilePathIsInvalid)344 TEST_P(ModularFileSystemTest, TestReadFilePathIsInvalid) {
345   const std::string filepath = GetURIForPath("a_file");
346   std::unique_ptr<WritableFile> file;
347   Status status = env_->NewWritableFile(filepath, &file);
348   if (!status.ok())
349     GTEST_SKIP() << "NewWritableFile() not supported: " << status;
350 
351   const std::string new_path = GetURIForPath("a_file/a_file");
352   std::unique_ptr<RandomAccessFile> same_file;
353   status = env_->NewRandomAccessFile(new_path, &same_file);
354   EXPECT_PRED2(UnimplementedOrReturnsCode, status, Code::FAILED_PRECONDITION);
355 }
356 
TEST_P(ModularFileSystemTest,TestCreateMemoryRegion)357 TEST_P(ModularFileSystemTest, TestCreateMemoryRegion) {
358   const std::string filepath = GetURIForPath("a_file");
359   std::unique_ptr<ReadOnlyMemoryRegion> region;
360   Status status = env_->NewReadOnlyMemoryRegionFromFile(filepath, &region);
361   EXPECT_PRED2(UnimplementedOrReturnsCode, status, Code::NOT_FOUND);
362 }
363 
TEST_P(ModularFileSystemTest,TestCreateMemoryRegionNonExisting)364 TEST_P(ModularFileSystemTest, TestCreateMemoryRegionNonExisting) {
365   const std::string filepath = GetURIForPath("dir_not_found/a_file");
366   std::unique_ptr<ReadOnlyMemoryRegion> region;
367   Status status = env_->NewReadOnlyMemoryRegionFromFile(filepath, &region);
368   EXPECT_PRED2(UnimplementedOrReturnsCode, status, Code::NOT_FOUND);
369 }
370 
TEST_P(ModularFileSystemTest,TestCreateMemoryRegionExistingDir)371 TEST_P(ModularFileSystemTest, TestCreateMemoryRegionExistingDir) {
372   const std::string filepath = GetURIForPath("a_file");
373   Status status = env_->CreateDir(filepath);
374   if (!status.ok()) GTEST_SKIP() << "CreateDir() not supported: " << status;
375 
376   std::unique_ptr<ReadOnlyMemoryRegion> new_file;
377   status = env_->NewReadOnlyMemoryRegionFromFile(filepath, &new_file);
378   EXPECT_PRED2(UnimplementedOrReturnsCode, status, Code::FAILED_PRECONDITION);
379 }
380 
TEST_P(ModularFileSystemTest,TestCreateMemoryRegionFromEmptyFile)381 TEST_P(ModularFileSystemTest, TestCreateMemoryRegionFromEmptyFile) {
382   const std::string filepath = GetURIForPath("a_file");
383   std::unique_ptr<WritableFile> new_file;
384   Status status = env_->NewWritableFile(filepath, &new_file);
385   if (!status.ok())
386     GTEST_SKIP() << "NewWritableFile() not supported: " << status;
387 
388   std::unique_ptr<ReadOnlyMemoryRegion> region;
389   status = env_->NewReadOnlyMemoryRegionFromFile(filepath, &region);
390   EXPECT_PRED2(UnimplementedOrReturnsCode, status, Code::INVALID_ARGUMENT);
391 }
392 
TEST_P(ModularFileSystemTest,TestCreateMemoryRegionFromFile)393 TEST_P(ModularFileSystemTest, TestCreateMemoryRegionFromFile) {
394   const std::string filepath = GetURIForPath("a_file");
395   std::unique_ptr<WritableFile> new_file;
396   Status status = env_->NewWritableFile(filepath, &new_file);
397   if (!status.ok())
398     GTEST_SKIP() << "NewWritableFile() not supported: " << status;
399 
400   const std::string test_data("asdf");
401   status = new_file->Append(test_data);
402   if (!status.ok()) GTEST_SKIP() << "Append() not supported: " << status;
403   status = new_file->Flush();
404   if (!status.ok()) GTEST_SKIP() << "Flush() not supported: " << status;
405   status = new_file->Close();
406   if (!status.ok()) GTEST_SKIP() << "Close() not supported: " << status;
407 
408   std::unique_ptr<ReadOnlyMemoryRegion> region;
409   status = env_->NewReadOnlyMemoryRegionFromFile(filepath, &region);
410   EXPECT_PRED2(UnimplementedOrReturnsCode, status, Code::OK);
411   if (!status.ok())
412     GTEST_SKIP() << "NewReadOnlyMemoryRegionFromFile() not supported: "
413                  << status;
414   EXPECT_EQ(region->length(), test_data.size());
415   EXPECT_STREQ(reinterpret_cast<const char*>(region->data()),
416                test_data.c_str());
417 }
418 
TEST_P(ModularFileSystemTest,TestCreateMemoryRegionFromFilePathIsInvalid)419 TEST_P(ModularFileSystemTest, TestCreateMemoryRegionFromFilePathIsInvalid) {
420   const std::string filepath = GetURIForPath("a_file");
421   std::unique_ptr<WritableFile> file;
422   Status status = env_->NewWritableFile(filepath, &file);
423   if (!status.ok())
424     GTEST_SKIP() << "NewWritableFile() not supported: " << status;
425 
426   std::string new_path = GetURIForPath("a_file/a_file");
427   std::unique_ptr<ReadOnlyMemoryRegion> region;
428   status = env_->NewReadOnlyMemoryRegionFromFile(new_path, &region);
429   EXPECT_PRED2(UnimplementedOrReturnsCode, status, Code::FAILED_PRECONDITION);
430 }
431 
TEST_P(ModularFileSystemTest,TestCreateDir)432 TEST_P(ModularFileSystemTest, TestCreateDir) {
433   const std::string dirpath = GetURIForPath("a_dir");
434   Status status = env_->CreateDir(dirpath);
435   EXPECT_PRED2(UnimplementedOrReturnsCode, status, Code::OK);
436 }
437 
TEST_P(ModularFileSystemTest,TestCreateDirNoParent)438 TEST_P(ModularFileSystemTest, TestCreateDirNoParent) {
439   const std::string dirpath = GetURIForPath("dir_not_found/a_dir");
440   Status status = env_->CreateDir(dirpath);
441   EXPECT_PRED2(UnimplementedOrReturnsCode, status, Code::NOT_FOUND);
442 }
443 
TEST_P(ModularFileSystemTest,TestCreateDirWhichIsFile)444 TEST_P(ModularFileSystemTest, TestCreateDirWhichIsFile) {
445   const std::string filepath = GetURIForPath("a_file");
446   std::unique_ptr<WritableFile> new_file;
447   Status status = env_->NewWritableFile(filepath, &new_file);
448   if (!status.ok())
449     GTEST_SKIP() << "NewWritableFile() not supported: " << status;
450 
451   status = env_->CreateDir(filepath);
452   EXPECT_PRED2(UnimplementedOrReturnsCode, status, Code::ALREADY_EXISTS);
453 }
454 
TEST_P(ModularFileSystemTest,TestCreateDirTwice)455 TEST_P(ModularFileSystemTest, TestCreateDirTwice) {
456   const std::string dirpath = GetURIForPath("a_dir");
457   Status status = env_->CreateDir(dirpath);
458   if (!status.ok()) GTEST_SKIP() << "CreateDir() not supported: " << status;
459 
460   status = env_->CreateDir(dirpath);
461   EXPECT_PRED2(UnimplementedOrReturnsCode, status, Code::ALREADY_EXISTS);
462 }
463 
TEST_P(ModularFileSystemTest,TestCreateDirPathIsInvalid)464 TEST_P(ModularFileSystemTest, TestCreateDirPathIsInvalid) {
465   const std::string filepath = GetURIForPath("a_file");
466   std::unique_ptr<WritableFile> file;
467   Status status = env_->NewWritableFile(filepath, &file);
468   if (!status.ok())
469     GTEST_SKIP() << "NewWritableFile() not supported: " << status;
470 
471   const std::string new_path = GetURIForPath("a_file/a_dir");
472   status = env_->CreateDir(new_path);
473   EXPECT_PRED2(UnimplementedOrReturnsCode, status, Code::FAILED_PRECONDITION);
474 }
475 
TEST_P(ModularFileSystemTest,TestRecursivelyCreateDir)476 TEST_P(ModularFileSystemTest, TestRecursivelyCreateDir) {
477   const std::string dirpath = GetURIForPath("a/path/to/a/dir");
478   Status status = env_->RecursivelyCreateDir(dirpath);
479   EXPECT_PRED2(UnimplementedOrReturnsCode, status, Code::OK);
480 }
481 
TEST_P(ModularFileSystemTest,TestRecursivelyCreateDirInATree)482 TEST_P(ModularFileSystemTest, TestRecursivelyCreateDirInATree) {
483   const std::string dirpath = GetURIForPath("a/path/to/a/dir");
484   Status status = env_->RecursivelyCreateDir(dirpath);
485   if (!status.ok())
486     GTEST_SKIP() << "RecursivelyCreateDir() not supported: " << status;
487 
488   const std::string new_dirpath = GetURIForPath("a/path/to/a/another/dir");
489   status = env_->RecursivelyCreateDir(new_dirpath);
490   EXPECT_PRED2(UnimplementedOrReturnsCode, status, Code::OK);
491 }
492 
TEST_P(ModularFileSystemTest,TestRecursivelyCreateDirWhichIsFile)493 TEST_P(ModularFileSystemTest, TestRecursivelyCreateDirWhichIsFile) {
494   const std::string filepath = GetURIForPath("a_file");
495   std::unique_ptr<WritableFile> new_file;
496   Status status = env_->NewWritableFile(filepath, &new_file);
497   if (!status.ok())
498     GTEST_SKIP() << "NewWritableFile() not supported: " << status;
499 
500   status = env_->RecursivelyCreateDir(filepath);
501   EXPECT_PRED2(UnimplementedOrReturnsCode, status, Code::FAILED_PRECONDITION);
502 }
503 
TEST_P(ModularFileSystemTest,TestRecursivelyCreateDirTwice)504 TEST_P(ModularFileSystemTest, TestRecursivelyCreateDirTwice) {
505   const std::string dirpath = GetURIForPath("a/path/to/a/dir");
506   Status status = env_->RecursivelyCreateDir(dirpath);
507   if (!status.ok())
508     GTEST_SKIP() << "RecursivelyCreateDir() not supported: " << status;
509 
510   status = env_->RecursivelyCreateDir(dirpath);
511   EXPECT_PRED2(UnimplementedOrReturnsCode, status, Code::OK);
512 }
513 
TEST_P(ModularFileSystemTest,TestRecursivelyCreateDirPathIsInvalid)514 TEST_P(ModularFileSystemTest, TestRecursivelyCreateDirPathIsInvalid) {
515   const std::string filepath = GetURIForPath("a_file");
516   std::unique_ptr<WritableFile> file;
517   Status status = env_->NewWritableFile(filepath, &file);
518   if (!status.ok())
519     GTEST_SKIP() << "NewWritableFile() not supported: " << status;
520 
521   const std::string new_path = GetURIForPath("a_file/a_dir");
522   status = env_->RecursivelyCreateDir(new_path);
523   EXPECT_PRED2(UnimplementedOrReturnsCode, status, Code::FAILED_PRECONDITION);
524 }
525 
TEST_P(ModularFileSystemTest,TestRecursivelyCreateDirFromNestedDir)526 TEST_P(ModularFileSystemTest, TestRecursivelyCreateDirFromNestedDir) {
527   const std::string parent_path = GetURIForPath("some/path");
528   Status status = env_->RecursivelyCreateDir(parent_path);
529   if (!status.ok())
530     GTEST_SKIP() << "RecursivelyCreateDir() not supported: " << status;
531 
532   const std::string new_dirpath = GetURIForPath("some/path/that/is/extended");
533   status = env_->RecursivelyCreateDir(new_dirpath);
534   EXPECT_PRED2(UnimplementedOrReturnsCode, status, Code::OK);
535 }
536 
TEST_P(ModularFileSystemTest,TestRecursivelyCreateDirFromNestedFile)537 TEST_P(ModularFileSystemTest, TestRecursivelyCreateDirFromNestedFile) {
538   const std::string parent_path = GetURIForPath("some/path");
539   Status status = env_->RecursivelyCreateDir(parent_path);
540   if (!status.ok())
541     GTEST_SKIP() << "RecursivelyCreateDir() not supported: " << status;
542 
543   const std::string filepath = GetURIForPath("some/path/to_a_file");
544   std::unique_ptr<WritableFile> file;
545   status = env_->NewWritableFile(filepath, &file);
546   if (!status.ok())
547     GTEST_SKIP() << "NewWritableFile() not supported: " << status;
548 
549   const std::string new_dirpath = GetURIForPath("some/path/to_a_file/error");
550   status = env_->RecursivelyCreateDir(new_dirpath);
551   EXPECT_PRED2(UnimplementedOrReturnsCode, status, Code::FAILED_PRECONDITION);
552 }
553 
TEST_P(ModularFileSystemTest,TestDeleteFile)554 TEST_P(ModularFileSystemTest, TestDeleteFile) {
555   const std::string filepath = GetURIForPath("a_file");
556   std::unique_ptr<WritableFile> new_file;
557   Status status = env_->NewWritableFile(filepath, &new_file);
558   if (!status.ok())
559     GTEST_SKIP() << "NewWritableFile() not supported: " << status;
560 
561   status = env_->DeleteFile(filepath);
562   EXPECT_PRED2(UnimplementedOrReturnsCode, status, Code::OK);
563 }
564 
TEST_P(ModularFileSystemTest,TestDeleteFileFromDirectory)565 TEST_P(ModularFileSystemTest, TestDeleteFileFromDirectory) {
566   const std::string dirpath = GetURIForPath("a_dir");
567   Status status = env_->CreateDir(dirpath);
568   if (!status.ok()) GTEST_SKIP() << "CreateDir() not supported: " << status;
569 
570   const std::string filepath = GetURIForPath("a_dir/a_file");
571   std::unique_ptr<WritableFile> new_file;
572   status = env_->NewWritableFile(filepath, &new_file);
573   if (!status.ok())
574     GTEST_SKIP() << "NewWritableFile() not supported: " << status;
575 
576   status = env_->DeleteFile(filepath);
577   EXPECT_PRED2(UnimplementedOrReturnsCode, status, Code::OK);
578 }
579 
TEST_P(ModularFileSystemTest,TestDeleteFileDoesNotExist)580 TEST_P(ModularFileSystemTest, TestDeleteFileDoesNotExist) {
581   const std::string filepath = GetURIForPath("a_file");
582   Status status = env_->DeleteFile(filepath);
583   EXPECT_PRED2(UnimplementedOrReturnsCode, status, Code::NOT_FOUND);
584 }
585 
TEST_P(ModularFileSystemTest,TestDeleteFileWhichIsDirectory)586 TEST_P(ModularFileSystemTest, TestDeleteFileWhichIsDirectory) {
587   const std::string dirpath = GetURIForPath("a_dir");
588   Status status = env_->CreateDir(dirpath);
589   if (!status.ok()) GTEST_SKIP() << "CreateDir() not supported: " << status;
590 
591   status = env_->DeleteFile(dirpath);
592   EXPECT_PRED2(UnimplementedOrReturnsCode, status, Code::FAILED_PRECONDITION);
593 }
594 
TEST_P(ModularFileSystemTest,TestDeleteFilePathIsInvalid)595 TEST_P(ModularFileSystemTest, TestDeleteFilePathIsInvalid) {
596   const std::string filepath = GetURIForPath("a_file");
597   std::unique_ptr<WritableFile> file;
598   Status status = env_->NewWritableFile(filepath, &file);
599   if (!status.ok())
600     GTEST_SKIP() << "NewWritableFile() not supported: " << status;
601 
602   const std::string new_path = GetURIForPath("a_file/a_new_file");
603   status = env_->DeleteFile(new_path);
604   EXPECT_PRED2(UnimplementedOrReturnsCode, status, Code::FAILED_PRECONDITION);
605 }
606 
TEST_P(ModularFileSystemTest,TestDeleteDirectory)607 TEST_P(ModularFileSystemTest, TestDeleteDirectory) {
608   const std::string dirpath = GetURIForPath("a_dir");
609   Status status = env_->CreateDir(dirpath);
610   if (!status.ok()) GTEST_SKIP() << "CreateDir() not supported: " << status;
611 
612   status = env_->DeleteDir(dirpath);
613   EXPECT_PRED2(UnimplementedOrReturnsCode, status, Code::OK);
614 }
615 
TEST_P(ModularFileSystemTest,TestDeleteDirectoryFromDirectory)616 TEST_P(ModularFileSystemTest, TestDeleteDirectoryFromDirectory) {
617   const std::string dirpath = GetURIForPath("a_dir");
618   Status status = env_->CreateDir(dirpath);
619   if (!status.ok()) GTEST_SKIP() << "CreateDir() not supported: " << status;
620 
621   const std::string target_path = GetURIForPath("a_dir/another_dir");
622   EXPECT_EQ(env_->CreateDir(target_path).code(), Code::OK);
623 
624   status = env_->DeleteDir(target_path);
625   EXPECT_PRED2(UnimplementedOrReturnsCode, status, Code::OK);
626 }
627 
TEST_P(ModularFileSystemTest,TestDeleteDirectoryDoesNotExist)628 TEST_P(ModularFileSystemTest, TestDeleteDirectoryDoesNotExist) {
629   const std::string dirpath = GetURIForPath("a_dir");
630   Status status = env_->DeleteDir(dirpath);
631   EXPECT_PRED2(UnimplementedOrReturnsCode, status, Code::NOT_FOUND);
632 }
633 
TEST_P(ModularFileSystemTest,TestDeleteDirectoryNotEmpty)634 TEST_P(ModularFileSystemTest, TestDeleteDirectoryNotEmpty) {
635   const std::string dirpath = GetURIForPath("a_dir");
636   Status status = env_->CreateDir(dirpath);
637   if (!status.ok()) GTEST_SKIP() << "CreateDir() not supported: " << status;
638 
639   const std::string filepath = GetURIForPath("a_dir/a_file");
640   std::unique_ptr<WritableFile> new_file;
641   status = env_->NewWritableFile(filepath, &new_file);
642   if (!status.ok())
643     GTEST_SKIP() << "NewWritableFile() not supported: " << status;
644 
645   status = env_->DeleteDir(dirpath);
646   EXPECT_PRED2(UnimplementedOrReturnsCode, status, Code::FAILED_PRECONDITION);
647 }
648 
TEST_P(ModularFileSystemTest,TestDeleteDirectoryWhichIsFile)649 TEST_P(ModularFileSystemTest, TestDeleteDirectoryWhichIsFile) {
650   const std::string filepath = GetURIForPath("a_file");
651   std::unique_ptr<WritableFile> new_file;
652   Status status = env_->NewWritableFile(filepath, &new_file);
653   if (!status.ok())
654     GTEST_SKIP() << "NewWritableFile() not supported: " << status;
655 
656   status = env_->DeleteDir(filepath);
657   EXPECT_PRED2(UnimplementedOrReturnsCode, status, Code::FAILED_PRECONDITION);
658 }
659 
TEST_P(ModularFileSystemTest,TestDeleteDirectoryPathIsInvalid)660 TEST_P(ModularFileSystemTest, TestDeleteDirectoryPathIsInvalid) {
661   const std::string filepath = GetURIForPath("a_file");
662   std::unique_ptr<WritableFile> file;
663   Status status = env_->NewWritableFile(filepath, &file);
664   if (!status.ok())
665     GTEST_SKIP() << "NewWritableFile() not supported: " << status;
666 
667   const std::string new_path = GetURIForPath("a_file/a_dir");
668   status = env_->DeleteDir(new_path);
669   EXPECT_PRED2(UnimplementedOrReturnsCode, status, Code::FAILED_PRECONDITION);
670 }
671 
TEST_P(ModularFileSystemTest,TestDeleteRecursivelyEmpty)672 TEST_P(ModularFileSystemTest, TestDeleteRecursivelyEmpty) {
673   const std::string dirpath = GetURIForPath("a_dir");
674   Status status = env_->CreateDir(dirpath);
675   if (!status.ok()) GTEST_SKIP() << "CreateDir() not supported: " << status;
676 
677   int64 undeleted_files = 0;
678   int64 undeleted_dirs = 0;
679   status = env_->DeleteRecursively(dirpath, &undeleted_files, &undeleted_dirs);
680   EXPECT_PRED2(UnimplementedOrReturnsCode, status, Code::OK);
681   EXPECT_EQ(undeleted_files, 0);
682   EXPECT_EQ(undeleted_dirs, 0);
683 }
684 
TEST_P(ModularFileSystemTest,TestDeleteRecursivelyNotEmpty)685 TEST_P(ModularFileSystemTest, TestDeleteRecursivelyNotEmpty) {
686   const std::string dirpath = GetURIForPath("a_dir");
687   Status status = env_->CreateDir(dirpath);
688   if (!status.ok()) GTEST_SKIP() << "CreateDir() not supported: " << status;
689 
690   const std::string some_path = GetURIForPath("a_dir/another_dir");
691   status = env_->CreateDir(some_path);
692   if (!status.ok()) GTEST_SKIP() << "CreateDir() not supported: " << status;
693 
694   const std::string another_path = GetURIForPath("a_dir/yet_another_dir");
695   status = env_->CreateDir(another_path);
696   if (!status.ok()) GTEST_SKIP() << "CreateDir() not supported: " << status;
697 
698   const std::string filepath = GetURIForPath("a_dir/a_file");
699   std::unique_ptr<WritableFile> new_file;
700   status = env_->NewWritableFile(filepath, &new_file);
701   if (!status.ok())
702     GTEST_SKIP() << "NewWritableFile() not supported: " << status;
703 
704   int64 undeleted_files = 0;
705   int64 undeleted_dirs = 0;
706   status = env_->DeleteRecursively(dirpath, &undeleted_files, &undeleted_dirs);
707   EXPECT_PRED2(UnimplementedOrReturnsCode, status, Code::OK);
708   EXPECT_EQ(undeleted_files, 0);
709   EXPECT_EQ(undeleted_dirs, 0);
710 }
711 
TEST_P(ModularFileSystemTest,TestDeleteRecursivelyDoesNotExist)712 TEST_P(ModularFileSystemTest, TestDeleteRecursivelyDoesNotExist) {
713   const std::string dirpath = GetURIForPath("a_dir");
714 
715   int64 undeleted_files = 0;
716   int64 undeleted_dirs = 0;
717   Status status =
718       env_->DeleteRecursively(dirpath, &undeleted_files, &undeleted_dirs);
719   EXPECT_PRED2(UnimplementedOrReturnsCode, status, Code::NOT_FOUND);
720   EXPECT_EQ(undeleted_files, 0);
721   EXPECT_EQ(undeleted_dirs, 1);
722 }
723 
TEST_P(ModularFileSystemTest,TestDeleteRecursivelyAFile)724 TEST_P(ModularFileSystemTest, TestDeleteRecursivelyAFile) {
725   const std::string filepath = GetURIForPath("a_file");
726   std::unique_ptr<WritableFile> new_file;
727   Status status = env_->NewWritableFile(filepath, &new_file);
728   if (!status.ok())
729     GTEST_SKIP() << "NewWritableFile() not supported: " << status;
730 
731   int64 undeleted_files = 0;
732   int64 undeleted_dirs = 0;
733   status = env_->DeleteRecursively(filepath, &undeleted_files, &undeleted_dirs);
734   EXPECT_EQ(undeleted_files, 0);
735   EXPECT_EQ(undeleted_dirs, 0);
736 }
737 
TEST_P(ModularFileSystemTest,TestDeleteRecursivelyPathIsInvalid)738 TEST_P(ModularFileSystemTest, TestDeleteRecursivelyPathIsInvalid) {
739   const std::string filepath = GetURIForPath("a_file");
740   std::unique_ptr<WritableFile> file;
741   Status status = env_->NewWritableFile(filepath, &file);
742   if (!status.ok())
743     GTEST_SKIP() << "NewWritableFile() not supported: " << status;
744 
745   const std::string new_path = GetURIForPath("a_file/a_dir");
746   int64 undeleted_files, undeleted_dirs;
747   status = env_->DeleteRecursively(new_path, &undeleted_files, &undeleted_dirs);
748   EXPECT_PRED2(UnimplementedOrReturnsCode, status, Code::FAILED_PRECONDITION);
749 }
750 
TEST_P(ModularFileSystemTest,TestDeleteRecursivelyANestedDir)751 TEST_P(ModularFileSystemTest, TestDeleteRecursivelyANestedDir) {
752   const std::string parent_path = GetURIForPath("parent/path");
753   Status status = env_->RecursivelyCreateDir(parent_path);
754   if (!status.ok())
755     GTEST_SKIP() << "RecursivelyCreateDir() not supported: " << status;
756 
757   const std::string new_dirpath = GetURIForPath("parent/path/that/is/extended");
758   status = env_->RecursivelyCreateDir(new_dirpath);
759   if (!status.ok())
760     GTEST_SKIP() << "RecursivelyCreateDir() not supported: " << status;
761 
762   const std::string path = GetURIForPath("parent/path/that");
763   int64 undeleted_files = 0;
764   int64 undeleted_dirs = 0;
765   status = env_->DeleteRecursively(path, &undeleted_files, &undeleted_dirs);
766   EXPECT_PRED2(UnimplementedOrReturnsCode, status, Code::OK);
767   EXPECT_EQ(undeleted_files, 0);
768   EXPECT_EQ(undeleted_dirs, 0);
769 
770   // Parent directory must still exist
771   status = env_->FileExists(parent_path);
772   EXPECT_PRED2(UnimplementedOrReturnsCode, status, Code::OK);
773 }
774 
TEST_P(ModularFileSystemTest,TestDeleteRecursivelyANestedFile)775 TEST_P(ModularFileSystemTest, TestDeleteRecursivelyANestedFile) {
776   const std::string parent_path = GetURIForPath("some/path");
777   Status status = env_->RecursivelyCreateDir(parent_path);
778   if (!status.ok())
779     GTEST_SKIP() << "RecursivelyCreateDir() not supported: " << status;
780 
781   const std::string filepath = GetURIForPath("some/path/to_a_file");
782   std::unique_ptr<WritableFile> file;
783   status = env_->NewWritableFile(filepath, &file);
784   if (!status.ok())
785     GTEST_SKIP() << "NewWritableFile() not supported: " << status;
786 
787   int64 undeleted_files = 0;
788   int64 undeleted_dirs = 0;
789   status = env_->DeleteRecursively(filepath, &undeleted_files, &undeleted_dirs);
790   EXPECT_PRED2(UnimplementedOrReturnsCode, status, Code::OK);
791   EXPECT_EQ(undeleted_files, 0);
792   EXPECT_EQ(undeleted_dirs, 0);
793 
794   // Parent directory must still exist
795   status = env_->FileExists(parent_path);
796   EXPECT_PRED2(UnimplementedOrReturnsCode, status, Code::OK);
797 }
798 
TEST_P(ModularFileSystemTest,TestRenameFile)799 TEST_P(ModularFileSystemTest, TestRenameFile) {
800   const std::string filepath = GetURIForPath("a_file");
801   std::unique_ptr<WritableFile> new_file;
802   Status status = env_->NewWritableFile(filepath, &new_file);
803   if (!status.ok())
804     GTEST_SKIP() << "NewWritableFile() not supported: " << status;
805 
806   const std::string new_filepath = GetURIForPath("a_new_file");
807   status = env_->RenameFile(filepath, new_filepath);
808   EXPECT_PRED2(UnimplementedOrReturnsCode, status, Code::OK);
809   if (!status.ok()) GTEST_SKIP() << "RenameFile() not supported: " << status;
810 
811   status = env_->FileExists(filepath);
812   EXPECT_PRED2(UnimplementedOrReturnsCode, status, Code::NOT_FOUND);
813   status = env_->FileExists(new_filepath);
814   EXPECT_PRED2(UnimplementedOrReturnsCode, status, Code::OK);
815 }
816 
TEST_P(ModularFileSystemTest,TestRenameFileOverwrite)817 TEST_P(ModularFileSystemTest, TestRenameFileOverwrite) {
818   const std::string filepath = GetURIForPath("a_file");
819   std::unique_ptr<WritableFile> file;
820   Status status = env_->NewWritableFile(filepath, &file);
821   if (!status.ok())
822     GTEST_SKIP() << "NewWritableFile() not supported: " << status;
823 
824   const std::string new_filepath = GetURIForPath("a_new_file");
825   std::unique_ptr<WritableFile> new_file;
826   status = env_->NewWritableFile(filepath, &new_file);
827   if (!status.ok())
828     GTEST_SKIP() << "NewWritableFile() not supported: " << status;
829 
830   status = env_->RenameFile(filepath, new_filepath);
831   EXPECT_PRED2(UnimplementedOrReturnsCode, status, Code::OK);
832   if (!status.ok()) GTEST_SKIP() << "RenameFile() not supported: " << status;
833 
834   status = env_->FileExists(filepath);
835   EXPECT_PRED2(UnimplementedOrReturnsCode, status, Code::NOT_FOUND);
836   status = env_->FileExists(new_filepath);
837   EXPECT_PRED2(UnimplementedOrReturnsCode, status, Code::OK);
838 }
839 
TEST_P(ModularFileSystemTest,TestRenameFileSourceNotFound)840 TEST_P(ModularFileSystemTest, TestRenameFileSourceNotFound) {
841   const std::string filepath = GetURIForPath("a_file");
842   const std::string new_filepath = GetURIForPath("a_new_file");
843   Status status = env_->RenameFile(filepath, new_filepath);
844   EXPECT_PRED2(UnimplementedOrReturnsCode, status, Code::NOT_FOUND);
845 }
846 
TEST_P(ModularFileSystemTest,TestRenameFileDestinationParentNotFound)847 TEST_P(ModularFileSystemTest, TestRenameFileDestinationParentNotFound) {
848   const std::string filepath = GetURIForPath("a_file");
849   std::unique_ptr<WritableFile> file;
850   Status status = env_->NewWritableFile(filepath, &file);
851   if (!status.ok())
852     GTEST_SKIP() << "NewWritableFile() not supported: " << status;
853 
854   const std::string new_filepath = GetURIForPath("a_dir/a_file");
855   status = env_->RenameFile(filepath, new_filepath);
856   EXPECT_PRED2(UnimplementedOrReturnsCode, status, Code::NOT_FOUND);
857 }
858 
TEST_P(ModularFileSystemTest,TestRenameFileSourceIsDirectory)859 TEST_P(ModularFileSystemTest, TestRenameFileSourceIsDirectory) {
860   const std::string dirpath = GetURIForPath("a_dir");
861   Status status = env_->CreateDir(dirpath);
862   if (!status.ok()) GTEST_SKIP() << "CreateDir() not supported: " << status;
863 
864   const std::string new_filepath = GetURIForPath("a_new_file");
865   status = env_->RenameFile(dirpath, new_filepath);
866   EXPECT_PRED2(UnimplementedOrReturnsCode, status, Code::FAILED_PRECONDITION);
867 }
868 
TEST_P(ModularFileSystemTest,TestRenameFileTargetIsDirectory)869 TEST_P(ModularFileSystemTest, TestRenameFileTargetIsDirectory) {
870   const std::string filepath = GetURIForPath("a_file");
871   std::unique_ptr<WritableFile> new_file;
872   Status status = env_->NewWritableFile(filepath, &new_file);
873   if (!status.ok())
874     GTEST_SKIP() << "NewWritableFile() not supported: " << status;
875 
876   const std::string dirpath = GetURIForPath("a_dir");
877   status = env_->CreateDir(dirpath);
878   if (!status.ok()) GTEST_SKIP() << "CreateDir() not supported: " << status;
879 
880   status = env_->RenameFile(filepath, dirpath);
881   EXPECT_PRED2(UnimplementedOrReturnsCode, status, Code::FAILED_PRECONDITION);
882 }
883 
TEST_P(ModularFileSystemTest,TestRenameFileSourcePathIsInvalid)884 TEST_P(ModularFileSystemTest, TestRenameFileSourcePathIsInvalid) {
885   const std::string filepath = GetURIForPath("a_file");
886   std::unique_ptr<WritableFile> file;
887   Status status = env_->NewWritableFile(filepath, &file);
888   if (!status.ok())
889     GTEST_SKIP() << "NewWritableFile() not supported: " << status;
890 
891   const std::string old_filepath = GetURIForPath("a_file/x");
892   const std::string new_filepath = GetURIForPath("a_new_file");
893   status = env_->RenameFile(old_filepath, new_filepath);
894   EXPECT_PRED2(UnimplementedOrReturnsCode, status, Code::FAILED_PRECONDITION);
895 }
896 
TEST_P(ModularFileSystemTest,TestRenameFileTargetPathIsInvalid)897 TEST_P(ModularFileSystemTest, TestRenameFileTargetPathIsInvalid) {
898   const std::string old_filepath = GetURIForPath("a_file");
899   std::unique_ptr<WritableFile> old_file;
900   Status status = env_->NewWritableFile(old_filepath, &old_file);
901   if (!status.ok())
902     GTEST_SKIP() << "NewWritableFile() not supported: " << status;
903 
904   const std::string filepath = GetURIForPath("a_file");
905   std::unique_ptr<WritableFile> file;
906   status = env_->NewWritableFile(filepath, &file);
907   if (!status.ok())
908     GTEST_SKIP() << "NewWritableFile() not supported: " << status;
909 
910   const std::string new_filepath = GetURIForPath("a_file/a_new_file");
911   status = env_->RenameFile(old_filepath, new_filepath);
912   EXPECT_PRED2(UnimplementedOrReturnsCode, status, Code::FAILED_PRECONDITION);
913 }
914 
TEST_P(ModularFileSystemTest,TestRenameFileCompareContents)915 TEST_P(ModularFileSystemTest, TestRenameFileCompareContents) {
916   const std::string filepath = GetURIForPath("a_file");
917   std::unique_ptr<WritableFile> file;
918   Status status = env_->NewWritableFile(filepath, &file);
919   if (!status.ok())
920     GTEST_SKIP() << "NewWritableFile() not supported: " << status;
921 
922   const std::string test_data("asdf");
923   status = file->Append(test_data);
924   if (!status.ok()) GTEST_SKIP() << "Append() not supported: " << status;
925   status = file->Flush();
926   if (!status.ok()) GTEST_SKIP() << "Flush() not supported: " << status;
927   status = file->Close();
928   if (!status.ok()) GTEST_SKIP() << "Close() not supported: " << status;
929 
930   const std::string new_filepath = GetURIForPath("a_new_file");
931   status = env_->RenameFile(filepath, new_filepath);
932   EXPECT_PRED2(UnimplementedOrReturnsCode, status, Code::OK);
933   if (!status.ok()) GTEST_SKIP() << "RenameFile() not supported: " << status;
934 
935   uint64 size;
936   status = env_->GetFileSize(new_filepath, &size);
937   EXPECT_PRED2(UnimplementedOrReturnsCode, status, Code::OK);
938   if (!status.ok()) GTEST_SKIP() << "GetFileSize() not supported: " << status;
939   EXPECT_EQ(size, test_data.size());
940 }
941 
TEST_P(ModularFileSystemTest,TestCopyFile)942 TEST_P(ModularFileSystemTest, TestCopyFile) {
943   const std::string filepath = GetURIForPath("a_file");
944   std::unique_ptr<WritableFile> new_file;
945   Status status = env_->NewWritableFile(filepath, &new_file);
946   if (!status.ok())
947     GTEST_SKIP() << "NewWritableFile() not supported: " << status;
948 
949   const std::string new_filepath = GetURIForPath("a_new_file");
950   status = env_->CopyFile(filepath, new_filepath);
951   EXPECT_PRED2(UnimplementedOrReturnsCode, status, Code::OK);
952   if (!status.ok()) GTEST_SKIP() << "CopyFile() not supported: " << status;
953 
954   status = env_->FileExists(filepath);
955   EXPECT_PRED2(UnimplementedOrReturnsCode, status, Code::OK);
956   status = env_->FileExists(new_filepath);
957   EXPECT_PRED2(UnimplementedOrReturnsCode, status, Code::OK);
958 }
959 
TEST_P(ModularFileSystemTest,TestCopyFileOverwrite)960 TEST_P(ModularFileSystemTest, TestCopyFileOverwrite) {
961   const std::string filepath = GetURIForPath("a_file");
962   std::unique_ptr<WritableFile> file;
963   Status status = env_->NewWritableFile(filepath, &file);
964   if (!status.ok())
965     GTEST_SKIP() << "NewWritableFile() not supported: " << status;
966 
967   const std::string new_filepath = GetURIForPath("a_new_file");
968   std::unique_ptr<WritableFile> new_file;
969   status = env_->NewWritableFile(filepath, &new_file);
970   if (!status.ok())
971     GTEST_SKIP() << "NewWritableFile() not supported: " << status;
972 
973   status = env_->CopyFile(filepath, new_filepath);
974   EXPECT_PRED2(UnimplementedOrReturnsCode, status, Code::OK);
975   if (!status.ok()) GTEST_SKIP() << "CopyFile() not supported: " << status;
976 
977   status = env_->FileExists(filepath);
978   EXPECT_PRED2(UnimplementedOrReturnsCode, status, Code::OK);
979   status = env_->FileExists(new_filepath);
980   EXPECT_PRED2(UnimplementedOrReturnsCode, status, Code::OK);
981 }
982 
TEST_P(ModularFileSystemTest,TestCopyFileSourceNotFound)983 TEST_P(ModularFileSystemTest, TestCopyFileSourceNotFound) {
984   const std::string filepath = GetURIForPath("a_file");
985   const std::string new_filepath = GetURIForPath("a_new_file");
986   Status status = env_->CopyFile(filepath, new_filepath);
987   EXPECT_PRED2(UnimplementedOrReturnsCode, status, Code::NOT_FOUND);
988 }
989 
TEST_P(ModularFileSystemTest,TestCopyFileSourceIsDirectory)990 TEST_P(ModularFileSystemTest, TestCopyFileSourceIsDirectory) {
991   const std::string dirpath = GetURIForPath("a_dir");
992   Status status = env_->CreateDir(dirpath);
993   if (!status.ok()) GTEST_SKIP() << "CreateDir() not supported: " << status;
994 
995   const std::string new_filepath = GetURIForPath("a_new_file");
996   status = env_->CopyFile(dirpath, new_filepath);
997   EXPECT_PRED2(UnimplementedOrReturnsCode, status, Code::FAILED_PRECONDITION);
998 }
999 
TEST_P(ModularFileSystemTest,TestCopyFileTargetIsDirectory)1000 TEST_P(ModularFileSystemTest, TestCopyFileTargetIsDirectory) {
1001   const std::string filepath = GetURIForPath("a_file");
1002   std::unique_ptr<WritableFile> new_file;
1003   Status status = env_->NewWritableFile(filepath, &new_file);
1004   if (!status.ok())
1005     GTEST_SKIP() << "NewWritableFile() not supported: " << status;
1006 
1007   const std::string dirpath = GetURIForPath("a_dir");
1008   status = env_->CreateDir(dirpath);
1009   if (!status.ok()) GTEST_SKIP() << "CreateDir() not supported: " << status;
1010 
1011   status = env_->CopyFile(filepath, dirpath);
1012   EXPECT_PRED2(UnimplementedOrReturnsCode, status, Code::FAILED_PRECONDITION);
1013 }
1014 
TEST_P(ModularFileSystemTest,TestCopyFileSourcePathIsInvalid)1015 TEST_P(ModularFileSystemTest, TestCopyFileSourcePathIsInvalid) {
1016   const std::string filepath = GetURIForPath("a_file");
1017   std::unique_ptr<WritableFile> file;
1018   Status status = env_->NewWritableFile(filepath, &file);
1019   if (!status.ok())
1020     GTEST_SKIP() << "NewWritableFile() not supported: " << status;
1021 
1022   const std::string old_filepath = GetURIForPath("a_file/x");
1023   const std::string new_filepath = GetURIForPath("a_new_file");
1024   status = env_->CopyFile(old_filepath, new_filepath);
1025   EXPECT_PRED2(UnimplementedOrReturnsCode, status, Code::FAILED_PRECONDITION);
1026 }
1027 
TEST_P(ModularFileSystemTest,TestCopyFileTargetPathIsInvalid)1028 TEST_P(ModularFileSystemTest, TestCopyFileTargetPathIsInvalid) {
1029   const std::string old_filepath = GetURIForPath("a_file");
1030   std::unique_ptr<WritableFile> old_file;
1031   Status status = env_->NewWritableFile(old_filepath, &old_file);
1032   if (!status.ok())
1033     GTEST_SKIP() << "NewWritableFile() not supported: " << status;
1034 
1035   const std::string filepath = GetURIForPath("a_file");
1036   std::unique_ptr<WritableFile> file;
1037   status = env_->NewWritableFile(filepath, &file);
1038   if (!status.ok())
1039     GTEST_SKIP() << "NewWritableFile() not supported: " << status;
1040 
1041   const std::string new_filepath = GetURIForPath("a_file/a_new_file");
1042   status = env_->CopyFile(old_filepath, new_filepath);
1043   EXPECT_PRED2(UnimplementedOrReturnsCode, status, Code::FAILED_PRECONDITION);
1044 }
1045 
TEST_P(ModularFileSystemTest,TestCopyFileCompareContents)1046 TEST_P(ModularFileSystemTest, TestCopyFileCompareContents) {
1047   const std::string filepath = GetURIForPath("a_file");
1048   std::unique_ptr<WritableFile> file;
1049   Status status = env_->NewWritableFile(filepath, &file);
1050   if (!status.ok())
1051     GTEST_SKIP() << "NewWritableFile() not supported: " << status;
1052 
1053   const std::string test_data("asdf");
1054   status = file->Append(test_data);
1055   if (!status.ok()) GTEST_SKIP() << "Append() not supported: " << status;
1056   status = file->Flush();
1057   if (!status.ok()) GTEST_SKIP() << "Flush() not supported: " << status;
1058   status = file->Close();
1059   if (!status.ok()) GTEST_SKIP() << "Close() not supported: " << status;
1060 
1061   const std::string new_filepath = GetURIForPath("a_new_file");
1062   status = env_->CopyFile(filepath, new_filepath);
1063   EXPECT_PRED2(UnimplementedOrReturnsCode, status, Code::OK);
1064   if (!status.ok()) GTEST_SKIP() << "RenameFile() not supported: " << status;
1065 
1066   uint64 size;
1067   status = env_->GetFileSize(filepath, &size);
1068   EXPECT_PRED2(UnimplementedOrReturnsCode, status, Code::OK);
1069   if (!status.ok()) GTEST_SKIP() << "GetFileSize() not supported: " << status;
1070   EXPECT_EQ(size, test_data.size());
1071 
1072   status = env_->GetFileSize(new_filepath, &size);
1073   EXPECT_PRED2(UnimplementedOrReturnsCode, status, Code::OK);
1074   if (!status.ok()) GTEST_SKIP() << "GetFileSize() not supported: " << status;
1075   EXPECT_EQ(size, test_data.size());
1076 }
1077 
TEST_P(ModularFileSystemTest,TestFileExists)1078 TEST_P(ModularFileSystemTest, TestFileExists) {
1079   const std::string filepath = GetURIForPath("a_file");
1080   std::unique_ptr<WritableFile> file;
1081   Status status = env_->NewWritableFile(filepath, &file);
1082   if (!status.ok())
1083     GTEST_SKIP() << "NewWritableFile() not supported: " << status;
1084 
1085   status = env_->FileExists(filepath);
1086   EXPECT_PRED2(UnimplementedOrReturnsCode, status, Code::OK);
1087 }
1088 
TEST_P(ModularFileSystemTest,TestFileExistsButIsDirectory)1089 TEST_P(ModularFileSystemTest, TestFileExistsButIsDirectory) {
1090   const std::string filepath = GetURIForPath("a_file");
1091   Status status = env_->CreateDir(filepath);
1092   if (!status.ok()) GTEST_SKIP() << "CreateDir() not supported: " << status;
1093 
1094   status = env_->FileExists(filepath);
1095   EXPECT_PRED2(UnimplementedOrReturnsCode, status, Code::OK);
1096 }
1097 
TEST_P(ModularFileSystemTest,TestFileExistsNotFound)1098 TEST_P(ModularFileSystemTest, TestFileExistsNotFound) {
1099   const std::string filepath = GetURIForPath("a_file");
1100   Status status = env_->FileExists(filepath);
1101   EXPECT_PRED2(UnimplementedOrReturnsCode, status, Code::NOT_FOUND);
1102 }
1103 
TEST_P(ModularFileSystemTest,TestFileExistsPathIsInvalid)1104 TEST_P(ModularFileSystemTest, TestFileExistsPathIsInvalid) {
1105   const std::string filepath = GetURIForPath("a_file");
1106   std::unique_ptr<WritableFile> file;
1107   Status status = env_->NewWritableFile(filepath, &file);
1108   if (!status.ok())
1109     GTEST_SKIP() << "NewWritableFile() not supported: " << status;
1110 
1111   const std::string target_path = GetURIForPath("a_file/a_new_file");
1112   status = env_->FileExists(target_path);
1113   EXPECT_PRED2(UnimplementedOrReturnsCode, status, Code::FAILED_PRECONDITION);
1114 }
1115 
TEST_P(ModularFileSystemTest,TestFilesExist)1116 TEST_P(ModularFileSystemTest, TestFilesExist) {
1117   const std::vector<std::string> filenames = {GetURIForPath("a"),
1118                                               GetURIForPath("b")};
1119   for (const auto& filename : filenames) {
1120     std::unique_ptr<WritableFile> file;
1121     Status status = env_->NewWritableFile(filename, &file);
1122     if (!status.ok())
1123       GTEST_SKIP() << "NewWritableFile() not supported: " << status;
1124   }
1125 
1126   EXPECT_TRUE(env_->FilesExist(filenames, /*status=*/nullptr));
1127 
1128   std::vector<Status> statuses;
1129   EXPECT_TRUE(env_->FilesExist(filenames, &statuses));
1130   EXPECT_EQ(statuses.size(), filenames.size());
1131   for (const auto& status : statuses)
1132     EXPECT_PRED2(UnimplementedOrReturnsCode, status, Code::OK);
1133 }
1134 
TEST_P(ModularFileSystemTest,TestFilesExistAllFailureModes)1135 TEST_P(ModularFileSystemTest, TestFilesExistAllFailureModes) {
1136   // if reordering these, make sure to reorder checks at the end
1137   const std::vector<std::string> filenames = {
1138       GetURIForPath("a_dir"),
1139       GetURIForPath("a_file"),
1140       GetURIForPath("a_file/a_new_file"),
1141       GetURIForPath("file_not_found"),
1142   };
1143 
1144   Status status = env_->CreateDir(filenames[0]);
1145   if (!status.ok()) GTEST_SKIP() << "CreateDir() not supported: " << status;
1146 
1147   std::unique_ptr<WritableFile> file;
1148   status = env_->NewWritableFile(filenames[1], &file);
1149   if (!status.ok())
1150     GTEST_SKIP() << "NewWritableFile() not supported: " << status;
1151 
1152   std::vector<Status> statuses;
1153   EXPECT_FALSE(env_->FilesExist(filenames, &statuses));
1154   EXPECT_EQ(statuses.size(), filenames.size());
1155   EXPECT_PRED2(UnimplementedOrReturnsCode, statuses[0], Code::OK);
1156   EXPECT_PRED2(UnimplementedOrReturnsCode, statuses[1], Code::OK);
1157   EXPECT_PRED2(UnimplementedOrReturnsCode, statuses[2],
1158                Code::FAILED_PRECONDITION);
1159   EXPECT_PRED2(UnimplementedOrReturnsCode, statuses[3], Code::NOT_FOUND);
1160 }
1161 
TEST_P(ModularFileSystemTest,TestFilesExistsNoFiles)1162 TEST_P(ModularFileSystemTest, TestFilesExistsNoFiles) {
1163   const std::vector<std::string> filenames = {};
1164   EXPECT_TRUE(env_->FilesExist(filenames, /*status=*/nullptr));
1165 
1166   std::vector<Status> statuses;
1167   EXPECT_TRUE(env_->FilesExist(filenames, &statuses));
1168   EXPECT_TRUE(statuses.empty());
1169 }
1170 
TEST_P(ModularFileSystemTest,TestStatEmptyFile)1171 TEST_P(ModularFileSystemTest, TestStatEmptyFile) {
1172   const std::string filepath = GetURIForPath("a_file");
1173   std::unique_ptr<WritableFile> file;
1174   Status status = env_->NewWritableFile(filepath, &file);
1175   if (!status.ok())
1176     GTEST_SKIP() << "NewWritableFile() not supported: " << status;
1177 
1178   FileStatistics stat;
1179   status = env_->Stat(filepath, &stat);
1180   EXPECT_PRED2(UnimplementedOrReturnsCode, status, Code::OK);
1181   if (!status.ok()) GTEST_SKIP() << "Stat() not supported: " << status;
1182   EXPECT_FALSE(stat.is_directory);
1183   EXPECT_EQ(stat.length, 0);
1184 }
1185 
TEST_P(ModularFileSystemTest,TestStatNonEmptyFile)1186 TEST_P(ModularFileSystemTest, TestStatNonEmptyFile) {
1187   const std::string filepath = GetURIForPath("a_file");
1188   std::unique_ptr<WritableFile> file;
1189   Status status = env_->NewWritableFile(filepath, &file);
1190   if (!status.ok())
1191     GTEST_SKIP() << "NewWritableFile() not supported: " << status;
1192 
1193   const std::string test_data("asdf");
1194   status = file->Append(test_data);
1195   if (!status.ok()) GTEST_SKIP() << "Append() not supported: " << status;
1196   status = file->Flush();
1197   if (!status.ok()) GTEST_SKIP() << "Flush() not supported: " << status;
1198   status = file->Close();
1199   if (!status.ok()) GTEST_SKIP() << "Close() not supported: " << status;
1200 
1201   FileStatistics stat;
1202   status = env_->Stat(filepath, &stat);
1203   EXPECT_PRED2(UnimplementedOrReturnsCode, status, Code::OK);
1204   if (!status.ok()) GTEST_SKIP() << "Stat() not supported: " << status;
1205   EXPECT_FALSE(stat.is_directory);
1206   EXPECT_EQ(stat.length, test_data.size());
1207 }
1208 
TEST_P(ModularFileSystemTest,TestStatDirectory)1209 TEST_P(ModularFileSystemTest, TestStatDirectory) {
1210   const std::string dirpath = GetURIForPath("a_dir");
1211   Status status = env_->CreateDir(dirpath);
1212   if (!status.ok()) GTEST_SKIP() << "CreateDir() not supported: " << status;
1213 
1214   FileStatistics stat;
1215   status = env_->Stat(dirpath, &stat);
1216   EXPECT_PRED2(UnimplementedOrReturnsCode, status, Code::OK);
1217   if (!status.ok()) GTEST_SKIP() << "Stat() not supported: " << status;
1218   EXPECT_TRUE(stat.is_directory);
1219 }
1220 
TEST_P(ModularFileSystemTest,TestStatNotFound)1221 TEST_P(ModularFileSystemTest, TestStatNotFound) {
1222   const std::string dirpath = GetURIForPath("a_dir");
1223   FileStatistics stat;
1224   Status status = env_->Stat(dirpath, &stat);
1225   EXPECT_PRED2(UnimplementedOrReturnsCode, status, Code::NOT_FOUND);
1226 }
1227 
TEST_P(ModularFileSystemTest,TestStatPathIsInvalid)1228 TEST_P(ModularFileSystemTest, TestStatPathIsInvalid) {
1229   const std::string filepath = GetURIForPath("a_file");
1230   std::unique_ptr<WritableFile> file;
1231   Status status = env_->NewWritableFile(filepath, &file);
1232   if (!status.ok())
1233     GTEST_SKIP() << "NewWritableFile() not supported: " << status;
1234 
1235   const std::string target_path = GetURIForPath("a_file/a_new_file");
1236   FileStatistics stat;
1237   status = env_->Stat(target_path, &stat);
1238   EXPECT_PRED2(UnimplementedOrReturnsCode, status, Code::FAILED_PRECONDITION);
1239 }
1240 
TEST_P(ModularFileSystemTest,TestIsDirectory)1241 TEST_P(ModularFileSystemTest, TestIsDirectory) {
1242   const std::string dirpath = GetURIForPath("a_dir");
1243   Status status = env_->CreateDir(dirpath);
1244   if (!status.ok()) GTEST_SKIP() << "CreateDir() not supported: " << status;
1245 
1246   status = env_->IsDirectory(dirpath);
1247   EXPECT_PRED2(UnimplementedOrReturnsCode, status, Code::OK);
1248 }
1249 
TEST_P(ModularFileSystemTest,TestIsDirectoryFile)1250 TEST_P(ModularFileSystemTest, TestIsDirectoryFile) {
1251   const std::string filepath = GetURIForPath("a_file");
1252   std::unique_ptr<WritableFile> file;
1253   Status status = env_->NewWritableFile(filepath, &file);
1254   if (!status.ok())
1255     GTEST_SKIP() << "NewWritableFile() not supported: " << status;
1256 
1257   status = env_->IsDirectory(filepath);
1258   EXPECT_PRED2(UnimplementedOrReturnsCode, status, Code::FAILED_PRECONDITION);
1259 }
1260 
TEST_P(ModularFileSystemTest,TestIsDirectoryNotFound)1261 TEST_P(ModularFileSystemTest, TestIsDirectoryNotFound) {
1262   const std::string dirpath = GetURIForPath("a_dir");
1263   Status status = env_->IsDirectory(dirpath);
1264   EXPECT_PRED2(UnimplementedOrReturnsCode, status, Code::NOT_FOUND);
1265 }
1266 
TEST_P(ModularFileSystemTest,TestIsDirectoryPathIsInvalid)1267 TEST_P(ModularFileSystemTest, TestIsDirectoryPathIsInvalid) {
1268   const std::string filepath = GetURIForPath("a_file");
1269   std::unique_ptr<WritableFile> file;
1270   Status status = env_->NewWritableFile(filepath, &file);
1271   if (!status.ok())
1272     GTEST_SKIP() << "NewWritableFile() not supported: " << status;
1273 
1274   const std::string target_path = GetURIForPath("a_file/a_new_file");
1275   status = env_->IsDirectory(target_path);
1276   EXPECT_PRED2(UnimplementedOrReturnsCode, status, Code::FAILED_PRECONDITION);
1277 }
1278 
TEST_P(ModularFileSystemTest,TestGetFileSizeEmptyFile)1279 TEST_P(ModularFileSystemTest, TestGetFileSizeEmptyFile) {
1280   const std::string filepath = GetURIForPath("a_file");
1281   std::unique_ptr<WritableFile> file;
1282   Status status = env_->NewWritableFile(filepath, &file);
1283   if (!status.ok())
1284     GTEST_SKIP() << "NewWritableFile() not supported: " << status;
1285 
1286   uint64 size;
1287   status = env_->GetFileSize(filepath, &size);
1288   EXPECT_PRED2(UnimplementedOrReturnsCode, status, Code::OK);
1289   if (!status.ok()) GTEST_SKIP() << "GetFileSize() not supported: " << status;
1290   EXPECT_EQ(size, 0);
1291 }
1292 
TEST_P(ModularFileSystemTest,TestGetFileSizeNonEmptyFile)1293 TEST_P(ModularFileSystemTest, TestGetFileSizeNonEmptyFile) {
1294   const std::string filepath = GetURIForPath("a_file");
1295   std::unique_ptr<WritableFile> file;
1296   Status status = env_->NewWritableFile(filepath, &file);
1297   if (!status.ok())
1298     GTEST_SKIP() << "NewWritableFile() not supported: " << status;
1299 
1300   const std::string test_data("asdf");
1301   status = file->Append(test_data);
1302   if (!status.ok()) GTEST_SKIP() << "Append() not supported: " << status;
1303   status = file->Flush();
1304   if (!status.ok()) GTEST_SKIP() << "Flush() not supported: " << status;
1305   status = file->Close();
1306   if (!status.ok()) GTEST_SKIP() << "Close() not supported: " << status;
1307 
1308   uint64 size;
1309   status = env_->GetFileSize(filepath, &size);
1310   EXPECT_PRED2(UnimplementedOrReturnsCode, status, Code::OK);
1311   if (!status.ok()) GTEST_SKIP() << "GetFileSize() not supported: " << status;
1312   EXPECT_EQ(size, test_data.size());
1313 }
1314 
TEST_P(ModularFileSystemTest,TestGetFileSizeDirectory)1315 TEST_P(ModularFileSystemTest, TestGetFileSizeDirectory) {
1316   const std::string dirpath = GetURIForPath("a_dir");
1317   Status status = env_->CreateDir(dirpath);
1318   if (!status.ok()) GTEST_SKIP() << "CreateDir() not supported: " << status;
1319 
1320   uint64 size;
1321   status = env_->GetFileSize(dirpath, &size);
1322   EXPECT_PRED2(UnimplementedOrReturnsCode, status, Code::FAILED_PRECONDITION);
1323 }
1324 
TEST_P(ModularFileSystemTest,TestGetFileSizeNotFound)1325 TEST_P(ModularFileSystemTest, TestGetFileSizeNotFound) {
1326   const std::string filepath = GetURIForPath("a_dir");
1327   uint64 size;
1328   Status status = env_->GetFileSize(filepath, &size);
1329   EXPECT_PRED2(UnimplementedOrReturnsCode, status, Code::NOT_FOUND);
1330 }
1331 
TEST_P(ModularFileSystemTest,TestGetFileSizePathIsInvalid)1332 TEST_P(ModularFileSystemTest, TestGetFileSizePathIsInvalid) {
1333   const std::string filepath = GetURIForPath("a_file");
1334   std::unique_ptr<WritableFile> file;
1335   Status status = env_->NewWritableFile(filepath, &file);
1336   if (!status.ok())
1337     GTEST_SKIP() << "NewWritableFile() not supported: " << status;
1338 
1339   const std::string target_path = GetURIForPath("a_file/a_new_file");
1340   uint64 size;
1341   status = env_->GetFileSize(target_path, &size);
1342   EXPECT_PRED2(UnimplementedOrReturnsCode, status, Code::FAILED_PRECONDITION);
1343 }
1344 
TEST_P(ModularFileSystemTest,TestGetChildren)1345 TEST_P(ModularFileSystemTest, TestGetChildren) {
1346   const std::string dirpath = GetURIForPath("dir");
1347   Status status = env_->CreateDir(dirpath);
1348   if (!status.ok()) GTEST_SKIP() << "CreateDir() not supported: " << status;
1349 
1350   // If updating, make sure to update expected_children below.
1351   const std::vector<std::string> filenames = {
1352       GetURIForPath("dir/a_file"),
1353       GetURIForPath("dir/another_file"),
1354   };
1355   for (const auto& filename : filenames) {
1356     std::unique_ptr<WritableFile> file;
1357     status = env_->NewWritableFile(filename, &file);
1358     if (!status.ok())
1359       GTEST_SKIP() << "NewWritableFile() not supported: " << status;
1360   }
1361 
1362   // If updating, make sure to update expected_children below.
1363   const std::vector<std::string> dirnames = {
1364       GetURIForPath("dir/a_dir"),
1365       GetURIForPath("dir/another_dir"),
1366   };
1367   for (const auto& dirname : dirnames) {
1368     status = env_->CreateDir(dirname);
1369     if (!status.ok()) GTEST_SKIP() << "CreateDir() not supported: " << status;
1370   }
1371 
1372   std::vector<std::string> children;
1373   status = env_->GetChildren(dirpath, &children);
1374   EXPECT_PRED2(UnimplementedOrReturnsCode, status, Code::OK);
1375   if (!status.ok()) GTEST_SKIP() << "GetChildren() not supported: " << status;
1376 
1377   // All entries must show up in the vector.
1378   // Must contain only the last name in filenames and dirnames.
1379   const std::vector<std::string> expected_children = {"a_file", "another_file",
1380                                                       "a_dir", "another_dir"};
1381   EXPECT_EQ(children.size(), filenames.size() + dirnames.size());
1382   for (const auto& child : expected_children)
1383     EXPECT_NE(std::find(children.begin(), children.end(), child),
1384               children.end());
1385 }
1386 
TEST_P(ModularFileSystemTest,TestGetChildrenEmpty)1387 TEST_P(ModularFileSystemTest, TestGetChildrenEmpty) {
1388   const std::string dirpath = GetURIForPath("dir");
1389   Status status = env_->CreateDir(dirpath);
1390   if (!status.ok()) GTEST_SKIP() << "CreateDir() not supported: " << status;
1391 
1392   std::vector<std::string> children;
1393   status = env_->GetChildren(dirpath, &children);
1394   EXPECT_PRED2(UnimplementedOrReturnsCode, status, Code::OK);
1395   EXPECT_EQ(children.size(), 0);
1396 }
1397 
TEST_P(ModularFileSystemTest,TestGetChildrenOfFile)1398 TEST_P(ModularFileSystemTest, TestGetChildrenOfFile) {
1399   const std::string filepath = GetURIForPath("a_file");
1400   std::unique_ptr<WritableFile> file;
1401   Status status = env_->NewWritableFile(filepath, &file);
1402   if (!status.ok())
1403     GTEST_SKIP() << "NewWritableFile() not supported: " << status;
1404 
1405   std::vector<std::string> children;
1406   status = env_->GetChildren(filepath, &children);
1407   EXPECT_PRED2(UnimplementedOrReturnsCode, status, Code::FAILED_PRECONDITION);
1408 }
1409 
TEST_P(ModularFileSystemTest,TestGetChildrenPathNotFound)1410 TEST_P(ModularFileSystemTest, TestGetChildrenPathNotFound) {
1411   const std::string target_path = GetURIForPath("a_dir");
1412   std::vector<std::string> children;
1413   Status status = env_->GetChildren(target_path, &children);
1414   EXPECT_PRED2(UnimplementedOrReturnsCode, status, Code::NOT_FOUND);
1415 }
1416 
TEST_P(ModularFileSystemTest,TestGetChildrenPathIsInvalid)1417 TEST_P(ModularFileSystemTest, TestGetChildrenPathIsInvalid) {
1418   const std::string filepath = GetURIForPath("a_file");
1419   std::unique_ptr<WritableFile> file;
1420   Status status = env_->NewWritableFile(filepath, &file);
1421   if (!status.ok())
1422     GTEST_SKIP() << "NewWritableFile() not supported: " << status;
1423 
1424   const std::string target_path = GetURIForPath("a_file/a_new_dir");
1425   std::vector<std::string> children;
1426   status = env_->GetChildren(target_path, &children);
1427   EXPECT_PRED2(UnimplementedOrReturnsCode, status, Code::FAILED_PRECONDITION);
1428 }
1429 
TEST_P(ModularFileSystemTest,TestGetMatchingPaths)1430 TEST_P(ModularFileSystemTest, TestGetMatchingPaths) {
1431   const std::vector<std::string> matching_filenames = {
1432       GetURIForPath("a_file"),
1433       GetURIForPath("another_file"),
1434   };
1435   const std::vector<std::string> other_filenames = {
1436       GetURIForPath("some_file"),
1437       GetURIForPath("yet_another_file"),
1438   };
1439 
1440   for (const auto& filename : matching_filenames) {
1441     std::unique_ptr<WritableFile> file;
1442     Status status = env_->NewWritableFile(filename, &file);
1443     if (!status.ok())
1444       GTEST_SKIP() << "NewWritableFile() not supported: " << status;
1445   }
1446 
1447   for (const auto& filename : other_filenames) {
1448     std::unique_ptr<WritableFile> file;
1449     Status status = env_->NewWritableFile(filename, &file);
1450     if (!status.ok())
1451       GTEST_SKIP() << "NewWritableFile() not supported: " << status;
1452   }
1453 
1454   std::vector<std::string> results;
1455   Status status = env_->GetMatchingPaths(GetURIForPath("/a*"), &results);
1456   EXPECT_PRED2(UnimplementedOrReturnsCode, status, Code::OK);
1457   if (!status.ok())
1458     GTEST_SKIP() << "GetMatchingPaths() not supported: " << status;
1459   EXPECT_EQ(results.size(), matching_filenames.size());
1460   for (const auto& match : matching_filenames)
1461     EXPECT_NE(std::find(results.begin(), results.end(), match), results.end());
1462 }
1463 
TEST_P(ModularFileSystemTest,TestGetMatchingPathsEmptyFileSystem)1464 TEST_P(ModularFileSystemTest, TestGetMatchingPathsEmptyFileSystem) {
1465   std::vector<std::string> results;
1466   Status status = env_->GetMatchingPaths(GetURIForPath("a*"), &results);
1467   EXPECT_PRED2(UnimplementedOrReturnsCode, status, Code::OK);
1468   EXPECT_EQ(results.size(), 0);
1469 }
1470 
TEST_P(ModularFileSystemTest,TestGetMatchingPathsEmptyPattern)1471 TEST_P(ModularFileSystemTest, TestGetMatchingPathsEmptyPattern) {
1472   const std::vector<std::string> filenames = {
1473       GetURIForPath("a_file"),
1474       GetURIForPath("another_file"),
1475       GetURIForPath("some_file"),
1476       GetURIForPath("yet_another_file"),
1477   };
1478 
1479   for (const auto& filename : filenames) {
1480     std::unique_ptr<WritableFile> file;
1481     Status status = env_->NewWritableFile(filename, &file);
1482     if (!status.ok())
1483       GTEST_SKIP() << "NewWritableFile() not supported: " << status;
1484   }
1485 
1486   std::vector<std::string> results;
1487   Status status = env_->GetMatchingPaths(GetURIForPath(""), &results);
1488   EXPECT_PRED2(UnimplementedOrReturnsCode, status, Code::OK);
1489   if (!status.ok())
1490     GTEST_SKIP() << "GetMatchingPaths() not supported: " << status;
1491   EXPECT_EQ(results.size(), 1);
1492   EXPECT_NE(std::find(results.begin(), results.end(), GetURIForPath("")),
1493             results.end());
1494 }
1495 
TEST_P(ModularFileSystemTest,TestGetMatchingPathsLiteralMatch)1496 TEST_P(ModularFileSystemTest, TestGetMatchingPathsLiteralMatch) {
1497   const std::vector<std::string> filenames = {
1498       GetURIForPath("a_file"),
1499       GetURIForPath("another_file"),
1500       GetURIForPath("some_file"),
1501       GetURIForPath("yet_another_file"),
1502   };
1503 
1504   for (const auto& filename : filenames) {
1505     std::unique_ptr<WritableFile> file;
1506     Status status = env_->NewWritableFile(filename, &file);
1507     if (!status.ok())
1508       GTEST_SKIP() << "NewWritableFile() not supported: " << status;
1509   }
1510 
1511   std::vector<std::string> results;
1512   Status status = env_->GetMatchingPaths(filenames[0], &results);
1513   EXPECT_PRED2(UnimplementedOrReturnsCode, status, Code::OK);
1514   if (!status.ok())
1515     GTEST_SKIP() << "GetMatchingPaths() not supported: " << status;
1516   EXPECT_EQ(results.size(), 1);
1517   EXPECT_NE(std::find(results.begin(), results.end(), filenames[0]),
1518             results.end());
1519 }
1520 
TEST_P(ModularFileSystemTest,TestGetMatchingPathsNoMatch)1521 TEST_P(ModularFileSystemTest, TestGetMatchingPathsNoMatch) {
1522   const std::vector<std::string> filenames = {
1523       GetURIForPath("a_file"),
1524       GetURIForPath("another_file"),
1525       GetURIForPath("some_file"),
1526       GetURIForPath("yet_another_file"),
1527   };
1528 
1529   for (const auto& filename : filenames) {
1530     std::unique_ptr<WritableFile> file;
1531     Status status = env_->NewWritableFile(filename, &file);
1532     if (!status.ok())
1533       GTEST_SKIP() << "NewWritableFile() not supported: " << status;
1534   }
1535 
1536   std::vector<std::string> results;
1537   Status status = env_->GetMatchingPaths(GetURIForPath("x?y*"), &results);
1538   if (!status.ok())
1539     GTEST_SKIP() << "GetMatchingPaths() not supported: " << status;
1540   EXPECT_PRED2(UnimplementedOrReturnsCode, status, Code::OK);
1541   EXPECT_EQ(results.size(), 0);
1542 }
1543 
TEST_P(ModularFileSystemTest,TestAppendAndTell)1544 TEST_P(ModularFileSystemTest, TestAppendAndTell) {
1545   const std::string filename = GetURIForPath("a_file");
1546   std::unique_ptr<WritableFile> file;
1547   Status status = env_->NewWritableFile(filename, &file);
1548   if (!status.ok())
1549     GTEST_SKIP() << "NewWritableFile() not supported: " << status;
1550 
1551   int64 position;
1552   status = file->Tell(&position);
1553   EXPECT_PRED2(UnimplementedOrReturnsCode, status, Code::OK);
1554   if (!status.ok()) GTEST_SKIP() << "Tell() not supported: " << status;
1555   EXPECT_EQ(position, 0);
1556 
1557   const std::string test_data("asdf");
1558   status = file->Append(test_data);
1559   EXPECT_PRED2(UnimplementedOrReturnsCode, status, Code::OK);
1560   if (!status.ok()) GTEST_SKIP() << "Append() not supported: " << status;
1561 
1562   status = file->Tell(&position);
1563   EXPECT_EQ(status.code(), Code::OK);
1564   EXPECT_EQ(position, test_data.size());
1565 }
1566 
TEST_P(ModularFileSystemTest,TestClose)1567 TEST_P(ModularFileSystemTest, TestClose) {
1568   const std::string filename = GetURIForPath("a_file");
1569   std::unique_ptr<WritableFile> file;
1570   Status status = env_->NewWritableFile(filename, &file);
1571   if (!status.ok())
1572     GTEST_SKIP() << "NewWritableFile() not supported: " << status;
1573 
1574   status = file->Close();
1575   EXPECT_PRED2(UnimplementedOrReturnsCode, status, Code::OK);
1576   if (!status.ok()) GTEST_SKIP() << "Close() not supported: " << status;
1577 }
1578 
TEST_P(ModularFileSystemTest,TestRoundTrip)1579 TEST_P(ModularFileSystemTest, TestRoundTrip) {
1580   const std::string filepath = GetURIForPath("a_file");
1581   std::unique_ptr<WritableFile> file;
1582   Status status = env_->NewWritableFile(filepath, &file);
1583   if (!status.ok())
1584     GTEST_SKIP() << "NewWritableFile() not supported: " << status;
1585 
1586   const std::string test_data("asdf");
1587   status = file->Append(test_data);
1588   EXPECT_PRED2(UnimplementedOrReturnsCode, status, Code::OK);
1589   if (!status.ok()) GTEST_SKIP() << "Append() not supported: " << status;
1590 
1591   status = file->Flush();
1592   EXPECT_PRED2(UnimplementedOrReturnsCode, status, Code::OK);
1593   if (!status.ok()) GTEST_SKIP() << "Flush() not supported: " << status;
1594 
1595   status = file->Close();
1596   EXPECT_PRED2(UnimplementedOrReturnsCode, status, Code::OK);
1597   if (!status.ok()) GTEST_SKIP() << "Close() not supported: " << status;
1598 
1599   std::unique_ptr<RandomAccessFile> read_file;
1600   status = env_->NewRandomAccessFile(filepath, &read_file);
1601   if (!status.ok())
1602     GTEST_SKIP() << "NewRandomAccessFile() not supported: " << status;
1603 
1604   char scratch[64 /* big enough to accommodate test_data */] = {0};
1605   StringPiece result;
1606   status = read_file->Read(0, test_data.size(), &result, scratch);
1607   EXPECT_PRED2(UnimplementedOrReturnsCode, status, Code::OK);
1608   EXPECT_EQ(test_data, result);
1609 }
1610 
TEST_P(ModularFileSystemTest,TestRoundTripWithAppendableFile)1611 TEST_P(ModularFileSystemTest, TestRoundTripWithAppendableFile) {
1612   const std::string filepath = GetURIForPath("a_file");
1613   std::unique_ptr<WritableFile> file;
1614   Status status = env_->NewWritableFile(filepath, &file);
1615   if (!status.ok())
1616     GTEST_SKIP() << "NewWritableFile() not supported: " << status;
1617 
1618   const std::string test_data("asdf");
1619   status = file->Append(test_data);
1620   EXPECT_PRED2(UnimplementedOrReturnsCode, status, Code::OK);
1621   if (!status.ok()) GTEST_SKIP() << "Append() not supported: " << status;
1622 
1623   status = file->Flush();
1624   EXPECT_PRED2(UnimplementedOrReturnsCode, status, Code::OK);
1625   if (!status.ok()) GTEST_SKIP() << "Flush() not supported: " << status;
1626 
1627   status = file->Close();
1628   EXPECT_PRED2(UnimplementedOrReturnsCode, status, Code::OK);
1629   if (!status.ok()) GTEST_SKIP() << "Close() not supported: " << status;
1630 
1631   std::unique_ptr<WritableFile> same_file;
1632   status = env_->NewAppendableFile(filepath, &same_file);
1633   if (!status.ok())
1634     GTEST_SKIP() << "NewAppendableFile() not supported: " << status;
1635 
1636   const std::string more_test_data("qwer");
1637   EXPECT_EQ(same_file->Append(more_test_data).code(), Code::OK);
1638   EXPECT_EQ(same_file->Flush().code(), Code::OK);
1639   EXPECT_EQ(same_file->Close().code(), Code::OK);
1640 
1641   std::unique_ptr<RandomAccessFile> read_file;
1642   status = env_->NewRandomAccessFile(filepath, &read_file);
1643   if (!status.ok())
1644     GTEST_SKIP() << "NewRandomAccessFile() not supported: " << status;
1645 
1646   char scratch[64 /* big enough for test_data and more_test_data */] = {0};
1647   StringPiece result;
1648   status = read_file->Read(0, test_data.size() + more_test_data.size(), &result,
1649                            scratch);
1650   EXPECT_PRED2(UnimplementedOrReturnsCode, status, Code::OK);
1651   EXPECT_EQ(test_data + more_test_data, result);
1652   EXPECT_EQ(
1653       read_file->Read(test_data.size(), more_test_data.size(), &result, scratch)
1654           .code(),
1655       Code::OK);
1656   EXPECT_EQ(more_test_data, result);
1657 }
1658 
TEST_P(ModularFileSystemTest,TestReadOutOfRange)1659 TEST_P(ModularFileSystemTest, TestReadOutOfRange) {
1660   const std::string filepath = GetURIForPath("a_file");
1661   std::unique_ptr<WritableFile> file;
1662   Status status = env_->NewWritableFile(filepath, &file);
1663   if (!status.ok())
1664     GTEST_SKIP() << "NewWritableFile() not supported: " << status;
1665 
1666   const std::string test_data("asdf");
1667   status = file->Append(test_data);
1668   EXPECT_PRED2(UnimplementedOrReturnsCode, status, Code::OK);
1669   if (!status.ok()) GTEST_SKIP() << "Append() not supported: " << status;
1670 
1671   status = file->Flush();
1672   EXPECT_PRED2(UnimplementedOrReturnsCode, status, Code::OK);
1673   if (!status.ok()) GTEST_SKIP() << "Flush() not supported: " << status;
1674 
1675   status = file->Close();
1676   EXPECT_PRED2(UnimplementedOrReturnsCode, status, Code::OK);
1677   if (!status.ok()) GTEST_SKIP() << "Close() not supported: " << status;
1678 
1679   std::unique_ptr<RandomAccessFile> read_file;
1680   status = env_->NewRandomAccessFile(filepath, &read_file);
1681   if (!status.ok())
1682     GTEST_SKIP() << "NewRandomAccessFile() not supported: " << status;
1683 
1684   char scratch[64 /* must be bigger than test_data */] = {0};
1685   StringPiece result;
1686   // read at least 1 byte more than test_data
1687   status = read_file->Read(0, test_data.size() + 1, &result, scratch);
1688   EXPECT_PRED2(UnimplementedOrReturnsCode, status, Code::OUT_OF_RANGE);
1689 }
1690 
1691 // The URI schemes that need to be tested are provided by the user via flags
1692 // (or, if none is supplied, all existing schemes are used). As a scheme can
1693 // become available after a shared object with a filesystem implementation is
1694 // loaded, we can only check for availability after all arguments have been
1695 // parsed.
1696 //
1697 // Furthermore, as `INSTANTIATE_TEST_SUITE_P` needs to be at global level and we
1698 // don't want to have a `std::vector<std::string>` at global level, we use a
1699 // static pointer to such a vector: we construct it via `SchemeVector()` below
1700 // and when tests are instantiated we process it using `GetSchemes()`.
SchemeVector()1701 static std::vector<std::string>* SchemeVector() {
1702   static std::vector<std::string>* schemes = new std::vector<std::string>;
1703   return schemes;
1704 }
1705 
1706 // `INSTANTIATE_TEST_SUITE_P` is called once for every `TEST_P`. However, we
1707 // only want to analyze the user provided schemes and those that are registered
1708 // only once. Hence, this function keeping another static pointer to a vector
1709 // which contains only the schemes under test.
1710 //
1711 // Without this additional step, when there are schemes available but the user
1712 // only requests schemes that don't exist, first instantiation of the test would
1713 // filter out all the user provided schemes (as they are not registered) but
1714 // subsequent instantiations would return all registered schemes (since the
1715 // vector with the user provided schemes is cleared).
GetSchemesFromUserOrEnv()1716 static std::vector<std::string>* GetSchemesFromUserOrEnv() {
1717   std::vector<std::string>* all_schemes = new std::vector<std::string>;
1718   tensorflow::Status status =
1719       tensorflow::Env::Default()->GetRegisteredFileSystemSchemes(all_schemes);
1720 
1721   if (status.ok()) {
1722     std::vector<std::string>* user_schemes = SchemeVector();
1723     if (!user_schemes->empty()) {
1724       auto is_requested_scheme = [user_schemes](const auto& scheme) {
1725         return std::find(user_schemes->begin(), user_schemes->end(), scheme) ==
1726                user_schemes->end();
1727       };
1728       auto end = std::remove_if(all_schemes->begin(), all_schemes->end(),
1729                                 is_requested_scheme);
1730       all_schemes->erase(end, all_schemes->end());
1731     }
1732   }
1733 
1734   return all_schemes;
1735 }
1736 
GetSchemes()1737 static std::vector<std::string> GetSchemes() {
1738   static std::vector<std::string>* schemes = GetSchemesFromUserOrEnv();
1739   return *schemes;
1740 }
1741 
1742 INSTANTIATE_TEST_SUITE_P(ModularFileSystem, ModularFileSystemTest,
1743                          ::testing::ValuesIn(GetSchemes()));
1744 
1745 // Loads a shared object implementing filesystem functionality.
LoadDSO(const std::string & dso)1746 static bool LoadDSO(const std::string& dso) {
1747   tensorflow::Status status = RegisterFilesystemPlugin(dso);
1748   if (!status.ok())
1749     VLOG(0) << "Filesystems from '" << dso
1750             << "' could not be registered: " << status;
1751   return status.ok();
1752 }
1753 
1754 // Tests whether a URI scheme results in a filesystem that is supported.
1755 //
1756 // As we need these URI schemes to instantiate the test suite when
1757 // `testing::InitGoogleTest` gets called, here we just store them to an
1758 // internal scheme registry. See `URISchemeRegister` above.
GetURIScheme(const std::string & scheme)1759 static bool GetURIScheme(const std::string& scheme) {
1760   tensorflow::SchemeVector()->push_back(scheme);
1761   return true;
1762 }
1763 
1764 // This function is used for cloud filesystem
1765 // `S3` and `GCS` require the `root_dir_` to have bucket name
1766 // `HDFS` requires the `root_dir` to have namenode
1767 // `root_dir_ = scheme + "://" cloud_path_ + root_dir_`
SetCloudPath(const std::string & cloud_path_)1768 static bool SetCloudPath(const std::string& cloud_path_) {
1769   ModularFileSystemTest::SetCloudPath(cloud_path_);
1770   return true;
1771 }
1772 
SetTmpDir(const std::string & tmp_dir_)1773 static bool SetTmpDir(const std::string& tmp_dir_) {
1774   ModularFileSystemTest::SetTmpDir(tmp_dir_);
1775   return true;
1776 }
1777 
1778 }  // namespace
1779 }  // namespace tensorflow
1780 
1781 // Due to the usages of flags for this manual test, we need a special `main` to
1782 // ensure our flags are parsed properly as `testing::InitGoogleTest` silently
1783 // ignores other flags. Furthermore, we need this to ensure that the DSO is
1784 // loaded exactly once, if provided.
main(int argc,char ** argv)1785 GTEST_API_ int main(int argc, char** argv) {
1786   const std::vector<tensorflow::Flag> flag_list = {
1787       tensorflow::Flag("dso", tensorflow::LoadDSO, "",
1788                        "Path to shared object to load"),
1789       tensorflow::Flag("scheme", tensorflow::GetURIScheme, "",
1790                        "URI scheme to test"),
1791       tensorflow::Flag("cloud_path", tensorflow::SetCloudPath, "",
1792                        "Path for cloud filesystem (namenode for hdfs, "
1793                        "bucketname for s3/gcs)"),
1794       tensorflow::Flag("tmp_dir", tensorflow::SetTmpDir, "",
1795                        "Temporary directory to store test data.")};
1796   if (!tensorflow::Flags::Parse(&argc, argv, flag_list)) {
1797     std::cout << tensorflow::Flags::Usage(argv[0], flag_list);
1798     return -1;
1799   }
1800 
1801   tensorflow::testing::InstallStacktraceHandler();
1802   tensorflow::ModularFileSystemTest::InitializeTestRNG();
1803   testing::InitGoogleTest(&argc, argv);
1804   return RUN_ALL_TESTS();
1805 }
1806