1 /**
2  * @file   vfs_helpers.h
3  *
4  * @section LICENSE
5  *
6  * The MIT License
7  *
8  * @copyright Copyright (c) 2020-2021 TileDB, Inc.
9  *
10  * Permission is hereby granted, free of charge, to any person obtaining a copy
11  * of this software and associated documentation files (the "Software"), to deal
12  * in the Software without restriction, including without limitation the rights
13  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14  * copies of the Software, and to permit persons to whom the Software is
15  * furnished to do so, subject to the following conditions:
16  *
17  * The above copyright notice and this permission notice shall be included in
18  * all copies or substantial portions of the Software.
19  *
20  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
23  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
26  * THE SOFTWARE.
27  *
28  * @section DESCRIPTION
29  *
30  * This file declares some vfs-specfic test suite helper functions.
31  */
32 
33 #ifndef TILEDB_VFS_HELPERS_H
34 #define TILEDB_VFS_HELPERS_H
35 
36 #include "test/src/helpers.h"
37 
38 #ifdef _WIN32
39 #include "tiledb/sm/filesystem/win.h"
40 #else
41 #include "tiledb/sm/filesystem/posix.h"
42 #endif
43 
44 namespace tiledb {
45 namespace test {
46 
47 // Forward declaration
48 class SupportedFs;
49 
50 /**
51  * Create the vector of supported filesystems.
52  */
53 std::vector<std::unique_ptr<SupportedFs>> vfs_test_get_fs_vec();
54 
55 /**
56  * Initialize the vfs test.
57  *
58  * @param fs_vec The vector of supported filesystems
59  * @param ctx The TileDB context.
60  * @param vfs The VFS object.
61  * @param config An optional configuration argument.
62  */
63 Status vfs_test_init(
64     const std::vector<std::unique_ptr<SupportedFs>>& fs_vec,
65     tiledb_ctx_t** ctx,
66     tiledb_vfs_t** vfs,
67     tiledb_config_t* config = nullptr);
68 
69 /**
70  * Close the vfs test.
71  *
72  * @param fs_vec The vector of supported filesystems
73  * @param ctx The TileDB context.
74  * @param vfs The VFS object.
75  */
76 Status vfs_test_close(
77     const std::vector<std::unique_ptr<SupportedFs>>& fs_vec,
78     tiledb_ctx_t* ctx,
79     tiledb_vfs_t* vfs);
80 
81 /**
82  * This class defines and manipulates
83  * a list of supported filesystems.
84  */
85 class SupportedFs {
86  public:
87   virtual ~SupportedFs() = default;
88 
89   /* ********************************* */
90   /*               API                 */
91   /* ********************************* */
92 
93   /**
94    * Returns Status upon setting up the associated
95    * filesystem's configuration
96    * Only for S3, Azure
97    * No-op otherwise
98    *
99    * @param config Configuration parameters
100    * @param error Error parameter
101    * @return Status OK if successful
102    */
103   virtual Status prepare_config(
104       tiledb_config_t* config, tiledb_error_t* error) = 0;
105 
106   /**
107    * Creates bucket / container if does not exist
108    * Only for S3, Azure
109    * No-op otherwise
110    *
111    * @param ctx The TileDB context.
112    * @param vfs The VFS object.
113    * @return Status OK if successful
114    */
115   virtual Status init(tiledb_ctx_t* ctx, tiledb_vfs_t* vfs) = 0;
116 
117   /**
118    * Removes bucket / container if exists
119    * Only for S3, Azure
120    * No-op otherwise
121    *
122    * @param ctx The TileDB context.
123    * @param vfs The VFS object.
124    * @return Status OK if successful
125    */
126   virtual Status close(tiledb_ctx_t* ctx, tiledb_vfs_t* vfs) = 0;
127 
128   /**
129    * Get the name of the filesystem's directory
130    *
131    * @return string directory name
132    */
133   virtual std::string temp_dir() = 0;
134 };
135 
136 /**
137  * This class provides support for
138  * the S3 filesystem.
139  */
140 class SupportedFsS3 : public SupportedFs {
141  public:
SupportedFsS3()142   SupportedFsS3()
143       : s3_prefix_("s3://")
144       , s3_bucket_(s3_prefix_ + random_name("tiledb") + "/")
145       , temp_dir_(s3_bucket_ + "tiledb_test/") {
146   }
147 
148   ~SupportedFsS3() = default;
149 
150   /* ********************************* */
151   /*               API                 */
152   /* ********************************* */
153 
154   /**
155    * Returns Status upon setting up the associated
156    * filesystem's configuration
157    *
158    * @param config Configuration parameters
159    * @param error Error parameter
160    * @return Status OK if successful
161    */
162   virtual Status prepare_config(tiledb_config_t* config, tiledb_error_t* error);
163 
164   /**
165    * Creates bucket if does not exist
166    *
167    * @param ctx The TileDB context.
168    * @param vfs The VFS object.
169    * @return Status OK if successful
170    */
171   virtual Status init(tiledb_ctx_t* ctx, tiledb_vfs_t* vfs);
172 
173   /**
174    * Removes bucket if exists
175    *
176    * @param ctx The TileDB context.
177    * @param vfs The VFS object.
178    * @return Status OK if successful
179    */
180   virtual Status close(tiledb_ctx_t* ctx, tiledb_vfs_t* vfs);
181 
182   /**
183    * Get the name of the filesystem's directory
184    *
185    * @return string directory name
186    */
187   virtual std::string temp_dir();
188 
189  private:
190   /* ********************************* */
191   /*           ATTRIBUTES              */
192   /* ********************************* */
193 
194   /** The directory prefix of the S3 filesystem. */
195   const std::string s3_prefix_;
196 
197   /** The bucket name for the S3 filesystem. */
198   const std::string s3_bucket_;
199 
200   /** The directory name of the S3 filesystem. */
201   std::string temp_dir_;
202 };
203 
204 /**
205  * This class provides support for
206  * the HDFS filesystem.
207  */
208 class SupportedFsHDFS : public SupportedFs {
209  public:
SupportedFsHDFS()210   SupportedFsHDFS()
211       : temp_dir_("hdfs:///tiledb_test/") {
212   }
213 
214   ~SupportedFsHDFS() = default;
215 
216   /* ********************************* */
217   /*               API                 */
218   /* ********************************* */
219 
220   /**
221    * No-op
222    *
223    * @param config Configuration parameters
224    * @param error Error parameter
225    * @return Status OK if successful
226    */
227   virtual Status prepare_config(tiledb_config_t* config, tiledb_error_t* error);
228 
229   /**
230    * No-op
231    *
232    * @param ctx The TileDB context.
233    * @param vfs The VFS object.
234    * @return Status OK if successful
235    */
236   virtual Status init(tiledb_ctx_t* ctx, tiledb_vfs_t* vfs);
237 
238   /**
239    * No-op
240    *
241    * @param ctx The TileDB context.
242    * @param vfs The VFS object.
243    * @return Status OK if successful
244    */
245   virtual Status close(tiledb_ctx_t* ctx, tiledb_vfs_t* vfs);
246 
247   /**
248    * Get the name of the filesystem's directory
249    *
250    * @return string directory name
251    */
252   virtual std::string temp_dir();
253 
254  private:
255   /* ********************************* */
256   /*           ATTRIBUTES              */
257   /* ********************************* */
258 
259   /** The directory name of the HDFS filesystem. */
260   std::string temp_dir_;
261 };
262 
263 /**
264  * This class provides support for
265  * the Azure filesystem.
266  */
267 class SupportedFsAzure : public SupportedFs {
268  public:
SupportedFsAzure()269   SupportedFsAzure()
270       : azure_prefix_("azure://")
271       , container_(azure_prefix_ + random_name("tiledb") + "/")
272       , temp_dir_(container_ + "tiledb_test/") {
273   }
274 
275   ~SupportedFsAzure() = default;
276 
277   /* ********************************* */
278   /*               API                 */
279   /* ********************************* */
280 
281   /**
282    * Returns Status upon setting up the associated
283    * filesystem's configuration
284    *
285    * @param config Configuration parameters
286    * @param error Error parameter
287    * @return Status OK if successful
288    */
289   virtual Status prepare_config(tiledb_config_t* config, tiledb_error_t* error);
290 
291   /**
292    * Creates container if does not exist
293    *
294    * @param ctx The TileDB context.
295    * @param vfs The VFS object.
296    * @return Status OK if successful
297    */
298   virtual Status init(tiledb_ctx_t* ctx, tiledb_vfs_t* vfs);
299 
300   /**
301    * Removes container if exists
302    *
303    * @param ctx The TileDB context.
304    * @param vfs The VFS object.
305    * @return Status OK if successful
306    */
307   virtual Status close(tiledb_ctx_t* ctx, tiledb_vfs_t* vfs);
308 
309   /**
310    * Get the name of the filesystem's directory
311    *
312    * @return string directory name
313    */
314   virtual std::string temp_dir();
315 
316  private:
317   /* ********************************* */
318   /*           ATTRIBUTES              */
319   /* ********************************* */
320 
321   /** The directory prefix of the Azure filesystem. */
322   const std::string azure_prefix_;
323 
324   /** The container name for the Azure filesystem. */
325   const std::string container_;
326 
327   /** The directory name of the Azure filesystem. */
328   std::string temp_dir_;
329 };
330 
331 /**
332  * This class provides support for the GCS filesystem.
333  */
334 class SupportedFsGCS : public SupportedFs {
335  public:
SupportedFsGCS()336   SupportedFsGCS()
337       : prefix_("gcs://")
338       , bucket_(prefix_ + random_name("tiledb") + "/")
339       , temp_dir_(bucket_ + "tiledb_test/") {
340   }
341 
342   ~SupportedFsGCS() = default;
343 
344   /* ********************************* */
345   /*               API                 */
346   /* ********************************* */
347 
348   /**
349    * Returns Status upon setting up the associated
350    * filesystem's configuration
351    *
352    * @param config Configuration parameters
353    * @param error Error parameter
354    * @return Status OK if successful
355    */
356   virtual Status prepare_config(tiledb_config_t* config, tiledb_error_t* error);
357 
358   /**
359    * Creates bucket if does not exist
360    *
361    * @param ctx The TileDB context.
362    * @param vfs The VFS object.
363    * @return Status OK if successful
364    */
365   virtual Status init(tiledb_ctx_t* ctx, tiledb_vfs_t* vfs);
366 
367   /**
368    * Removes bucket if exists
369    *
370    * @param ctx The TileDB context.
371    * @param vfs The VFS object.
372    * @return Status OK if successful
373    */
374   virtual Status close(tiledb_ctx_t* ctx, tiledb_vfs_t* vfs);
375 
376   /**
377    * Get the name of the filesystem's directory
378    *
379    * @return string directory name
380    */
381   virtual std::string temp_dir();
382 
383  private:
384   /* ********************************* */
385   /*           ATTRIBUTES              */
386   /* ********************************* */
387 
388   /** The directory prefix of the GCS filesystem. */
389   const std::string prefix_;
390 
391   /** The bucket name for the GCS filesystem. */
392   const std::string bucket_;
393 
394   /** The directory name of the GCS filesystem. */
395   std::string temp_dir_;
396 };
397 
398 /**
399  * This class provides support for
400  * the Windows or Posix (local) filesystem.
401  */
402 class SupportedFsLocal : public SupportedFs {
403  public:
404 #ifdef _WIN32
SupportedFsLocal()405   SupportedFsLocal()
406       : temp_dir_(tiledb::sm::Win::current_dir() + "\\tiledb_test\\")
407       , file_prefix_("") {
408   }
409 #else
410   SupportedFsLocal()
411       : temp_dir_(tiledb::sm::Posix::current_dir() + "/tiledb_test/")
412       , file_prefix_("file://") {
413   }
414 #endif
415 
416   ~SupportedFsLocal() = default;
417 
418   /* ********************************* */
419   /*               API                 */
420   /* ********************************* */
421 
422   /**
423    * No-op
424    *
425    * @param config Configuration parameters
426    * @param error Error parameter
427    * @return Status OK if successful
428    */
429   virtual Status prepare_config(tiledb_config_t* config, tiledb_error_t* error);
430 
431   /**
432    * No-op
433    *
434    * @param ctx The TileDB context.
435    * @param vfs The VFS object.
436    * @return Status OK if successful
437    */
438   virtual Status init(tiledb_ctx_t* ctx, tiledb_vfs_t* vfs);
439 
440   /**
441    * No-op
442    *
443    * @param ctx The TileDB context.
444    * @param vfs The VFS object.
445    * @return Status OK if successful
446    */
447   virtual Status close(tiledb_ctx_t* ctx, tiledb_vfs_t* vfs);
448 
449   /**
450    * Get the name of the filesystem's directory
451    *
452    * @return string directory name
453    */
454   virtual std::string temp_dir();
455 
456   /**
457    * Get the name of the filesystem's file prefix
458    *
459    * @return string prefix name
460    */
461   std::string file_prefix();
462 
463  private:
464   /* ********************************* */
465   /*           ATTRIBUTES              */
466   /* ********************************* */
467 
468 #ifdef _WIN32
469   /** The directory name of the Windows filesystem. */
470   std::string temp_dir_;
471 
472   /** The file prefix name of the Windows filesystem. */
473   std::string file_prefix_;
474 
475 #else
476   /** The directory name of the Posix filesystem. */
477   std::string temp_dir_;
478 
479   /** The file prefix name of the Posix filesystem. */
480   std::string file_prefix_;
481 #endif
482 };
483 
484 /**
485  * This class provides support for
486  * the Mem filesystem.
487  */
488 class SupportedFsMem : public SupportedFs {
489  public:
SupportedFsMem()490   SupportedFsMem()
491       : temp_dir_("mem://tiledb_test/") {
492   }
493 
494   ~SupportedFsMem() = default;
495 
496   /* ********************************* */
497   /*               API                 */
498   /* ********************************* */
499 
500   /**
501    * Returns Status upon setting up the associated
502    * filesystem's configuration
503    *
504    * @param config Configuration parameters
505    * @param error Error parameter
506    * @return Status OK if successful
507    */
508   virtual Status prepare_config(tiledb_config_t* config, tiledb_error_t* error);
509 
510   /**
511    * Creates container if does not exist
512    *
513    * @param ctx The TileDB context.
514    * @param vfs The VFS object.
515    * @return Status OK if successful
516    */
517   virtual Status init(tiledb_ctx_t* ctx, tiledb_vfs_t* vfs);
518 
519   /**
520    * Removes container if exists
521    *
522    * @param ctx The TileDB context.
523    * @param vfs The VFS object.
524    * @return Status OK if successful
525    */
526   virtual Status close(tiledb_ctx_t* ctx, tiledb_vfs_t* vfs);
527 
528   /**
529    * Get the name of the filesystem's directory
530    *
531    * @return string directory name
532    */
533   virtual std::string temp_dir();
534 
535  private:
536   /* ********************************* */
537   /*           ATTRIBUTES              */
538   /* ********************************* */
539 
540   /** The directory name of the Mem filesystem. */
541   std::string temp_dir_;
542 };
543 
544 }  // End of namespace test
545 }  // End of namespace tiledb
546 
547 #endif
548