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 <kdb/manager.h> // KDBManager
27 #include <kdb/kdb-priv.h>
28 #include <vdb/vdb-priv.h>
29 
30 #include <ktst/unit_test.hpp> // TEST_CASE
31 #include <vfs/path.h>
32 #include <vfs/manager.h>
33 #include <klib/text.h>
34 #include <klib/out.h>
35 #include <klib/printf.h>
36 #include <kfs/directory.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_3060 )
46 
47 std::string original_value = std::string( "" );
48 
49 const VDBManager * vdb_mgr = NULL;
50 VFSManager * vfs_mgr = NULL;
51 
make_global_managers(void)52 static rc_t make_global_managers( void )
53 {
54     rc_t rc = VDBManagerMakeRead( &vdb_mgr, NULL );
55     if ( rc != 0 )
56         std::cout << "VDB-3060.VdbFixture: VDBManagerMakeRead() failed" << std::endl;
57     else
58     {
59         rc = VFSManagerMake ( &vfs_mgr );
60         if ( rc != 0 )
61             std::cout << "VdbFixture: VFSManagerMake() failed" << std::endl;
62     }
63     return rc;
64 }
65 
release_global_managers(void)66 static void release_global_managers( void )
67 {
68     VFSManagerRelease ( vfs_mgr );
69     VDBManagerRelease ( vdb_mgr );
70 }
71 
72 
73 /*
74     test VDBManagerGetCacheRoot() with invalid and valid parameters
75     print the currently stored value
76     store this value in the global: original_value
77 */
TEST_CASE(GetCacheRoot_1)78 TEST_CASE( GetCacheRoot_1 )
79 {
80     VPath const * vpath = NULL;
81     rc_t rc = VDBManagerGetCacheRoot( NULL, &vpath );
82     if ( rc == 0 )
83         FAIL( "FAIL: VDBManagerGetCacheRoot( NULL, &vpath ) succeed" );
84     rc = VDBManagerGetCacheRoot( vdb_mgr, NULL );
85     if ( rc == 0 )
86         FAIL( "FAIL: VDBManagerGetCacheRoot( mgr, NULL ) succeed" );
87     rc = VDBManagerGetCacheRoot( vdb_mgr, &vpath );
88     if ( rc != 0 )
89         FAIL( "FAIL: VDBManagerGetCacheRoot( mgr, &vpath ) failed" );
90     if ( vpath == NULL )
91         FAIL( "FAIL: VDBManagerGetCacheRoot( mgr, &vpath ) returned vpath == NULL " );
92 
93     String const * spath = NULL;
94     rc = VPathMakeString ( vpath, &spath );
95     if ( rc != 0 )
96         FAIL( "FAIL: VPathMakeString( vpath, &spatch ) failed" );
97 
98     original_value = std::string( spath->addr, spath->size );
99     std::cout << "original value: " << original_value << std::endl;
100 
101     if ( spath != NULL )
102         StringWhack( spath );
103 
104     if ( vpath != NULL )
105         VPathRelease( vpath );
106 }
107 
108 const char other_path[] = "/some/other/path";
109 
110 /*
111     test VDBManagerSetCacheRoot() with invalid and valid parameters
112     set the value to "/home/user/somepath"
113 */
TEST_CASE(SetCacheRoot_1)114 TEST_CASE( SetCacheRoot_1 )
115 {
116     rc_t rc = VDBManagerSetCacheRoot( vdb_mgr, NULL );
117     if ( rc == 0 )
118         FAIL( "FAIL: VDBManagerSetCacheRoot( mgr, NULL ) succeed" );
119 
120     VPath * vpath;
121     rc = VFSManagerMakePath ( vfs_mgr, &vpath, other_path );
122     if ( rc != 0 )
123         FAIL( "FAIL: VFSManagerMakePath() failed" );
124 
125     rc = VDBManagerSetCacheRoot( NULL, vpath );
126     if ( rc == 0 )
127         FAIL( "FAIL: VDBManagerSetCacheRoot( NULL, vpath ) succeed" );
128 
129     rc = VDBManagerSetCacheRoot( vdb_mgr, vpath );
130     if ( rc != 0 )
131         FAIL( "FAIL: VDBManagerSetCacheRoot( mgr, vpath ) failed" );
132 
133     if ( vpath != NULL )
134         VPathRelease( vpath );
135 }
136 
137 
138 /*
139     call VDBManagerGetCacheRoot() to verify that the new value
140     is indeed the value we did set in the test-case above
141 */
TEST_CASE(GetCacheRoot_2)142 TEST_CASE( GetCacheRoot_2 )
143 {
144     VPath const * vpath = NULL;
145     rc_t rc = VDBManagerGetCacheRoot( vdb_mgr, &vpath );
146     if ( rc != 0 )
147         FAIL( "FAIL: VDBManagerGetCacheRoot( mgr, &vpath ) failed" );
148     if ( vpath == NULL )
149         FAIL( "FAIL: VDBManagerGetCacheRoot( mgr, &vpath ) returned vpath == NULL " );
150 
151     String const * spath = NULL;
152     rc = VPathMakeString ( vpath, &spath );
153     if ( rc != 0 )
154         FAIL( "FAIL: VPathMakeString( vpath, &spatch ) failed" );
155 
156     std::string s1 = std::string( spath->addr, spath->size );
157     std::string s2 = std::string( other_path );
158     std::cout << "after setting different value: " << s1;
159     if ( s1 == s2 )
160         std::cout << " - as expected" << std::endl;
161     else
162     {
163         std::cout << " - we did not expected this!" << std::endl;
164         FAIL( "FAIL: unexpected value after setting a new cache-root" );
165     }
166 
167     if ( spath != NULL )
168         StringWhack( spath );
169 
170     if ( vpath != NULL )
171         VPathRelease( vpath );
172 }
173 
174 
175 /*
176     put the value stored in the global 'original_value' back in place
177 */
TEST_CASE(SetCacheRoot_2)178 TEST_CASE( SetCacheRoot_2 )
179 {
180     VPath * vpath;
181     rc_t rc = VFSManagerMakePath ( vfs_mgr, &vpath, original_value.c_str() );
182     if ( rc != 0 )
183         FAIL( "FAIL: VFSManagerMakePath() failed" );
184 
185     rc = VDBManagerSetCacheRoot( vdb_mgr, vpath );
186     if ( rc != 0 )
187         FAIL( "FAIL: VDBManagerSetCacheRoot( mgr, vpath ) failed" );
188 
189     if ( vpath != NULL )
190         VPathRelease( vpath );
191 }
192 
193 
194 /*
195     check if the original value is back in place
196 */
TEST_CASE(GetCacheRoot_3)197 TEST_CASE( GetCacheRoot_3 )
198 {
199     VPath const * vpath = NULL;
200     rc_t rc = VDBManagerGetCacheRoot( vdb_mgr, &vpath );
201     if ( rc != 0 )
202         FAIL( "FAIL: VDBManagerGetCacheRoot( mgr, &vpath ) failed" );
203     if ( vpath == NULL )
204         FAIL( "FAIL: VDBManagerGetCacheRoot( mgr, &vpath ) returned vpath == NULL " );
205 
206     String const * spath = NULL;
207     rc = VPathMakeString ( vpath, &spath );
208     if ( rc != 0 )
209         FAIL( "FAIL: VPathMakeString( vpath, &spath ) failed" );
210 
211     std::string s = std::string( spath->addr, spath->size );
212     std::cout << "reverted to original value of: " << s << std::endl;
213 
214     if ( s != original_value )
215         FAIL( "FAIL: did not restore original value" );
216 
217     if ( spath != NULL )
218         StringWhack( spath );
219 
220     if ( vpath != NULL )
221         VPathRelease( vpath );
222 }
223 
TEST_CASE(two_managers)224 TEST_CASE( two_managers )
225 {
226     const VDBManager * vdb_mgr2 = NULL;
227     VPath const * vpath1 = NULL;
228     VPath const * vpath2 = NULL;
229     VPath * vpath_new = NULL;
230     String const * spath1 = NULL;
231     String const * spath2 = NULL;
232     rc_t rc;
233 
234     rc = VFSManagerMakePath ( vfs_mgr, &vpath_new, "something_different" );
235     if ( rc != 0 )
236         FAIL( "FAIL: VFSManagerMakePath( vpath_new ) failed" );
237 
238     rc = VDBManagerMakeRead( &vdb_mgr2, NULL );
239     if ( rc != 0 )
240         FAIL( "FAIL: VDBManagerMakeRead( &vdb_mgr2 ) failed" );
241 
242     rc = VDBManagerSetCacheRoot( vdb_mgr2, vpath_new );
243     if ( rc != 0 )
244         FAIL( "FAIL: VDBManagerSetCacheRoot( vdb_mgr, vpath_new ) failed" );
245 
246     rc = VDBManagerGetCacheRoot( vdb_mgr, &vpath1 );
247     if ( rc != 0 )
248         FAIL( "FAIL: VDBManagerGetCacheRoot( vdb_mgr, &vpath1 ) failed" );
249 
250     rc = VDBManagerGetCacheRoot( vdb_mgr2, &vpath2 );
251     if ( rc != 0 )
252         FAIL( "FAIL: VDBManagerGetCacheRoot( vdb_mgr1, &vpath2 ) failed" );
253 
254     rc = VPathMakeString ( vpath1, &spath1 );
255     if ( rc != 0 )
256         FAIL( "FAIL: VPathMakeString( vpath1, &spath1 ) failed" );
257 
258     rc = VPathMakeString ( vpath2, &spath2 );
259     if ( rc != 0 )
260         FAIL( "FAIL: VPathMakeString( vpath2, &spath2 ) failed" );
261 
262     std::string s1 = std::string( spath1->addr, spath1->size );
263     std::string s2 = std::string( spath2->addr, spath2->size );
264     if ( s1 != s2 )
265         FAIL( "FAIL: cache-root values do not match" );
266     else
267         std::cout << "cache-root values are the same" << std::endl;
268 
269     if ( spath1 != NULL ) StringWhack( spath1 );
270     if ( spath2 != NULL ) StringWhack( spath2 );
271     if ( vpath_new != NULL ) VPathRelease( vpath_new );
272     if ( vpath1 != NULL ) VPathRelease( vpath1 );
273     if ( vpath2 != NULL ) VPathRelease( vpath2 );
274     if ( vdb_mgr2 != NULL ) VDBManagerRelease ( vdb_mgr2 );
275 }
276 
TEST_CASE(root_tmp)277 TEST_CASE( root_tmp )
278 {
279     std::cout << "testing root-tmp" << std::endl;
280 
281     const KDBManager * kdb_mgr = NULL;
282     rc_t rc = VDBManagerGetKDBManagerRead( vdb_mgr, &kdb_mgr) ;
283     if ( rc != 0 )
284         FAIL( "FAIL: VDBManagerGetKDBManagerRead() failed" );
285 
286     VFSManager * vfs_mgr_1 = NULL;
287     rc = KDBManagerGetVFSManager( kdb_mgr, &vfs_mgr_1 );
288     if ( rc != 0 )
289         FAIL( "FAIL: KDBManagerGetVFSManager() failed" );
290 
291     VPath * vpath = NULL;
292     rc = VFSManagerMakeSysPath( vfs_mgr_1, &vpath, "/tmp1" );
293     if ( rc != 0 )
294         FAIL( "FAIL: VFSManagerMakeSysPath() failed" );
295 
296     rc = VDBManagerSetCacheRoot( vdb_mgr, vpath );
297     if ( rc != 0 )
298         FAIL( "FAIL: VDBManagerSetCacheRoot( mgr, vpath ) failed" );
299 
300     if ( vpath != NULL ) VPathRelease( vpath );
301     if ( vfs_mgr_1 != NULL ) VFSManagerRelease ( vfs_mgr_1 );
302     if ( kdb_mgr != NULL ) KDBManagerRelease ( kdb_mgr );
303 
304 }
305 
306 char * org_home;
307 const char HomeSub[] = "test_root_history";
308 char new_home[ 1024 ];
309 char new_home_buffer[ 1024 ]; /* buffer for putenv has to stay alive! */
310 
311 
write_root(KConfig * cfg,const char * base,const char * cat,const char * sub_cat)312 rc_t write_root( KConfig *cfg, const char * base, const char * cat, const char * sub_cat )
313 {
314     char key[ 256 ];
315     size_t num_writ;
316     rc_t rc = string_printf ( key, sizeof key, &num_writ, "/repository/user/%s/%s/root", cat, sub_cat );
317     if ( rc == 0 )
318     {
319         char value[ 256 ];
320         rc = string_printf ( value, sizeof value, &num_writ, "%s/ncbi/%s", base, sub_cat );
321         if ( rc == 0 )
322             rc = KConfigWriteString( cfg, key, value );
323     }
324     return rc;
325 }
326 
327 
write_dflt_path(KConfig * cfg,const char * base)328 rc_t write_dflt_path( KConfig *cfg, const char * base )
329 {
330     char value[ 256 ];
331     size_t num_writ;
332     rc_t rc = string_printf ( value, sizeof value, &num_writ, "%s/ncbi", base );
333     if ( rc == 0 )
334         rc = KConfigWriteString( cfg, "/repository/user/default-path", value );
335     return rc;
336 }
337 
create_test_config(const char * base)338 rc_t create_test_config( const char * base )
339 {
340     KConfig *cfg;
341     rc_t rc = KConfigMake ( &cfg, NULL );
342     if ( rc == 0 )
343     {
344         rc = write_root( cfg, base, "main", "public" );
345         if ( rc == 0 )
346             rc = write_root( cfg, base, "protected", "dbGaP-2956" );
347         if ( rc == 0 )
348             rc = write_root( cfg, base, "protected", "dbGaP-4831" );
349         if ( rc == 0 )
350             rc = write_dflt_path( cfg, base );
351         if ( rc == 0 )
352             rc = KConfigCommit ( cfg );
353         KConfigRelease ( cfg );
354     }
355     return rc;
356 }
357 
prepare_test(const char * sub)358 rc_t prepare_test( const char * sub )
359 {
360     org_home = getenv( "HOME" );
361     size_t num_writ;
362     rc_t rc = string_printf ( new_home, sizeof new_home, &num_writ, "%s/%s", org_home, sub );
363     if ( rc == 0 )
364         rc = string_printf ( new_home_buffer, sizeof new_home_buffer, &num_writ, "HOME=%s", new_home );
365     if ( rc == 0 )
366         rc = putenv( new_home_buffer );
367     if ( rc == 0 )
368         rc = create_test_config( org_home );
369     return rc;
370 }
371 
finish_test()372 void finish_test()
373 {
374     /* clear the temp. home-directory */
375     KDirectory * dir;
376     rc_t rc = KDirectoryNativeDir( &dir );
377     if ( rc == 0 )
378     {
379         rc = KDirectoryRemove( dir, true, "%s/%s", org_home, HomeSub );
380         KDirectoryRelease( dir );
381     }
382 }
383 
384 //////////////////////////////////////////// Main
385 extern "C"
386 {
387 
388 #include <kapp/args.h>
389 
KAppVersion(void)390 ver_t CC KAppVersion ( void ) { return 0x1000000; }
UsageSummary(const char * progname)391 rc_t CC UsageSummary ( const char * progname ) { return 0; }
Usage(const Args * args)392 rc_t CC Usage ( const Args * args ) { return 0; }
393 const char UsageDefaultName[] = "test-VDB-3060";
394 
KMain(int argc,char * argv[])395 rc_t CC KMain ( int argc, char *argv [] )
396 {
397     rc_t rc = prepare_test( HomeSub );
398     if ( rc == 0 )
399     {
400         rc = make_global_managers();
401         if ( rc == 0 )
402         {
403             rc = VDB_3060( argc, argv );
404             release_global_managers();
405         }
406     }
407     finish_test();
408     return rc;
409 }
410 
411 }
412