src/storage/blobfs/test/integration/large/short.cc
// The purpose of this test is to repro the case where a blob is being retrieved from the blob hash
// at the same time it is being destructed, causing an invalid vnode to be returned. This can only
// occur when the client is opening a new fd to the blob at the same time it is being destructed
// after all writes to disk have completed.
// This test works best if a sleep is added at the beginning of fbl_recycle in VnodeBlob.
//
// TODO(rvargas): The description seems to hint that this test should be removed because it's
// not really doing anything (requires adding sleeps in the code); it's trying to protect against
// a regression for a race from too far away.
The purpose of this test is to repro the case where a blob is being retrieved from the blob hash
at the same time it is being destructed, causing an invalid vnode to be returned. This can only
occur when the client is opening a new fd to the blob at the same time it is being destructed
after all writes to disk have completed.
This test works best if a sleep is added at the beginning of fbl_recycle in VnodeBlob.

The description seems to hint that this test should be removed because it's
not really doing anything (requires adding sleeps in the code); it's trying to protect against
a regression for a race from too far away.
The purpose of this test is to repro the case where a blob is being retrieved from the blob hash at the same time it is being destructed causing an invalid vnode to be returned . This can only occur when the client is opening a new fd to the blob at the same time it is being destructed after all writes to disk have completed . This test works best if a sleep is added at the beginning of fbl_recycle in VnodeBlob . The description seems to hint that this test should be removed because it ' s not really doing anything ( requires adding sleeps in the code ) ; it ' s trying to protect against a regression for a race from too far away .
void RunCreateWriteReopenTest() {
  size_t num_ops = 10;
  std::unique_ptr<BlobInfo> anchor_info;
  ASSERT_NO_FAILURES(GenerateRandomBlob(kMountPath, 1 << 10, &anchor_info));
  std::unique_ptr<BlobInfo> info;
  ASSERT_NO_FAILURES(GenerateRandomBlob(kMountPath, 10 * (1 << 20), &info));
  std::string path(info->path);
  for (size_t i = 0; i < num_ops; i++) {
    fprintf(stderr, "Running op %lu...\n", i);
    fbl::unique_fd fd;
    fbl::unique_fd anchor_fd;
    ASSERT_NO_FAILURES(MakeBlobUnverified(info.get(), &fd));
    ASSERT_NO_FAILURES(MakeBlobUnverified(anchor_info.get(), &anchor_fd));
    fd.reset();
    std::atomic_bool done = false;
    std::thread thread(ReopenThread, path, &done);
    {
      auto join_thread = fbl::MakeAutoCall([&]() {
        done = true;
        thread.join();
      });
      sleep(1);
      ASSERT_EQ(syncfs(anchor_fd.get()), 0);
    }
    ASSERT_EQ(0, unlink(info->path));
    ASSERT_EQ(0, unlink(anchor_info->path));
  }
}
void RunCreateWriteReopenTest ( ) { size_t num_ops = 10 ; std :: unique_ptr < BlobInfo > anchor_info ; ASSERT_NO_FAILURES ( GenerateRandomBlob ( kMountPath , 1 << 10 , & anchor_info ) ) ; std :: unique_ptr < BlobInfo > info ; ASSERT_NO_FAILURES ( GenerateRandomBlob ( kMountPath , 10 * ( 1 << 20 ) , & info ) ) ; std :: string path ( info -> path ) ; for ( size_t i = 0 ; i < num_ops ; i ++ ) { fprintf ( stderr , " \n " , i ) ; fbl :: unique_fd fd ; fbl :: unique_fd anchor_fd ; ASSERT_NO_FAILURES ( MakeBlobUnverified ( info . get ( ) , & fd ) ) ; ASSERT_NO_FAILURES ( MakeBlobUnverified ( anchor_info . get ( ) , & anchor_fd ) ) ; fd . reset ( ) ; std :: atomic_bool done = false ; std :: thread thread ( ReopenThread , path , & done ) ; { auto join_thread = fbl :: MakeAutoCall ( [ & ] ( ) { done = true ; thread . join ( ) ; } ) ; sleep ( 1 ) ; ASSERT_EQ ( syncfs ( anchor_fd . get ( ) ) , 0 ) ; } ASSERT_EQ ( 0 , unlink ( info -> path ) ) ; ASSERT_EQ ( 0 , unlink ( anchor_info -> path ) ) ; } }
The purpose of this test is to repro the case where a blob is being retrieved from the blob hash
at the same time it is being destructed, causing an invalid vnode to be returned.
The purpose of this test is to repro the case where a blob is being retrieved from the blob hash at the same time it is being destructed causing an invalid vnode to be returned .
// Write both blobs to disk (without verification, so we can start reopening the blob asap). // Launch a background thread to wait for the file to become readable. // Always join the thread before returning from the test. // Sleep while the thread continually opens and closes the blob.