1 /***********************************************************************************************************************************
2 Storage Test Harness
3 
4 Helper functions for testing storage and related functions.
5 ***********************************************************************************************************************************/
6 #ifndef TEST_COMMON_HARNESS_STORAGE_H
7 #define TEST_COMMON_HARNESS_STORAGE_H
8 
9 #include "common/compress/helper.h"
10 #include "common/crypto/common.h"
11 #include "storage/storage.intern.h"
12 
13 /***********************************************************************************************************************************
14 Get a file and test it against the specified content
15 ***********************************************************************************************************************************/
16 typedef struct TestStorageGetParam
17 {
18     VAR_PARAM_HEADER;
19     bool remove;                                                    // Remove file after testing?
20     CompressType compressType;                                      // Compression extension added to file name (limited gz and bz2)
21     CipherType cipherType;
22     const char *cipherPass;                                         // If pass=null but cipherType set, defaults to TEST_CIPHER_PASS
23     const char *comment;                                            // Comment
24 } TestStorageGetParam;
25 
26 #define TEST_STORAGE_GET(storage, file, expected, ...)                                                                             \
27     do                                                                                                                             \
28     {                                                                                                                              \
29         hrnTestLogPrefix(__LINE__);                                                                                                \
30         testStorageGet(storage, file, expected, (TestStorageGetParam){VAR_PARAM_INIT, __VA_ARGS__});                               \
31     }                                                                                                                              \
32     while (0)
33 
34 #define TEST_STORAGE_GET_EMPTY(storage, file, ...)                                                                                 \
35     TEST_STORAGE_GET(storage, file, "", __VA_ARGS__)
36 
37 void testStorageGet(
38     const Storage *const storage, const char *const file, const char *const expected, const TestStorageGetParam param);
39 
40 /***********************************************************************************************************************************
41 Check file exists
42 ***********************************************************************************************************************************/
43 typedef struct TestStorageExistsParam
44 {
45     VAR_PARAM_HEADER;
46     bool remove;                                                    // Remove file after testing?
47     const char *comment;                                            // Comment
48 } TestStorageExistsParam;
49 
50 #define TEST_STORAGE_EXISTS(storage, file, ...)                                                                                    \
51     do                                                                                                                             \
52     {                                                                                                                              \
53         hrnTestLogPrefix(__LINE__);                                                                                                \
54         testStorageExists(storage, file, (TestStorageExistsParam){VAR_PARAM_INIT, __VA_ARGS__});                                   \
55     }                                                                                                                              \
56     while (0)
57 
58 void testStorageExists(const Storage *const storage, const char *const file, const TestStorageExistsParam param);
59 
60 /***********************************************************************************************************************************
61 List files in a path and optionally remove them
62 ***********************************************************************************************************************************/
63 typedef struct HrnStorageListParam
64 {
65     VAR_PARAM_HEADER;
66     bool remove;                                                    // Remove files after testing?
67     bool noRecurse;                                                 // Do not recurse into subdirectories
68     const char *expression;                                         // Filter the list based on expression
69     const char *comment;                                            // Comment
70 } HrnStorageListParam;
71 
72 #define TEST_STORAGE_LIST(storage, path, expected, ...)                                                                            \
73     do                                                                                                                             \
74     {                                                                                                                              \
75         hrnTestLogPrefix(__LINE__);                                                                                                \
76         hrnStorageList(storage, path, expected, (HrnStorageListParam){VAR_PARAM_INIT, __VA_ARGS__});                               \
77     }                                                                                                                              \
78     while (0)
79 
80 #define TEST_STORAGE_LIST_EMPTY(storage, path, ...)                                                                                \
81     TEST_STORAGE_LIST(storage, path, NULL, __VA_ARGS__)
82 
83 void hrnStorageList(
84     const Storage *const storage, const char *const path, const char *const expected, const HrnStorageListParam param);
85 
86 /***********************************************************************************************************************************
87 Change the mode of a path/file
88 ***********************************************************************************************************************************/
89 typedef struct HrnStorageModeParam
90 {
91     VAR_PARAM_HEADER;
92     mode_t mode;                                                    // Mode to set -- reset to default if not provided
93     const char *comment;                                            // Comment
94 } HrnStorageModeParam;
95 
96 #define HRN_STORAGE_MODE(storage, path, ...)                                                                                       \
97     do                                                                                                                             \
98     {                                                                                                                              \
99         hrnTestLogPrefix(__LINE__);                                                                                                \
100         hrnStorageMode(storage, path, (HrnStorageModeParam){VAR_PARAM_INIT, __VA_ARGS__});                                         \
101     }                                                                                                                              \
102     while (0)
103 
104 void hrnStorageMode(const Storage *const storage, const char *const path, HrnStorageModeParam param);
105 
106 /***********************************************************************************************************************************
107 Move a file
108 ***********************************************************************************************************************************/
109 typedef struct HrnStorageMoveParam
110 {
111     VAR_PARAM_HEADER;
112     const char *comment;                                            // Comment
113 } HrnStorageMoveParam;
114 
115 #define HRN_STORAGE_MOVE(storage, fileSource, fileDest, ...)                                                                       \
116     do                                                                                                                             \
117     {                                                                                                                              \
118         hrnTestLogPrefix(__LINE__);                                                                                                \
119         hrnStorageMove(storage, fileSource, fileDest, (HrnStorageMoveParam){VAR_PARAM_INIT, __VA_ARGS__});                         \
120     }                                                                                                                              \
121     while (0)
122 
123 void hrnStorageMove(
124     const Storage *const storage, const char *const fileSource, const char *const fileDest, HrnStorageMoveParam param);
125 
126 /***********************************************************************************************************************************
127 Copy a file
128 ***********************************************************************************************************************************/
129 typedef struct HrnStorageCopyParam
130 {
131     VAR_PARAM_HEADER;
132     const char *comment;                                            // Comment
133 } HrnStorageCopyParam;
134 
135 #define HRN_STORAGE_COPY(storageSource, fileSource, storageDest, fileDest, ...)                                                    \
136     do                                                                                                                             \
137     {                                                                                                                              \
138         hrnTestLogPrefix(__LINE__);                                                                                                \
139         hrnStorageCopy(storageSource, fileSource, storageDest, fileDest, (HrnStorageCopyParam){VAR_PARAM_INIT, __VA_ARGS__});      \
140     }                                                                                                                              \
141     while (0)
142 
143 void hrnStorageCopy(
144     const Storage *const storageSource, const char *const fileSource, const Storage *const storageDest, const char *const fileDest,
145     HrnStorageCopyParam param);
146 
147 /***********************************************************************************************************************************
148 Create a path
149 ***********************************************************************************************************************************/
150 typedef struct HrnStoragePathCreateParam
151 {
152     VAR_PARAM_HEADER;
153     mode_t mode;                                                    // Path mode (defaults to STORAGE_MODE_PATH_DEFAULT)
154     bool noErrorOnExists;                                           // Do not error if the path already exists
155     bool noParentCreate;                                            // Do not attempt to create the parent path (it must exist)
156     const char *comment;                                            // Comment
157 } HrnStoragePathCreateParam;
158 
159 #define HRN_STORAGE_PATH_CREATE(storage, path, ...)                                                                                \
160     do                                                                                                                             \
161     {                                                                                                                              \
162         hrnTestLogPrefix(__LINE__);                                                                                                \
163         hrnStoragePathCreate(storage, path, (HrnStoragePathCreateParam){VAR_PARAM_INIT, __VA_ARGS__});                             \
164     }                                                                                                                              \
165     while (0)
166 
167 void hrnStoragePathCreate(const Storage *const storage, const char *const path, HrnStoragePathCreateParam param);
168 
169 /***********************************************************************************************************************************
170 Remove a path
171 ***********************************************************************************************************************************/
172 typedef struct HrnStoragePathRemoveParam
173 {
174     VAR_PARAM_HEADER;
175     bool errorOnMissing;                                            // Error if the path is missing
176     bool recurse;                                                   // Delete the path and all subpaths/files
177     const char *comment;                                            // Comment
178 } HrnStoragePathRemoveParam;
179 
180 #define HRN_STORAGE_PATH_REMOVE(storage, path, ...)                                                                                \
181     do                                                                                                                             \
182     {                                                                                                                              \
183         hrnTestLogPrefix(__LINE__);                                                                                                \
184         hrnStoragePathRemove(storage, path, (HrnStoragePathRemoveParam){VAR_PARAM_INIT, __VA_ARGS__});                             \
185     }                                                                                                                              \
186     while (0)
187 
188 void hrnStoragePathRemove(const Storage *const storage, const char *const path, HrnStoragePathRemoveParam param);
189 
190 /***********************************************************************************************************************************
191 Put a file with optional compression and/or encryption
192 ***********************************************************************************************************************************/
193 typedef struct HrnStoragePutParam
194 {
195     VAR_PARAM_HEADER;
196     mode_t modeFile;                                                // File mode if not the default
197     time_t timeModified;                                            // Time file was last modified
198     CompressType compressType;                                      // Limited to gz and bz2 (lz4 and zstd are not always available)
199     CipherType cipherType;
200     const char *cipherPass;
201     const char *comment;                                            // Comment
202 } HrnStoragePutParam;
203 
204 #define HRN_STORAGE_PUT(storage, file, buffer, ...)                                                                                \
205     do                                                                                                                             \
206     {                                                                                                                              \
207         hrnTestLogPrefix(__LINE__);                                                                                                \
208         hrnStoragePut(storage, file, buffer, NULL, (HrnStoragePutParam){VAR_PARAM_INIT, __VA_ARGS__});                             \
209     }                                                                                                                              \
210     while (0)
211 
212 #define HRN_STORAGE_PUT_EMPTY(storage, file, ...)                                                                                  \
213     HRN_STORAGE_PUT(storage, file, NULL, __VA_ARGS__)
214 
215 #define HRN_STORAGE_PUT_Z(storage, file, stringz, ...)                                                                             \
216     HRN_STORAGE_PUT(storage, file, BUFSTRZ(stringz), __VA_ARGS__)
217 
218 void hrnStoragePut(
219     const Storage *const storage, const char *const file, const Buffer *const buffer, const char *const logPrefix,
220     HrnStoragePutParam param);
221 
222 /***********************************************************************************************************************************
223 Remove a file
224 ***********************************************************************************************************************************/
225 typedef struct HrnStorageRemoveParam
226 {
227     VAR_PARAM_HEADER;
228     bool errorOnMissing;                                            // Error when the file is missing
229     const char *comment;                                            // Comment
230 } HrnStorageRemoveParam;
231 
232 #define HRN_STORAGE_REMOVE(storage, file, ...)                                                                                     \
233     do                                                                                                                             \
234     {                                                                                                                              \
235         hrnTestLogPrefix(__LINE__);                                                                                                \
236         hrnStorageRemove(storage, file, (HrnStorageRemoveParam){VAR_PARAM_INIT, __VA_ARGS__});                                     \
237     }                                                                                                                              \
238     while (0)
239 
240 void hrnStorageRemove(const Storage *const storage, const char *const file, const HrnStorageRemoveParam param);
241 
242 /***********************************************************************************************************************************
243 Change the time of a path/file
244 ***********************************************************************************************************************************/
245 typedef struct HrnStorageTimeParam
246 {
247     VAR_PARAM_HEADER;
248     const char *comment;                                            // Comment
249 } HrnStorageTimeParam;
250 
251 #define HRN_STORAGE_TIME(storage, path, time, ...)                                                                                 \
252     do                                                                                                                             \
253     {                                                                                                                              \
254         hrnTestLogPrefix(__LINE__);                                                                                                \
255         hrnStorageTime(storage, path, time, (HrnStorageTimeParam){VAR_PARAM_INIT, __VA_ARGS__});                                   \
256     }                                                                                                                              \
257     while (0)
258 
259 void hrnStorageTime(const Storage *const storage, const char *const path, const time_t modified, const HrnStorageTimeParam param);
260 
261 /***********************************************************************************************************************************
262 Dummy interface for constructing test storage drivers. All required functions are stubbed out so this interface can be copied and
263 specific functions replaced for testing.
264 ***********************************************************************************************************************************/
265 extern const StorageInterface storageInterfaceTestDummy;
266 
267 /***********************************************************************************************************************************
268 Callback for formatting info list results
269 ***********************************************************************************************************************************/
270 typedef struct HarnessStorageInfoListCallbackData
271 {
272     const Storage *storage;                                         // Storage object when needed (e.g. fileCompressed = true)
273     const String *path;                                             // subpath when storage is specified
274 
275     String *content;                                                // String where content should be added
276     bool modeOmit;                                                  // Should the specified mode be omitted?
277     mode_t modeFile;                                                // File to omit if modeOmit is true
278     mode_t modePath;                                                // Path mode to omit if modeOmit is true
279     bool timestampOmit;                                             // Should the timestamp be omitted?
280     bool userOmit;                                                  // Should the current user be omitted?
281     bool groupOmit;                                                 // Should the current group be omitted?
282     bool sizeOmit;                                                  // Should the size be omitted
283     bool rootPathOmit;                                              // Should the root path be omitted?
284     bool fileCompressed;                                            // Files will be decompressed to get size
285 } HarnessStorageInfoListCallbackData;
286 
287 void hrnStorageInfoListCallback(void *callbackData, const StorageInfo *info);
288 
289 #endif
290