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 *  Unit tests for KDirectoryCreateLink
25 */
26 
27 #include <kfs/directory.h> /* KDirectoryRelease */
28 #include <kfs/file.h> /* KFileRelease */
29 
30 #include <ktst/unit_test.hpp> /* TEST_SUITE */
31 
32 #include <string>
33 
34 using std::string;
35 
36 TEST_SUITE(LinkSuite)
37 
38 #define DIR "tmp"
39 #define DIR2 "tmp2"
40 
41 struct Fixture {
42     KDirectory * wd;
43 
FixtureFixture44     Fixture() : wd(NULL) {
45         rc_t rc = KDirectoryNativeDir(&wd);
46         if (rc != 0)
47             throw rc;
48 
49         rc = Clean();
50         if (rc != 0)
51             throw rc;
52     }
53 
~FixtureFixture54     ~Fixture() { assert(!wd); }
55 
CompareFixture56     rc_t Compare(const string & src, const char * dest) {
57         const KFile * fn = NULL;
58         rc_t rc = KDirectoryOpenFileRead(wd, &fn, dest);
59         if (rc != 0)
60             return rc;
61 
62         char in[99] = "";
63         size_t num_read = 0;
64         rc = KFileRead(fn, 0, in, sizeof in, &num_read);
65         if (rc != 0)
66             return rc;
67 
68         if (string(in) != src)
69             return 69;
70 
71         return KFileRelease(fn);
72     }
73 
FiniFixture74     rc_t Fini() {
75         rc_t rc = Clean();
76 
77         rc_t r2 = KDirectoryRelease(wd);
78         if (r2 != 0 && rc == 0)
79             rc = r2;
80         wd = NULL;
81 
82         return rc;
83     }
84 
85 private:
CleanFixture86     rc_t Clean() {
87         rc_t rc = KDirectoryRemove(wd, true, DIR);
88         if (rc != 0)
89             return rc;
90 
91         return KDirectoryRemove(wd, true, DIR2);
92     }
93 };
94 
FIXTURE_TEST_CASE(Test_Link,Fixture)95 FIXTURE_TEST_CASE(Test_Link, Fixture) {
96     const KFile * fn = NULL;
97 #define NEW "l"
98 
99     // link files do not exist
100     REQUIRE_RC_FAIL(KDirectoryOpenFileRead(wd, &fn, "%s/%s", DIR, NEW));
101     REQUIRE_RC_FAIL(KDirectoryOpenFileRead(wd, &fn, "%s/%s", DIR2, NEW));
102 
103     // create a next file
104 #define NXT "n"
105     KFile * f2 = NULL;
106     REQUIRE_RC(KDirectoryCreateFile(wd, &f2, false, 0660, kcmParents,
107         "%s/%s", DIR, NXT));
108 
109     // create src file
110 #define OLD "f"
111     KFile * fo = NULL;
112     REQUIRE_RC(KDirectoryCreateFile(wd, &fo, false, 0660, kcmParents,
113         "%s/%s", DIR, OLD));
114     const char out[] = "0123456789\n";
115     REQUIRE_RC(KFileWrite(fo, 0, out, sizeof out, NULL));
116 
117     // create link in the same directory
118     REQUIRE_RC(KDirectoryCreateLink(wd, 0, 0, DIR "/" OLD, DIR "/" NEW));
119     REQUIRE_RC(Compare(out, DIR "/" NEW));
120 
121     // cannot create link to existing file
122     REQUIRE_RC_FAIL(KDirectoryCreateLink(wd, 0, 0, DIR "/" OLD, DIR "/" NXT));
123 
124     // cannot create link in non-existing directory without kcmParents
125     REQUIRE_RC_FAIL(KDirectoryCreateLink(wd, 0, 0, DIR "/" OLD, "/9"));
126     REQUIRE_RC_FAIL(KDirectoryCreateLink(wd, 0, 0, DIR "/" OLD,
127         DIR2 "/" NEW));
128 
129     // create link in a different directory
130     REQUIRE_RC(KDirectoryCreateLink(wd, 0770, kcmParents, DIR "/" OLD,
131         DIR2 "/" NEW));
132     REQUIRE_RC(Compare(out, DIR2 "/" NEW));
133 
134     REQUIRE_RC(KFileRelease(f2));
135     REQUIRE_RC(KFileRelease(fo));
136 
137     REQUIRE_RC(Fini());
138 }
139 
140 extern "C" {
KAppVersion(void)141     ver_t CC KAppVersion(void) { return 0; }
KMain(int argc,char * argv[])142     rc_t CC KMain(int argc, char *argv[]) {
143         return LinkSuite(argc, argv);
144     }
145 }
146