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