@@ -201,6 +201,21 @@ class ErrorDummyFileSystem : public DummyFileSystem {
201
201
}
202
202
};
203
203
204
+ // / A version of \c DummyFileSystem that aborts on \c status() to test that
205
+ // / \c exists() is being used.
206
+ class NoStatusDummyFileSystem : public DummyFileSystem {
207
+ public:
208
+ ErrorOr<vfs::Status> status (const Twine &Path) override {
209
+ llvm::report_fatal_error (
210
+ " unexpected call to NoStatusDummyFileSystem::status" );
211
+ }
212
+
213
+ bool exists (const Twine &Path) override {
214
+ auto Status = DummyFileSystem::status (Path);
215
+ return Status && Status->exists ();
216
+ }
217
+ };
218
+
204
219
// / Replace back-slashes by front-slashes.
205
220
std::string getPosixPath (const Twine &S) {
206
221
SmallString<128 > Result;
@@ -968,6 +983,30 @@ TEST(OverlayFileSystemTest, PrintOutput) {
968
983
Output);
969
984
}
970
985
986
+ TEST (OverlayFileSystemTest, Exists) {
987
+ IntrusiveRefCntPtr<DummyFileSystem> Lower (new NoStatusDummyFileSystem ());
988
+ IntrusiveRefCntPtr<DummyFileSystem> Upper (new NoStatusDummyFileSystem ());
989
+ IntrusiveRefCntPtr<vfs::OverlayFileSystem> O (
990
+ new vfs::OverlayFileSystem (Lower));
991
+ O->pushOverlay (Upper);
992
+
993
+ Lower->addDirectory (" /both" );
994
+ Upper->addDirectory (" /both" );
995
+ Lower->addRegularFile (" /both/lower_file" );
996
+ Upper->addRegularFile (" /both/upper_file" );
997
+ Lower->addDirectory (" /lower" );
998
+ Upper->addDirectory (" /upper" );
999
+
1000
+ EXPECT_TRUE (O->exists (" /both" ));
1001
+ EXPECT_TRUE (O->exists (" /both" ));
1002
+ EXPECT_TRUE (O->exists (" /both/lower_file" ));
1003
+ EXPECT_TRUE (O->exists (" /both/upper_file" ));
1004
+ EXPECT_TRUE (O->exists (" /lower" ));
1005
+ EXPECT_TRUE (O->exists (" /upper" ));
1006
+ EXPECT_FALSE (O->exists (" /both/nope" ));
1007
+ EXPECT_FALSE (O->exists (" /nope" ));
1008
+ }
1009
+
971
1010
TEST (ProxyFileSystemTest, Basic) {
972
1011
IntrusiveRefCntPtr<vfs::InMemoryFileSystem> Base (
973
1012
new vfs::InMemoryFileSystem ());
@@ -3364,6 +3403,11 @@ TEST(RedirectingFileSystemTest, ExternalPaths) {
3364
3403
SeenPaths.push_back (Dir.str ());
3365
3404
return ProxyFileSystem::dir_begin (Dir, EC);
3366
3405
}
3406
+
3407
+ bool exists (const Twine &Path) override {
3408
+ SeenPaths.push_back (Path.str ());
3409
+ return ProxyFileSystem::exists (Path);
3410
+ }
3367
3411
};
3368
3412
3369
3413
std::error_code EC;
@@ -3395,3 +3439,124 @@ TEST(RedirectingFileSystemTest, ExternalPaths) {
3395
3439
3396
3440
EXPECT_EQ (CheckFS->SeenPaths , Expected);
3397
3441
}
3442
+
3443
+ TEST (RedirectingFileSystemTest, Exists) {
3444
+ IntrusiveRefCntPtr<DummyFileSystem> Dummy (new NoStatusDummyFileSystem ());
3445
+ auto YAML =
3446
+ MemoryBuffer::getMemBuffer (" {\n "
3447
+ " 'version': 0,\n "
3448
+ " 'roots': [\n "
3449
+ " {\n "
3450
+ " 'type': 'directory-remap',\n "
3451
+ " 'name': '/dremap',\n "
3452
+ " 'external-contents': '/a',\n "
3453
+ " },"
3454
+ " {\n "
3455
+ " 'type': 'directory-remap',\n "
3456
+ " 'name': '/dmissing',\n "
3457
+ " 'external-contents': '/dmissing',\n "
3458
+ " },"
3459
+ " {\n "
3460
+ " 'type': 'directory',\n "
3461
+ " 'name': '/both',\n "
3462
+ " 'contents': [\n "
3463
+ " {\n "
3464
+ " 'type': 'file',\n "
3465
+ " 'name': 'vfile',\n "
3466
+ " 'external-contents': '/c'\n "
3467
+ " }\n "
3468
+ " ]\n "
3469
+ " },\n "
3470
+ " {\n "
3471
+ " 'type': 'directory',\n "
3472
+ " 'name': '/vdir',\n "
3473
+ " 'contents': ["
3474
+ " {\n "
3475
+ " 'type': 'directory-remap',\n "
3476
+ " 'name': 'dremap',\n "
3477
+ " 'external-contents': '/b'\n "
3478
+ " },\n "
3479
+ " {\n "
3480
+ " 'type': 'file',\n "
3481
+ " 'name': 'missing',\n "
3482
+ " 'external-contents': '/missing'\n "
3483
+ " },\n "
3484
+ " {\n "
3485
+ " 'type': 'file',\n "
3486
+ " 'name': 'vfile',\n "
3487
+ " 'external-contents': '/c'\n "
3488
+ " }]\n "
3489
+ " }]\n "
3490
+ " }" );
3491
+
3492
+ Dummy->addDirectory (" /a" );
3493
+ Dummy->addRegularFile (" /a/foo" );
3494
+ Dummy->addDirectory (" /b" );
3495
+ Dummy->addRegularFile (" /c" );
3496
+ Dummy->addRegularFile (" /both/foo" );
3497
+
3498
+ auto Redirecting = vfs::RedirectingFileSystem::create (
3499
+ std::move (YAML), nullptr , " " , nullptr , Dummy);
3500
+
3501
+ EXPECT_TRUE (Redirecting->exists (" /dremap" ));
3502
+ EXPECT_FALSE (Redirecting->exists (" /dmissing" ));
3503
+ EXPECT_FALSE (Redirecting->exists (" /unknown" ));
3504
+ EXPECT_TRUE (Redirecting->exists (" /both" ));
3505
+ EXPECT_TRUE (Redirecting->exists (" /both/foo" ));
3506
+ EXPECT_TRUE (Redirecting->exists (" /both/vfile" ));
3507
+ EXPECT_TRUE (Redirecting->exists (" /vdir" ));
3508
+ EXPECT_TRUE (Redirecting->exists (" /vdir/dremap" ));
3509
+ EXPECT_FALSE (Redirecting->exists (" /vdir/missing" ));
3510
+ EXPECT_TRUE (Redirecting->exists (" /vdir/vfile" ));
3511
+ EXPECT_FALSE (Redirecting->exists (" /vdir/unknown" ));
3512
+ }
3513
+
3514
+ TEST (RedirectingFileSystemTest, ExistsFallback) {
3515
+ IntrusiveRefCntPtr<DummyFileSystem> Dummy (new NoStatusDummyFileSystem ());
3516
+ auto YAML =
3517
+ MemoryBuffer::getMemBuffer (" {\n "
3518
+ " 'version': 0,\n "
3519
+ " 'redirecting-with': 'fallback',\n "
3520
+ " 'roots': [\n "
3521
+ " {\n "
3522
+ " 'type': 'file',\n "
3523
+ " 'name': '/fallback',\n "
3524
+ " 'external-contents': '/missing',\n "
3525
+ " },"
3526
+ " ]\n "
3527
+ " }" );
3528
+
3529
+ Dummy->addRegularFile (" /fallback" );
3530
+
3531
+ auto Redirecting = vfs::RedirectingFileSystem::create (
3532
+ std::move (YAML), nullptr , " " , nullptr , Dummy);
3533
+
3534
+ EXPECT_TRUE (Redirecting->exists (" /fallback" ));
3535
+ EXPECT_FALSE (Redirecting->exists (" /missing" ));
3536
+ }
3537
+
3538
+ TEST (RedirectingFileSystemTest, ExistsRedirectOnly) {
3539
+ IntrusiveRefCntPtr<DummyFileSystem> Dummy (new NoStatusDummyFileSystem ());
3540
+ auto YAML =
3541
+ MemoryBuffer::getMemBuffer (" {\n "
3542
+ " 'version': 0,\n "
3543
+ " 'redirecting-with': 'redirect-only',\n "
3544
+ " 'roots': [\n "
3545
+ " {\n "
3546
+ " 'type': 'file',\n "
3547
+ " 'name': '/vfile',\n "
3548
+ " 'external-contents': '/a',\n "
3549
+ " },"
3550
+ " ]\n "
3551
+ " }" );
3552
+
3553
+ Dummy->addRegularFile (" /a" );
3554
+ Dummy->addRegularFile (" /b" );
3555
+
3556
+ auto Redirecting = vfs::RedirectingFileSystem::create (
3557
+ std::move (YAML), nullptr , " " , nullptr , Dummy);
3558
+
3559
+ EXPECT_FALSE (Redirecting->exists (" /a" ));
3560
+ EXPECT_FALSE (Redirecting->exists (" /b" ));
3561
+ EXPECT_TRUE (Redirecting->exists (" /vfile" ));
3562
+ }
0 commit comments