@@ -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 ());
@@ -3395,3 +3434,124 @@ TEST(RedirectingFileSystemTest, ExternalPaths) {
3395
3434
3396
3435
EXPECT_EQ (CheckFS->SeenPaths , Expected);
3397
3436
}
3437
+
3438
+ TEST (RedirectingFileSystemTest, Exists) {
3439
+ IntrusiveRefCntPtr<DummyFileSystem> Dummy (new NoStatusDummyFileSystem ());
3440
+ auto YAML =
3441
+ MemoryBuffer::getMemBuffer (" {\n "
3442
+ " 'version': 0,\n "
3443
+ " 'roots': [\n "
3444
+ " {\n "
3445
+ " 'type': 'directory-remap',\n "
3446
+ " 'name': '/dremap',\n "
3447
+ " 'external-contents': '/a',\n "
3448
+ " },"
3449
+ " {\n "
3450
+ " 'type': 'directory-remap',\n "
3451
+ " 'name': '/dmissing',\n "
3452
+ " 'external-contents': '/dmissing',\n "
3453
+ " },"
3454
+ " {\n "
3455
+ " 'type': 'directory',\n "
3456
+ " 'name': '/both',\n "
3457
+ " 'contents': [\n "
3458
+ " {\n "
3459
+ " 'type': 'file',\n "
3460
+ " 'name': 'vfile',\n "
3461
+ " 'external-contents': '/c'\n "
3462
+ " }\n "
3463
+ " ]\n "
3464
+ " },\n "
3465
+ " {\n "
3466
+ " 'type': 'directory',\n "
3467
+ " 'name': '/vdir',\n "
3468
+ " 'contents': ["
3469
+ " {\n "
3470
+ " 'type': 'directory-remap',\n "
3471
+ " 'name': 'dremap',\n "
3472
+ " 'external-contents': '/b'\n "
3473
+ " },\n "
3474
+ " {\n "
3475
+ " 'type': 'file',\n "
3476
+ " 'name': 'missing',\n "
3477
+ " 'external-contents': '/missing'\n "
3478
+ " },\n "
3479
+ " {\n "
3480
+ " 'type': 'file',\n "
3481
+ " 'name': 'vfile',\n "
3482
+ " 'external-contents': '/c'\n "
3483
+ " }]\n "
3484
+ " }]\n "
3485
+ " }" );
3486
+
3487
+ Dummy->addDirectory (" /a" );
3488
+ Dummy->addRegularFile (" /a/foo" );
3489
+ Dummy->addDirectory (" /b" );
3490
+ Dummy->addRegularFile (" /c" );
3491
+ Dummy->addRegularFile (" /both/foo" );
3492
+
3493
+ auto Redirecting = vfs::RedirectingFileSystem::create (
3494
+ std::move (YAML), nullptr , " " , nullptr , Dummy);
3495
+
3496
+ EXPECT_TRUE (Redirecting->exists (" /dremap" ));
3497
+ EXPECT_FALSE (Redirecting->exists (" /dmissing" ));
3498
+ EXPECT_FALSE (Redirecting->exists (" /unknown" ));
3499
+ EXPECT_TRUE (Redirecting->exists (" /both" ));
3500
+ EXPECT_TRUE (Redirecting->exists (" /both/foo" ));
3501
+ EXPECT_TRUE (Redirecting->exists (" /both/vfile" ));
3502
+ EXPECT_TRUE (Redirecting->exists (" /vdir" ));
3503
+ EXPECT_TRUE (Redirecting->exists (" /vdir/dremap" ));
3504
+ EXPECT_FALSE (Redirecting->exists (" /vdir/missing" ));
3505
+ EXPECT_TRUE (Redirecting->exists (" /vdir/vfile" ));
3506
+ EXPECT_FALSE (Redirecting->exists (" /vdir/unknown" ));
3507
+ }
3508
+
3509
+ TEST (RedirectingFileSystemTest, ExistsFallback) {
3510
+ IntrusiveRefCntPtr<DummyFileSystem> Dummy (new NoStatusDummyFileSystem ());
3511
+ auto YAML =
3512
+ MemoryBuffer::getMemBuffer (" {\n "
3513
+ " 'version': 0,\n "
3514
+ " 'redirecting-with': 'fallback',\n "
3515
+ " 'roots': [\n "
3516
+ " {\n "
3517
+ " 'type': 'file',\n "
3518
+ " 'name': '/fallback',\n "
3519
+ " 'external-contents': '/missing',\n "
3520
+ " },"
3521
+ " ]\n "
3522
+ " }" );
3523
+
3524
+ Dummy->addRegularFile (" /fallback" );
3525
+
3526
+ auto Redirecting = vfs::RedirectingFileSystem::create (
3527
+ std::move (YAML), nullptr , " " , nullptr , Dummy);
3528
+
3529
+ EXPECT_TRUE (Redirecting->exists (" /fallback" ));
3530
+ EXPECT_FALSE (Redirecting->exists (" /missing" ));
3531
+ }
3532
+
3533
+ TEST (RedirectingFileSystemTest, ExistsRedirectOnly) {
3534
+ IntrusiveRefCntPtr<DummyFileSystem> Dummy (new NoStatusDummyFileSystem ());
3535
+ auto YAML =
3536
+ MemoryBuffer::getMemBuffer (" {\n "
3537
+ " 'version': 0,\n "
3538
+ " 'redirecting-with': 'redirect-only',\n "
3539
+ " 'roots': [\n "
3540
+ " {\n "
3541
+ " 'type': 'file',\n "
3542
+ " 'name': '/vfile',\n "
3543
+ " 'external-contents': '/a',\n "
3544
+ " },"
3545
+ " ]\n "
3546
+ " }" );
3547
+
3548
+ Dummy->addRegularFile (" /a" );
3549
+ Dummy->addRegularFile (" /b" );
3550
+
3551
+ auto Redirecting = vfs::RedirectingFileSystem::create (
3552
+ std::move (YAML), nullptr , " " , nullptr , Dummy);
3553
+
3554
+ EXPECT_FALSE (Redirecting->exists (" /a" ));
3555
+ EXPECT_FALSE (Redirecting->exists (" /b" ));
3556
+ EXPECT_TRUE (Redirecting->exists (" /vfile" ));
3557
+ }
0 commit comments