1 // ===========================================================================
2 //
3 // PUBLIC DOMAIN NOTICE
4 // National Center for Biotechnology Information
5 //
6 // This software/database is a "United States Government Work" under the
7 // terms of the United States Copyright Act. It was written as part of
8 // the author's official duties as a United States Government employee and
9 // thus cannot be copyrighted. This software/database is freely available
10 // to the public for use. The National Library of Medicine and the U.S.
11 // Government have not placed any restriction on its use or reproduction.
12 //
13 // Although all reasonable efforts have been taken to ensure the accuracy
14 // and reliability of the software and data, the NLM and the U.S.
15 // Government do not and cannot warrant the performance or results that
16 // may be obtained by using this software or data. The NLM and the U.S.
17 // Government disclaim all warranties, express or implied, including
18 // warranties of performance, merchantability or fitness for any particular
19 // purpose.
20 //
21 // Please cite the author in any work or product based on this material.
22 //
23 // ===========================================================================
24
25 #include <vdb/manager.h> // VDBManager
26 #include <vdb/vdb-priv.h>
27
28 #include <ktst/unit_test.hpp> // TEST_CASE
29 #include <vfs/path.h>
30 #include <vfs/manager.h>
31 #include <klib/text.h>
32 #include <klib/out.h>
33 #include <klib/printf.h>
34 #include <klib/time.h>
35 #include <kfs/directory.h>
36 #include <kfs/file.h>
37 #include <kfg/config.h>
38
39 #include <sysalloc.h>
40 #include <cstdlib>
41 #include <stdexcept>
42
43 using namespace std;
44
45 TEST_SUITE( VDB_3061 )
46
47 const char HomeSub[] = "test_root_history";
48 char new_home[ 4096 ];
49
create_cache_file(KDirectory * dir,const char * path,const char * sub,const char * name,int64_t age_in_seconds)50 static rc_t create_cache_file( KDirectory * dir, const char * path, const char * sub, const char * name,
51 int64_t age_in_seconds )
52 {
53 KFile * f;
54 rc_t rc = KDirectoryCreateFile( dir, &f, false, 0775, kcmInit, "%s/ncbi/%s/%s", path, sub, name );
55 if ( rc == 0 )
56 {
57 KFileRelease( f );
58
59 KTime_t date = KTimeStamp() - age_in_seconds;
60 rc = KDirectorySetDate ( dir, false, date, "%s/ncbi/%s/%s", path, sub, name );
61 }
62 return rc;
63 }
64
create_repo_dirs(KDirectory * dir,const char * path,const char * sub,uint32_t age_in_days,int32_t offset_in_seconds)65 static rc_t create_repo_dirs( KDirectory * dir, const char * path, const char * sub,
66 uint32_t age_in_days, int32_t offset_in_seconds )
67 {
68 rc_t rc = KDirectoryCreateDir( dir, 0775, kcmInit | kcmParents, "%s/ncbi/%s/files", path, sub );
69 if ( rc == 0 )
70 rc = KDirectoryCreateDir( dir, 0775, kcmInit | kcmParents, "%s/ncbi/%s/nannot", path, sub );
71 if ( rc == 0 )
72 rc = KDirectoryCreateDir( dir, 0775, kcmInit | kcmParents, "%s/ncbi/%s/refseq", path, sub );
73 if ( rc == 0 )
74 rc = KDirectoryCreateDir( dir, 0775, kcmInit | kcmParents, "%s/ncbi/%s/sra", path, sub );
75 if ( rc == 0 )
76 rc = KDirectoryCreateDir( dir, 0775, kcmInit | kcmParents, "%s/ncbi/%s/wgs", path, sub );
77 if ( rc == 0 )
78 {
79 int64_t age_in_seconds = age_in_days;
80 age_in_seconds *= ( 60 * 60 * 24 );
81 age_in_seconds += offset_in_seconds;
82 rc = create_cache_file( dir, path, sub, "/sra/file1.txt", age_in_seconds );
83 }
84 return rc;
85 }
86
87
clear_out(const char * path)88 static void clear_out( const char * path )
89 {
90 /* clear the temp. home-directory */
91 KDirectory * dir;
92 rc_t rc = KDirectoryNativeDir( &dir );
93 if ( rc == 0 )
94 {
95 #ifdef WINDOWS
96 rc = KDirectoryRemove( dir, true, "%s", path );
97 #else
98 rc = KDirectoryRemove( dir, true, "%s", path );
99 #endif
100 KDirectoryRelease( dir );
101 }
102 }
103
TEST_CASE(CLEAR_CACHE_1)104 TEST_CASE( CLEAR_CACHE_1 )
105 {
106 REQUIRE_RC( KOutMsg( "running: CLEAR_CACHE_1\n" ) );
107
108 /* create a repository-structure equivalent to the config-values, with 3 files in it */
109 KDirectory * dir;
110 REQUIRE_RC( KDirectoryNativeDir( &dir ) );
111 REQUIRE_RC( create_repo_dirs( dir, new_home, "public", 10, 0 ) ); /* 10 days old */
112 REQUIRE_RC( create_repo_dirs( dir, new_home, "dbGaP-2956", 4, 0 ) ); /* 4 days old */
113 REQUIRE_RC( create_repo_dirs( dir, new_home, "dbGaP-4831", 5, -5 ) ); /* 5 days - 5 seconds old */
114 REQUIRE_RC( KDirectoryRelease ( dir ) );
115
116 /* we run the new function VDBManagerDeleteCacheOlderThan() with a 5-day threshold */
117 const VDBManager * vdb_mgr;
118 REQUIRE_RC( VDBManagerMakeRead( &vdb_mgr, NULL ) );
119 REQUIRE_RC( VDBManagerDeleteCacheOlderThan ( vdb_mgr, 5 ) );
120 REQUIRE_RC( VDBManagerRelease ( vdb_mgr ) );
121
122 /* now the 10 day old one should have disappeared, the other 2 are still there */
123 REQUIRE_RC( KDirectoryNativeDir( &dir ) );
124 uint32_t pt1 = KDirectoryPathType( dir, "%s/ncbi/public/sra/file1.txt", new_home );
125 REQUIRE_EQ( pt1, (uint32_t)kptNotFound );
126 uint32_t pt2 = KDirectoryPathType( dir, "%s/ncbi/dbGaP-2956/sra/file1.txt", new_home );
127 REQUIRE_EQ( pt2, (uint32_t)kptFile );
128 uint32_t pt3 = KDirectoryPathType( dir, "%s/ncbi/dbGaP-4831/sra/file1.txt", new_home );
129 REQUIRE_EQ( pt3, (uint32_t)kptFile );
130 REQUIRE_RC( KDirectoryRelease ( dir ) );
131
132 REQUIRE_RC( KOutMsg( "done: CLEAR_CACHE_1\n" ) );
133 }
134
135
TEST_CASE(CLEAR_CACHE_2)136 TEST_CASE( CLEAR_CACHE_2 )
137 {
138 REQUIRE_RC( KOutMsg( "running: CLEAR_CACHE_2\n" ) );
139
140 REQUIRE_RC( KOutMsg( "clearing: %s\n", new_home ) );
141 clear_out( new_home );
142
143 const VDBManager * vdb_mgr;
144 REQUIRE_RC( VDBManagerMakeRead( &vdb_mgr, NULL ) );
145 REQUIRE_RC( VDBManagerDeleteCacheOlderThan ( vdb_mgr, 0 ) );
146 REQUIRE_RC( VDBManagerRelease ( vdb_mgr ) );
147
148 REQUIRE_RC( KOutMsg( "done: CLEAR_CACHE_2\n" ) );
149 }
150
151
write_root(KConfig * cfg,const char * base,const char * cat,const char * sub_cat)152 static rc_t write_root( KConfig *cfg, const char * base, const char * cat, const char * sub_cat )
153 {
154 char key[ 256 ];
155 size_t num_writ;
156 rc_t rc = string_printf ( key, sizeof key, &num_writ, "/repository/user/%s/%s/root", cat, sub_cat );
157 if ( rc == 0 )
158 {
159 char value[ 256 ];
160 rc = string_printf ( value, sizeof value, &num_writ, "%s/ncbi/%s", base, sub_cat );
161 if ( rc == 0 )
162 rc = KConfigWriteString( cfg, key, value );
163 }
164 return rc;
165 }
166
167
write_dflt_path(KConfig * cfg,const char * base)168 static rc_t write_dflt_path( KConfig *cfg, const char * base )
169 {
170 char value[ 256 ];
171 size_t num_writ;
172 rc_t rc = string_printf ( value, sizeof value, &num_writ, "%s/ncbi", base );
173 if ( rc == 0 )
174 rc = KConfigWriteString( cfg, "/repository/user/default-path", value );
175 return rc;
176 }
177
178 #ifdef WINDOWS
convert_sys_path(const char * sys_path)179 static char * convert_sys_path( const char * sys_path )
180 {
181 char * res = NULL;
182 VFSManager * vfs_mgr;
183 rc_t rc = VFSManagerMake ( &vfs_mgr );
184 if ( rc == 0 )
185 {
186 VPath * p;
187 rc = VFSManagerMakeSysPath ( vfs_mgr, &p, sys_path );
188 if ( rc == 0 )
189 {
190 const String * S;
191 rc = VPathMakeString( p, &S );
192 if ( rc == 0 )
193 res = string_dup ( S->addr, S->size );
194 VPathRelease( p );
195 }
196 VFSManagerRelease( vfs_mgr );
197 }
198 return res;
199 }
200 #endif
201
create_test_config(KConfig ** cfg,const char * base)202 static rc_t create_test_config( KConfig **cfg, const char * base )
203 {
204 rc_t rc = KConfigMake ( cfg, NULL );
205 if ( rc == 0 )
206 {
207 #ifdef WINDOWS
208 const char * cfg_base = convert_sys_path( base );
209 #else
210 const char * cfg_base = base;
211 #endif
212 if ( cfg_base != NULL )
213 {
214 rc = write_root( *cfg, cfg_base, "main", "public" );
215 if ( rc == 0 )
216 rc = write_root( *cfg, cfg_base, "protected", "dbGaP-2956" );
217 if ( rc == 0 )
218 rc = write_root( *cfg, cfg_base, "protected", "dbGaP-4831" );
219 if ( rc == 0 )
220 rc = write_dflt_path( *cfg, cfg_base );
221 #ifdef WINDOWS
222 free( ( void * ) cfg_base );
223 #endif
224 }
225 }
226 return rc;
227 }
228
229 char * org_home;
230 char new_home_buffer[ 4096 ]; /* buffer for putenv has to stay alive! */
231
prepare_test(KConfig ** cfg,const char * sub)232 static rc_t prepare_test( KConfig **cfg, const char * sub )
233 {
234 size_t num_writ;
235 #ifdef WINDOWS
236 org_home = getenv ( "USERPROFILE" );
237 rc_t rc = string_printf ( new_home, sizeof new_home, &num_writ, "%s\\%s", org_home, sub );
238 #else
239 org_home = getenv( "HOME" );
240 rc_t rc = string_printf ( new_home, sizeof new_home, &num_writ, "%s/%s", org_home, sub );
241 #endif
242 if ( rc == 0 )
243 #ifdef WINDOWS
244 rc = string_printf ( new_home_buffer, sizeof new_home_buffer, &num_writ, "HOME=%s", new_home );
245 #else
246 rc = string_printf ( new_home_buffer, sizeof new_home_buffer, &num_writ, "USERPROFILE=%s", new_home );
247 #endif
248 if ( rc == 0 )
249 rc = putenv( new_home_buffer );
250 if ( rc == 0 )
251 rc = create_test_config( cfg, new_home );
252 return rc;
253 }
254
finish_test(const char * sub)255 void finish_test( const char * sub )
256 {
257 /* clear the temp. home-directory */
258 KDirectory * dir;
259 rc_t rc = KDirectoryNativeDir( &dir );
260 if ( rc == 0 )
261 {
262 #ifdef WINDOWS
263 rc = KDirectoryRemove( dir, true, "%s/%s", org_home, sub );
264 #else
265 rc = KDirectoryRemove( dir, true, "%s\\%s", org_home, sub );
266 #endif
267 rc = KDirectoryRemove( dir, true, "%s", new_home );
268 KDirectoryRelease( dir );
269 }
270 }
271
272 //////////////////////////////////////////// Main
273 extern "C"
274 {
275
276 #include <kapp/args.h>
277
KAppVersion(void)278 ver_t CC KAppVersion ( void ) { return 0x1000000; }
UsageSummary(const char * progname)279 rc_t CC UsageSummary ( const char * progname ) { return 0; }
Usage(const Args * args)280 rc_t CC Usage ( const Args * args ) { return 0; }
281 const char UsageDefaultName[] = "test-VDB-3060";
282
KMain(int argc,char * argv[])283 rc_t CC KMain ( int argc, char *argv [] )
284 {
285 KConfigDisableUserSettings();
286 const char HomeSub[] = "test_root_history";
287 KConfig *cfg;
288 rc_t rc = prepare_test( &cfg, HomeSub );
289 if ( rc == 0 )
290 rc = VDB_3061( argc, argv );
291 finish_test( HomeSub );
292 KConfigRelease ( cfg );
293 return rc;
294 }
295
296 }
297