2015-10-15 13:04:57 +02:00
# pragma once
2015-03-16 02:56:40 +01:00
# ifndef MESSMER_FSPP_FSTEST_FSPPDIRTEST_H_
# define MESSMER_FSPP_FSTEST_FSPPDIRTEST_H_
template < class ConcreteFileSystemTestFixture >
class FsppDirTest : public FileSystemTest < ConcreteFileSystemTestFixture > {
2015-03-18 01:46:33 +01:00
public :
void InitDirStructure ( ) {
2018-09-14 02:34:11 -07:00
this - > LoadDir ( " / " ) - > createAndOpenFile ( " myfile " , this - > MODE_PUBLIC , fspp : : uid_t ( 0 ) , fspp : : gid_t ( 0 ) ) ;
this - > LoadDir ( " / " ) - > createDir ( " mydir " , this - > MODE_PUBLIC , fspp : : uid_t ( 0 ) , fspp : : gid_t ( 0 ) ) ;
this - > LoadDir ( " / " ) - > createDir ( " myemptydir " , this - > MODE_PUBLIC , fspp : : uid_t ( 0 ) , fspp : : gid_t ( 0 ) ) ;
this - > LoadDir ( " /mydir " ) - > createAndOpenFile ( " myfile " , this - > MODE_PUBLIC , fspp : : uid_t ( 0 ) , fspp : : gid_t ( 0 ) ) ;
this - > LoadDir ( " /mydir " ) - > createAndOpenFile ( " myfile2 " , this - > MODE_PUBLIC , fspp : : uid_t ( 0 ) , fspp : : gid_t ( 0 ) ) ;
this - > LoadDir ( " /mydir " ) - > createDir ( " mysubdir " , this - > MODE_PUBLIC , fspp : : uid_t ( 0 ) , fspp : : gid_t ( 0 ) ) ;
this - > LoadDir ( " /mydir/mysubdir " ) - > createAndOpenFile ( " myfile " , this - > MODE_PUBLIC , fspp : : uid_t ( 0 ) , fspp : : gid_t ( 0 ) ) ;
this - > LoadDir ( " /mydir/mysubdir " ) - > createDir ( " mysubsubdir " , this - > MODE_PUBLIC , fspp : : uid_t ( 0 ) , fspp : : gid_t ( 0 ) ) ;
2015-03-18 01:46:33 +01:00
}
2015-03-19 03:52:58 +01:00
2015-03-19 04:36:02 +01:00
void EXPECT_CHILDREN_ARE ( const boost : : filesystem : : path & path , const std : : initializer_list < fspp : : Dir : : Entry > expected ) {
2017-01-21 19:18:52 +00:00
EXPECT_CHILDREN_ARE ( this - > LoadDir ( path ) . get ( ) , expected ) ;
2015-03-19 04:36:02 +01:00
}
2016-06-08 12:21:57 -07:00
void EXPECT_CHILDREN_ARE ( fspp : : Dir * dir , const std : : initializer_list < fspp : : Dir : : Entry > expected ) {
2015-03-19 04:24:43 +01:00
std : : vector < fspp : : Dir : : Entry > expectedChildren = expected ;
expectedChildren . push_back ( fspp : : Dir : : Entry ( fspp : : Dir : : EntryType : : DIR , " . " ) ) ;
expectedChildren . push_back ( fspp : : Dir : : Entry ( fspp : : Dir : : EntryType : : DIR , " .. " ) ) ;
2016-06-08 12:21:57 -07:00
EXPECT_UNORDERED_EQ ( expectedChildren , * dir - > children ( ) ) ;
2015-03-19 03:52:58 +01:00
}
2015-03-19 04:24:43 +01:00
template < class Entry >
void EXPECT_UNORDERED_EQ ( const std : : vector < Entry > & expected , std : : vector < Entry > actual ) {
EXPECT_EQ ( expected . size ( ) , actual . size ( ) ) ;
for ( const Entry & expectedEntry : expected ) {
removeOne ( & actual , expectedEntry ) ;
}
2015-03-19 03:52:58 +01:00
}
2015-03-19 04:24:43 +01:00
template < class Entry >
void removeOne ( std : : vector < Entry > * entries , const Entry & toRemove ) {
for ( auto iter = entries - > begin ( ) ; iter ! = entries - > end ( ) ; + + iter ) {
if ( iter - > type = = toRemove . type & & iter - > name = = toRemove . name ) {
entries - > erase ( iter ) ;
return ;
2015-03-19 03:52:58 +01:00
}
}
EXPECT_TRUE ( false ) ;
}
2015-03-16 02:56:40 +01:00
} ;
2019-10-13 19:16:06 +07:00
TYPED_TEST_SUITE_P ( FsppDirTest ) ;
2015-03-16 02:56:40 +01:00
2017-12-01 15:01:49 +00:00
inline fspp : : Dir : : Entry DirEntry ( const std : : string & name ) {
2015-03-19 04:24:43 +01:00
return fspp : : Dir : : Entry ( fspp : : Dir : : EntryType : : DIR , name ) ;
}
2017-12-01 15:01:49 +00:00
inline fspp : : Dir : : Entry FileEntry ( const std : : string & name ) {
2015-03-19 04:24:43 +01:00
return fspp : : Dir : : Entry ( fspp : : Dir : : EntryType : : FILE , name ) ;
}
2015-03-18 01:46:33 +01:00
TYPED_TEST_P ( FsppDirTest , Children_RootDir_Empty ) {
2015-03-19 04:36:02 +01:00
this - > EXPECT_CHILDREN_ARE ( " / " , { } ) ;
2015-03-16 02:56:40 +01:00
}
2015-03-19 04:36:02 +01:00
TYPED_TEST_P ( FsppDirTest , Children_RootDir_OneFile_Directly ) {
2015-03-16 02:56:40 +01:00
auto rootdir = this - > LoadDir ( " / " ) ;
2018-09-14 02:34:11 -07:00
rootdir - > createAndOpenFile ( " myfile " , this - > MODE_PUBLIC , fspp : : uid_t ( 0 ) , fspp : : gid_t ( 0 ) ) ;
2016-06-08 12:21:57 -07:00
this - > EXPECT_CHILDREN_ARE ( rootdir . get ( ) , {
2015-03-19 04:36:02 +01:00
FileEntry ( " myfile " )
} ) ;
}
TYPED_TEST_P ( FsppDirTest , Children_RootDir_OneFile_AfterReloadingDir ) {
2018-09-14 02:34:11 -07:00
this - > LoadDir ( " / " ) - > createAndOpenFile ( " myfile " , this - > MODE_PUBLIC , fspp : : uid_t ( 0 ) , fspp : : gid_t ( 0 ) ) ;
2015-03-19 04:36:02 +01:00
this - > EXPECT_CHILDREN_ARE ( " / " , {
2015-03-19 04:24:43 +01:00
FileEntry ( " myfile " )
} ) ;
2015-03-16 02:56:40 +01:00
}
2015-03-19 04:36:02 +01:00
TYPED_TEST_P ( FsppDirTest , Children_RootDir_OneDir_Directly ) {
2015-03-16 02:56:40 +01:00
auto rootdir = this - > LoadDir ( " / " ) ;
2018-09-14 02:34:11 -07:00
rootdir - > createDir ( " mydir " , this - > MODE_PUBLIC , fspp : : uid_t ( 0 ) , fspp : : gid_t ( 0 ) ) ;
2016-06-08 12:21:57 -07:00
this - > EXPECT_CHILDREN_ARE ( rootdir . get ( ) , {
2015-03-19 04:36:02 +01:00
DirEntry ( " mydir " )
} ) ;
}
TYPED_TEST_P ( FsppDirTest , Children_RootDir_OneDir_AfterReloadingDir ) {
2018-09-14 02:34:11 -07:00
this - > LoadDir ( " / " ) - > createDir ( " mydir " , this - > MODE_PUBLIC , fspp : : uid_t ( 0 ) , fspp : : gid_t ( 0 ) ) ;
2015-03-19 04:36:02 +01:00
this - > EXPECT_CHILDREN_ARE ( " / " , {
2015-03-19 04:24:43 +01:00
DirEntry ( " mydir " )
} ) ;
2015-03-16 02:56:40 +01:00
}
2015-03-18 01:46:33 +01:00
TYPED_TEST_P ( FsppDirTest , Children_RootDir_LargerStructure ) {
this - > InitDirStructure ( ) ;
2015-03-19 04:36:02 +01:00
this - > EXPECT_CHILDREN_ARE ( " / " , {
2015-03-19 04:24:43 +01:00
FileEntry ( " myfile " ) ,
DirEntry ( " mydir " ) ,
DirEntry ( " myemptydir " )
} ) ;
2015-03-18 01:46:33 +01:00
}
TYPED_TEST_P ( FsppDirTest , Children_Nested_Empty ) {
2018-09-14 02:34:11 -07:00
this - > LoadDir ( " / " ) - > createDir ( " myemptydir " , this - > MODE_PUBLIC , fspp : : uid_t ( 0 ) , fspp : : gid_t ( 0 ) ) ;
2015-03-19 04:36:02 +01:00
this - > EXPECT_CHILDREN_ARE ( " /myemptydir " , { } ) ;
2015-03-18 01:46:33 +01:00
}
TYPED_TEST_P ( FsppDirTest , Children_Nested_OneFile_Directly ) {
2018-09-14 02:34:11 -07:00
this - > LoadDir ( " / " ) - > createDir ( " mydir " , this - > MODE_PUBLIC , fspp : : uid_t ( 0 ) , fspp : : gid_t ( 0 ) ) ;
2015-03-16 04:02:45 +01:00
auto dir = this - > LoadDir ( " /mydir " ) ;
2018-09-14 02:34:11 -07:00
dir - > createAndOpenFile ( " myfile " , this - > MODE_PUBLIC , fspp : : uid_t ( 0 ) , fspp : : gid_t ( 0 ) ) ;
2016-06-08 12:21:57 -07:00
this - > EXPECT_CHILDREN_ARE ( dir . get ( ) , {
2015-03-19 04:24:43 +01:00
FileEntry ( " myfile " )
} ) ;
2015-03-16 04:02:45 +01:00
}
2015-03-18 01:46:33 +01:00
TYPED_TEST_P ( FsppDirTest , Children_Nested_OneFile_AfterReloadingDir ) {
2018-09-14 02:34:11 -07:00
this - > LoadDir ( " / " ) - > createDir ( " mydir " , this - > MODE_PUBLIC , fspp : : uid_t ( 0 ) , fspp : : gid_t ( 0 ) ) ;
this - > LoadDir ( " /mydir " ) - > createAndOpenFile ( " myfile " , this - > MODE_PUBLIC , fspp : : uid_t ( 0 ) , fspp : : gid_t ( 0 ) ) ;
2015-03-19 04:36:02 +01:00
this - > EXPECT_CHILDREN_ARE ( " /mydir " , {
2015-03-19 04:24:43 +01:00
FileEntry ( " myfile " )
} ) ;
2015-03-16 04:02:45 +01:00
}
2015-03-18 01:46:33 +01:00
TYPED_TEST_P ( FsppDirTest , Children_Nested_OneDir_Directly ) {
2018-09-14 02:34:11 -07:00
this - > LoadDir ( " / " ) - > createDir ( " mydir " , this - > MODE_PUBLIC , fspp : : uid_t ( 0 ) , fspp : : gid_t ( 0 ) ) ;
2015-03-16 04:02:45 +01:00
auto dir = this - > LoadDir ( " /mydir " ) ;
2018-09-14 02:34:11 -07:00
dir - > createDir ( " mysubdir " , this - > MODE_PUBLIC , fspp : : uid_t ( 0 ) , fspp : : gid_t ( 0 ) ) ;
2016-06-08 12:21:57 -07:00
this - > EXPECT_CHILDREN_ARE ( dir . get ( ) , {
2015-03-19 04:24:43 +01:00
DirEntry ( " mysubdir " )
} ) ;
2015-03-16 04:02:45 +01:00
}
2015-03-18 01:46:33 +01:00
TYPED_TEST_P ( FsppDirTest , Children_Nested_OneDir_AfterReloadingDir ) {
2018-09-14 02:34:11 -07:00
this - > LoadDir ( " / " ) - > createDir ( " mydir " , this - > MODE_PUBLIC , fspp : : uid_t ( 0 ) , fspp : : gid_t ( 0 ) ) ;
this - > LoadDir ( " /mydir " ) - > createDir ( " mysubdir " , this - > MODE_PUBLIC , fspp : : uid_t ( 0 ) , fspp : : gid_t ( 0 ) ) ;
2015-03-19 04:36:02 +01:00
this - > EXPECT_CHILDREN_ARE ( " /mydir " , {
2015-03-19 04:24:43 +01:00
DirEntry ( " mysubdir " )
} ) ;
2015-03-16 04:02:45 +01:00
}
2015-03-18 01:46:33 +01:00
TYPED_TEST_P ( FsppDirTest , Children_Nested_LargerStructure_Empty ) {
this - > InitDirStructure ( ) ;
2015-03-19 04:36:02 +01:00
this - > EXPECT_CHILDREN_ARE ( " /myemptydir " , { } ) ;
2015-03-18 01:46:33 +01:00
}
TYPED_TEST_P ( FsppDirTest , Children_Nested_LargerStructure ) {
this - > InitDirStructure ( ) ;
2015-03-19 04:36:02 +01:00
this - > EXPECT_CHILDREN_ARE ( " /mydir " , {
2015-03-19 04:24:43 +01:00
FileEntry ( " myfile " ) ,
FileEntry ( " myfile2 " ) ,
DirEntry ( " mysubdir " )
} ) ;
2015-03-18 01:46:33 +01:00
}
TYPED_TEST_P ( FsppDirTest , Children_Nested2_LargerStructure ) {
this - > InitDirStructure ( ) ;
2015-03-19 04:36:02 +01:00
this - > EXPECT_CHILDREN_ARE ( " /mydir/mysubdir " , {
2015-03-19 04:24:43 +01:00
FileEntry ( " myfile " ) ,
DirEntry ( " mysubsubdir " )
} ) ;
2015-03-18 01:46:33 +01:00
}
2015-03-19 05:32:09 +01:00
TYPED_TEST_P ( FsppDirTest , CreateAndOpenFile_InEmptyRoot ) {
2018-09-14 02:34:11 -07:00
this - > LoadDir ( " / " ) - > createAndOpenFile ( " myfile " , this - > MODE_PUBLIC , fspp : : uid_t ( 0 ) , fspp : : gid_t ( 0 ) ) ;
2015-03-16 02:56:40 +01:00
this - > LoadFile ( " /myfile " ) ;
2017-01-21 19:16:35 +00:00
this - > Load ( " /myfile " ) ; // Test that we can also load the file node
2015-03-16 02:56:40 +01:00
}
2015-03-19 05:32:09 +01:00
TYPED_TEST_P ( FsppDirTest , CreateAndOpenFile_InNonemptyRoot ) {
this - > InitDirStructure ( ) ;
2018-09-14 02:34:11 -07:00
this - > LoadDir ( " / " ) - > createAndOpenFile ( " mynewfile " , this - > MODE_PUBLIC , fspp : : uid_t ( 0 ) , fspp : : gid_t ( 0 ) ) ;
2015-03-19 05:32:09 +01:00
this - > EXPECT_CHILDREN_ARE ( " / " , {
FileEntry ( " myfile " ) ,
DirEntry ( " mydir " ) ,
DirEntry ( " myemptydir " ) ,
FileEntry ( " mynewfile " )
} ) ;
}
TYPED_TEST_P ( FsppDirTest , CreateAndOpenFile_InEmptyNestedDir ) {
this - > InitDirStructure ( ) ;
2018-09-14 02:34:11 -07:00
this - > LoadDir ( " /myemptydir " ) - > createAndOpenFile ( " mynewfile " , this - > MODE_PUBLIC , fspp : : uid_t ( 0 ) , fspp : : gid_t ( 0 ) ) ;
2015-03-19 05:32:09 +01:00
this - > EXPECT_CHILDREN_ARE ( " /myemptydir " , {
FileEntry ( " mynewfile " )
} ) ;
}
TYPED_TEST_P ( FsppDirTest , CreateAndOpenFile_InNonemptyNestedDir ) {
this - > InitDirStructure ( ) ;
2018-09-14 02:34:11 -07:00
this - > LoadDir ( " /mydir " ) - > createAndOpenFile ( " mynewfile " , this - > MODE_PUBLIC , fspp : : uid_t ( 0 ) , fspp : : gid_t ( 0 ) ) ;
2015-03-19 05:32:09 +01:00
this - > EXPECT_CHILDREN_ARE ( " /mydir " , {
FileEntry ( " myfile " ) ,
FileEntry ( " myfile2 " ) ,
DirEntry ( " mysubdir " ) ,
FileEntry ( " mynewfile " )
} ) ;
}
2015-03-18 01:46:33 +01:00
TYPED_TEST_P ( FsppDirTest , CreateAndOpenFile_AlreadyExisting ) {
2018-09-14 02:34:11 -07:00
this - > LoadDir ( " / " ) - > createAndOpenFile ( " myfile " , this - > MODE_PUBLIC , fspp : : uid_t ( 0 ) , fspp : : gid_t ( 0 ) ) ;
2015-03-18 01:46:33 +01:00
//TODO Change, once we know which way of error reporting we want for such errors
EXPECT_ANY_THROW (
2018-09-14 02:34:11 -07:00
this - > LoadDir ( " / " ) - > createAndOpenFile ( " myfile " , this - > MODE_PUBLIC , fspp : : uid_t ( 0 ) , fspp : : gid_t ( 0 ) ) ;
2015-03-18 01:46:33 +01:00
) ;
}
2015-03-19 05:32:09 +01:00
TYPED_TEST_P ( FsppDirTest , CreateDir_InEmptyRoot ) {
2018-09-14 02:34:11 -07:00
this - > LoadDir ( " / " ) - > createDir ( " mydir " , this - > MODE_PUBLIC , fspp : : uid_t ( 0 ) , fspp : : gid_t ( 0 ) ) ;
2015-03-16 02:56:40 +01:00
this - > LoadDir ( " /mydir " ) ;
2017-01-21 19:16:35 +00:00
this - > Load ( " /mydir " ) ; // Test we can also load the dir node
2015-03-16 02:56:40 +01:00
}
2015-03-19 05:32:09 +01:00
TYPED_TEST_P ( FsppDirTest , CreateDir_InNonemptyRoot ) {
this - > InitDirStructure ( ) ;
2018-09-14 02:34:11 -07:00
this - > LoadDir ( " / " ) - > createDir ( " mynewdir " , this - > MODE_PUBLIC , fspp : : uid_t ( 0 ) , fspp : : gid_t ( 0 ) ) ;
2015-03-19 05:32:09 +01:00
this - > EXPECT_CHILDREN_ARE ( " / " , {
FileEntry ( " myfile " ) ,
DirEntry ( " mydir " ) ,
DirEntry ( " myemptydir " ) ,
DirEntry ( " mynewdir " )
} ) ;
}
TYPED_TEST_P ( FsppDirTest , CreateDir_InEmptyNestedDir ) {
this - > InitDirStructure ( ) ;
2018-09-14 02:34:11 -07:00
this - > LoadDir ( " /myemptydir " ) - > createDir ( " mynewdir " , this - > MODE_PUBLIC , fspp : : uid_t ( 0 ) , fspp : : gid_t ( 0 ) ) ;
2015-03-19 05:32:09 +01:00
this - > EXPECT_CHILDREN_ARE ( " /myemptydir " , {
DirEntry ( " mynewdir " )
} ) ;
}
TYPED_TEST_P ( FsppDirTest , CreateDir_InNonemptyNestedDir ) {
this - > InitDirStructure ( ) ;
2018-09-14 02:34:11 -07:00
this - > LoadDir ( " /mydir " ) - > createDir ( " mynewdir " , this - > MODE_PUBLIC , fspp : : uid_t ( 0 ) , fspp : : gid_t ( 0 ) ) ;
2015-03-19 05:32:09 +01:00
this - > EXPECT_CHILDREN_ARE ( " /mydir " , {
FileEntry ( " myfile " ) ,
FileEntry ( " myfile2 " ) ,
DirEntry ( " mysubdir " ) ,
DirEntry ( " mynewdir " )
} ) ;
}
2015-03-18 01:46:33 +01:00
TYPED_TEST_P ( FsppDirTest , CreateDir_AlreadyExisting ) {
2018-09-14 02:34:11 -07:00
this - > LoadDir ( " / " ) - > createDir ( " mydir " , this - > MODE_PUBLIC , fspp : : uid_t ( 0 ) , fspp : : gid_t ( 0 ) ) ;
2015-03-18 01:46:33 +01:00
//TODO Change, once we know which way of error reporting we want for such errors
EXPECT_ANY_THROW (
2018-09-14 02:34:11 -07:00
this - > LoadDir ( " / " ) - > createDir ( " mydir " , this - > MODE_PUBLIC , fspp : : uid_t ( 0 ) , fspp : : gid_t ( 0 ) ) ;
2015-03-18 01:46:33 +01:00
) ;
}
2016-07-14 16:12:51 +02:00
TYPED_TEST_P ( FsppDirTest , Remove ) {
2017-01-21 19:18:52 +00:00
this - > CreateDir ( " /mytestdir " ) ;
EXPECT_NE ( boost : : none , this - > device - > Load ( " /mytestdir " ) ) ;
EXPECT_NE ( boost : : none , this - > device - > LoadDir ( " /mytestdir " ) ) ;
this - > Load ( " /mytestdir " ) - > remove ( ) ;
EXPECT_EQ ( boost : : none , this - > device - > Load ( " /mytestdir " ) ) ;
EXPECT_EQ ( boost : : none , this - > device - > LoadDir ( " /mytestdir " ) ) ;
2016-07-14 16:12:51 +02:00
}
TYPED_TEST_P ( FsppDirTest , Remove_Nested ) {
2017-01-21 19:18:52 +00:00
this - > CreateDir ( " /mytestdir " ) ;
this - > CreateDir ( " /mytestdir/mydir " ) ;
EXPECT_NE ( boost : : none , this - > device - > Load ( " /mytestdir/mydir " ) ) ;
EXPECT_NE ( boost : : none , this - > device - > LoadDir ( " /mytestdir/mydir " ) ) ;
this - > Load ( " /mytestdir/mydir " ) - > remove ( ) ;
EXPECT_EQ ( boost : : none , this - > device - > Load ( " /mytestdir/mydir " ) ) ;
EXPECT_EQ ( boost : : none , this - > device - > LoadDir ( " /mytestdir/mydir " ) ) ;
2016-07-14 16:12:51 +02:00
}
2019-10-13 19:16:06 +07:00
REGISTER_TYPED_TEST_SUITE_P ( FsppDirTest ,
2015-03-18 01:46:33 +01:00
Children_RootDir_Empty ,
2015-03-19 04:36:02 +01:00
Children_RootDir_OneFile_Directly ,
Children_RootDir_OneFile_AfterReloadingDir ,
Children_RootDir_OneDir_Directly ,
Children_RootDir_OneDir_AfterReloadingDir ,
2015-03-18 01:46:33 +01:00
Children_RootDir_LargerStructure ,
Children_Nested_Empty ,
Children_Nested_OneFile_Directly ,
Children_Nested_OneFile_AfterReloadingDir ,
Children_Nested_OneDir_Directly ,
Children_Nested_OneDir_AfterReloadingDir ,
Children_Nested_LargerStructure ,
Children_Nested_LargerStructure_Empty ,
Children_Nested2_LargerStructure ,
2015-03-19 05:32:09 +01:00
CreateAndOpenFile_InEmptyRoot ,
CreateAndOpenFile_InNonemptyRoot ,
CreateAndOpenFile_InEmptyNestedDir ,
CreateAndOpenFile_InNonemptyNestedDir ,
2015-03-18 01:46:33 +01:00
CreateAndOpenFile_AlreadyExisting ,
2015-03-19 05:32:09 +01:00
CreateDir_InEmptyRoot ,
CreateDir_InNonemptyRoot ,
CreateDir_InEmptyNestedDir ,
CreateDir_InNonemptyNestedDir ,
2016-07-14 16:12:51 +02:00
CreateDir_AlreadyExisting ,
Remove ,
Remove_Nested
2015-03-16 02:56:40 +01:00
) ;
2016-03-24 07:55:37 +00:00
2016-02-17 13:13:03 +01:00
//TODO rmdir (also test that deleting a non-empty dir returns ENOTEMPTY, because otherwise there might not be any unlink syscalls for the entries issued)
2015-04-25 03:36:30 +02:00
//TODO mkdir with uid/gid
2016-03-23 18:03:30 +00:00
//TODO createAndOpenFile: all stat values correctly set (1. in the OpenFile instance returned from createAndOpenFile and 2. on an lstat on the file object afterwards)
//TODO Test all operations do (or don't) affect dir timestamps correctly
2015-03-19 05:38:00 +01:00
2015-03-16 02:56:40 +01:00
# endif