text: #include <fcntl.h>
  #include <sys/stat.h>
  #include <sys/types.h>
  #include <unistd.h>
  #include <string>
  #include <iostream>
  #include <dirent.h>
  #include <cstring>
  #include <errno.h>
  #include <attr/xattr.h>
  
  #include "BaseTestCase.h"
  #include "../user_tools/api/workload.h"
  #include "../user_tools/api/actions.h"
  
  using fs_testing::tests::DataTestResult;
  using fs_testing::user_tools::api::WriteData;
  using fs_testing::user_tools::api::WriteDataMmap;
  using fs_testing::user_tools::api::Checkpoint;
  using std::string;
  
  #define TEST_FILE_PERMS  ((mode_t) (S_IRWXU | S_IRWXG | S_IRWXO))
  
  namespace fs_testing {
      namespace tests {
          
          
          class testName: public BaseTestCase {
              
              public:
              
              virtual int setup() override {
                  
                  test_path = mnt_dir_ ;
                  A_path = mnt_dir_ + "/A";
                  AC_path = mnt_dir_ + "/A/C";
                  B_path = mnt_dir_ + "/B";
                  Afoo_path = mnt_dir_ + "/A/foo";
                  Abar_path = mnt_dir_ + "/A/bar";
                  Bfoo_path = mnt_dir_ + "/B/foo";
                  Bbar_path = mnt_dir_ + "/B/bar";
                  ACfoo_path = mnt_dir_ + "/A/C/foo";
                  ACbar_path = mnt_dir_ + "/A/C/bar";
                  return 0;
              }
              
              virtual int run( int checkpoint ) override {
                  
                  test_path = mnt_dir_ ;
                  A_path =  mnt_dir_ + "/A";
                  AC_path =  mnt_dir_ + "/A/C";
                  B_path =  mnt_dir_ + "/B";
                  Afoo_path =  mnt_dir_ + "/A/foo";
                  Abar_path =  mnt_dir_ + "/A/bar";
                  Bfoo_path =  mnt_dir_ + "/B/foo";
                  Bbar_path =  mnt_dir_ + "/B/bar";
                  ACfoo_path =  mnt_dir_ + "/A/C/foo";
                  ACbar_path =  mnt_dir_ + "/A/C/bar";
                  int local_checkpoint = 0 ;
                  
                  if ( mkdir(A_path.c_str() , 0777) < 0){
                      return errno;
                  }
                  
                  if ( mkdir(AC_path.c_str() , 0777) < 0){
                      return errno;
                  }
                  
                  if ( mkdir(B_path.c_str() , 0777) < 0){
                      return errno;
                  }
                  
                  int fd_Bfoo = cm_->CmOpen(Bfoo_path.c_str() , O_RDWR|O_CREAT , 0777);
                  if ( fd_Bfoo < 0 ) {
                      cm_->CmClose( fd_Bfoo);
                      return errno;
                  }
                  
                  if ( cm_->CmFsync( fd_Bfoo) < 0){
                      return errno;
                  }
                  
                  if ( cm_->CmCheckpoint() < 0){
                      return -1;
                  }
                  local_checkpoint += 1;
                  if (local_checkpoint == checkpoint) {
                      return 0;
                  }
                  
                  int fd_Bbar = cm_->CmOpen(Bbar_path.c_str() , O_RDWR|O_CREAT , 0777);
                  if ( fd_Bbar < 0 ) {
                      cm_->CmClose( fd_Bbar);
                      return errno;
                  }
                  
                  
                  if ( cm_->CmFsync( fd_Bbar) < 0){
                      return errno;
                  }
                  
                  
                  if ( cm_->CmCheckpoint() < 0){
                      return -1;
                  }
                  local_checkpoint += 1;
                  if (local_checkpoint == checkpoint) {
                      return 0;
                  }
                  
                  if ( link(Bfoo_path.c_str() , ACfoo_path.c_str() ) < 0){
                      return errno;
                  }
                  
                  int fd_A = cm_->CmOpen(A_path.c_str() , O_DIRECTORY , 0777);
                  if ( fd_A < 0 ) {
                      cm_->CmClose( fd_A);
                      return errno;
                  }
                  
                  if ( cm_->CmFsync( fd_A) < 0){
                      return errno;
                  }
                  
                  
                  if ( cm_->CmCheckpoint() < 0){ 
                      return -1;
                  }
                  local_checkpoint += 1; 
                  if (local_checkpoint == checkpoint) { 
                      return 1;
                  }
                  
                  
                  if ( cm_->CmClose ( fd_Bbar) < 0){ 
                      return errno;
                  }
                  
                  if ( cm_->CmClose ( fd_Bfoo) < 0){
                      return errno;
                  }
                  
                  if ( cm_->CmClose ( fd_A) < 0){
                      return errno;
                  }
                  
                  return 0;
              }
              
              virtual int check_test( unsigned int last_checkpoint, DataTestResult *test_result) override {
                  
                  test_path = mnt_dir_ ;
                  A_path =  mnt_dir_ + "/A";
                  AC_path =  mnt_dir_ + "/A/C";
                  B_path =  mnt_dir_ + "/B";
                  Afoo_path =  mnt_dir_ + "/A/foo";
                  Abar_path =  mnt_dir_ + "/A/bar";
                  Bfoo_path =  mnt_dir_ + "/B/foo";
                  Bbar_path =  mnt_dir_ + "/B/bar";
                  ACfoo_path =  mnt_dir_ + "/A/C/foo";
                  ACbar_path =  mnt_dir_ + "/A/C/bar";
                  return 0;
              }
              
              private:
              
              string test_path; 
              string A_path; 
              string AC_path; 
              string B_path; 
              string Afoo_path; 
              string Abar_path; 
              string Bfoo_path; 
              string Bbar_path; 
              string ACfoo_path; 
              string ACbar_path; 
              
          };
          
      }  // namespace tests
  }  // namespace fs_testing
  
  extern "C" fs_testing::tests::BaseTestCase *test_case_get_instance() {
      return new fs_testing::tests::testName;
  }
  
  extern "C" void test_case_delete_instance(fs_testing::tests::BaseTestCase *tc) {
      delete tc;
  }
  