Kinetica   C#   API  Version 7.2.3.1
KifsFileHandlerTests.cs
Go to the documentation of this file.
1 using System;
2 using System.Collections.Generic;
3 using System.IO;
4 using System.Text;
5 using Xunit;
6 using kinetica;
7 using kinetica.FileSystem;
8 
9 namespace Kinetica.Tests
10 {
14  [Trait("Category", "Integration")]
15  public class KifsFileHandlerTests : IDisposable
16  {
17  private const string ConnectionUrl = "http://localhost:9191";
18  private const string Username = "admin";
19  private const string Password = "secret";
20  private const string TestDirName = "kifs_test_dir";
21 
22  private readonly kinetica.Kinetica _kdb;
23  private readonly KineticaFileHandler _fileHandler;
24  private readonly string _tempDir;
25 
27  {
28  _kdb = new kinetica.Kinetica(ConnectionUrl, new kinetica.Kinetica.Options()
29  {
30  Username = Username,
31  Password = Password
32  });
33  _fileHandler = new KineticaFileHandler(_kdb);
34  _tempDir = Path.Combine(Path.GetTempPath(), $"kifs_test_{Guid.NewGuid():N}");
35  Directory.CreateDirectory(_tempDir);
36  }
37 
38  public void Dispose()
39  {
40  // Clean up test directory
41  try { _fileHandler.DeleteDirectory(TestDirName, true, true); } catch { }
42 
43  // Clean up temp directory
44  if (Directory.Exists(_tempDir))
45  {
46  try { Directory.Delete(_tempDir, true); } catch { }
47  }
48  }
49 
50  #region Directory Tests
51 
52  [Fact]
54  {
55  // Arrange
56  try { _fileHandler.DeleteDirectory(TestDirName); } catch { }
57 
58  // Act
59  _fileHandler.CreateDirectory(TestDirName);
60 
61  // Assert
62  Assert.True(_fileHandler.KifsDirectoryExists(TestDirName));
63  }
64 
65  [Fact]
67  {
68  // Arrange
69  try { _fileHandler.DeleteDirectory(TestDirName); } catch { }
70  _fileHandler.CreateDirectory(TestDirName);
71 
72  // Act & Assert - should not throw
73  _fileHandler.CreateDirectory(TestDirName, noErrorIfExists: true);
74  Assert.True(_fileHandler.KifsDirectoryExists(TestDirName));
75  }
76 
77  [Fact]
79  {
80  // Arrange
81  try { _fileHandler.DeleteDirectory(TestDirName); } catch { }
82  _fileHandler.CreateDirectory(TestDirName);
83  Assert.True(_fileHandler.KifsDirectoryExists(TestDirName));
84 
85  // Act
86  _fileHandler.DeleteDirectory(TestDirName);
87 
88  // Assert
89  Assert.False(_fileHandler.KifsDirectoryExists(TestDirName));
90  }
91 
92  [Fact]
94  {
95  // Arrange
96  try { _fileHandler.DeleteDirectory(TestDirName); } catch { }
97  _fileHandler.CreateDirectory(TestDirName);
98 
99  // Act
100  var directories = _fileHandler.ShowAllDirectories();
101 
102  // Assert
103  Assert.NotNull(directories);
104  Assert.Contains(directories, d => d.KifsPath == TestDirName);
105  }
106 
107  [Fact]
109  {
110  // Arrange
111  try { _fileHandler.DeleteDirectory(TestDirName); } catch { }
112  _fileHandler.CreateDirectory(TestDirName);
113 
114  // Act
115  var directories = _fileHandler.ShowDirectory(TestDirName);
116 
117  // Assert
118  Assert.NotNull(directories);
119  Assert.Single(directories);
120  Assert.Equal(TestDirName, directories[0].KifsPath);
121  Assert.NotEmpty(directories[0].CreatedBy);
122  }
123 
124  [Fact]
126  {
127  // Arrange
128  try { _fileHandler.DeleteDirectory(TestDirName); } catch { }
129  _fileHandler.CreateDirectory(TestDirName);
130 
131  // Act & Assert
132  Assert.True(_fileHandler.KifsDirectoryExists(TestDirName));
133  }
134 
135  [Fact]
137  {
138  // Arrange
139  try { _fileHandler.DeleteDirectory(TestDirName); } catch { }
140 
141  // Act & Assert
142  Assert.False(_fileHandler.KifsDirectoryExists("non_existing_dir_" + Guid.NewGuid().ToString("N")));
143  }
144 
145  #endregion
146 
147  #region Upload Tests
148 
149  [Fact]
151  {
152  // Arrange
153  try { _fileHandler.DeleteDirectory(TestDirName); } catch { }
154  _fileHandler.CreateDirectory(TestDirName);
155 
156  var testFileName = "test_upload.txt";
157  var testFilePath = Path.Combine(_tempDir, testFileName);
158  File.WriteAllText(testFilePath, "Hello, KiFS!");
159 
160  // Act
161  _fileHandler.Upload(testFilePath, TestDirName);
162 
163  // Assert
164  var remoteFilePath = $"{TestDirName}/{testFileName}";
165  Assert.True(_fileHandler.KifsFileExists(remoteFilePath));
166  }
167 
168  [Fact]
170  {
171  // Arrange
172  try { _fileHandler.DeleteDirectory(TestDirName); } catch { }
173  _fileHandler.CreateDirectory(TestDirName);
174 
175  var testFiles = new List<string>();
176  for (int i = 1; i <= 3; i++)
177  {
178  var fileName = $"test_upload_{i}.txt";
179  var filePath = Path.Combine(_tempDir, fileName);
180  File.WriteAllText(filePath, $"Content for file {i}");
181  testFiles.Add(filePath);
182  }
183 
184  // Act
185  _fileHandler.Upload(testFiles, TestDirName);
186 
187  // Assert
188  foreach (var filePath in testFiles)
189  {
190  var fileName = Path.GetFileName(filePath);
191  var remoteFilePath = $"{TestDirName}/{fileName}";
192  Assert.True(_fileHandler.KifsFileExists(remoteFilePath));
193  }
194  }
195 
196  [Fact]
198  {
199  // Arrange
200  try { _fileHandler.DeleteDirectory(TestDirName); } catch { }
201  _fileHandler.CreateDirectory(TestDirName);
202 
203  var testFileName = "test_callback.txt";
204  var testFilePath = Path.Combine(_tempDir, testFileName);
205  File.WriteAllText(testFilePath, "Hello, Callback!");
206 
207  var callback = new TestUploadListener();
208 
209  // Act
210  _fileHandler.Upload(testFilePath, TestDirName, UploadOptions.Default, callback);
211 
212  // Assert
213  Assert.True(callback.FullFileUploadCalled);
214  }
215 
216  [Fact]
218  {
219  // Arrange
220  try { _fileHandler.DeleteDirectory(TestDirName); } catch { }
221  _fileHandler.CreateDirectory(TestDirName);
222 
223  // Act & Assert
224  Assert.Throws<KineticaException>(() =>
225  _fileHandler.Upload("/non/existent/file.txt", TestDirName));
226  }
227 
228  [Fact]
230  {
231  // Arrange
232  var testFilePath = Path.Combine(_tempDir, "test.txt");
233  File.WriteAllText(testFilePath, "Test");
234 
235  // Act & Assert
236  Assert.Throws<KineticaException>(() =>
237  _fileHandler.Upload(testFilePath, "non_existent_dir_" + Guid.NewGuid().ToString("N")));
238  }
239 
240  #endregion
241 
242  #region Download Tests
243 
244  [Fact]
246  {
247  // Arrange
248  try { _fileHandler.DeleteDirectory(TestDirName); } catch { }
249  _fileHandler.CreateDirectory(TestDirName);
250 
251  var testFileName = "test_download.txt";
252  var uploadPath = Path.Combine(_tempDir, testFileName);
253  var expectedContent = "Hello, Download!";
254  File.WriteAllText(uploadPath, expectedContent);
255  _fileHandler.Upload(uploadPath, TestDirName);
256 
257  var downloadDir = Path.Combine(_tempDir, "downloads");
258  Directory.CreateDirectory(downloadDir);
259 
260  // Act
261  var remoteFilePath = $"{TestDirName}/{testFileName}";
262  _fileHandler.Download(remoteFilePath, downloadDir);
263 
264  // Assert
265  var downloadedPath = Path.Combine(downloadDir, testFileName);
266  Assert.True(File.Exists(downloadedPath));
267  Assert.Equal(expectedContent, File.ReadAllText(downloadedPath));
268  }
269 
270  [Fact]
272  {
273  // Arrange
274  try { _fileHandler.DeleteDirectory(TestDirName); } catch { }
275  _fileHandler.CreateDirectory(TestDirName);
276 
277  var testFiles = new List<string>();
278  for (int i = 1; i <= 3; i++)
279  {
280  var fileName = $"test_download_{i}.txt";
281  var filePath = Path.Combine(_tempDir, fileName);
282  File.WriteAllText(filePath, $"Content for file {i}");
283  _fileHandler.Upload(filePath, TestDirName);
284  testFiles.Add($"{TestDirName}/{fileName}");
285  }
286 
287  var downloadDir = Path.Combine(_tempDir, "downloads_multi");
288  Directory.CreateDirectory(downloadDir);
289 
290  // Act
291  _fileHandler.Download(testFiles, downloadDir);
292 
293  // Assert
294  foreach (var remoteFile in testFiles)
295  {
296  var fileName = Path.GetFileName(remoteFile);
297  var downloadedPath = Path.Combine(downloadDir, fileName);
298  Assert.True(File.Exists(downloadedPath));
299  }
300  }
301 
302  [Fact]
304  {
305  // Arrange
306  try { _fileHandler.DeleteDirectory(TestDirName); } catch { }
307  _fileHandler.CreateDirectory(TestDirName);
308 
309  var testFileName = "test_overwrite.txt";
310  var uploadPath = Path.Combine(_tempDir, testFileName);
311  File.WriteAllText(uploadPath, "Original content");
312  _fileHandler.Upload(uploadPath, TestDirName);
313 
314  var downloadDir = Path.Combine(_tempDir, "downloads_overwrite");
315  Directory.CreateDirectory(downloadDir);
316  var existingFile = Path.Combine(downloadDir, testFileName);
317  File.WriteAllText(existingFile, "Existing content");
318 
319  // Act & Assert
320  var remoteFilePath = $"{TestDirName}/{testFileName}";
321  var options = new DownloadOptions(overwriteExisting: false);
322 
323  Assert.Throws<KineticaException>(() =>
324  _fileHandler.Download(remoteFilePath, downloadDir, options, null));
325  }
326 
327  #endregion
328 
329  #region File Operations Tests
330 
331  [Fact]
333  {
334  // Arrange
335  try { _fileHandler.DeleteDirectory(TestDirName); } catch { }
336  _fileHandler.CreateDirectory(TestDirName);
337 
338  var testFileName = "test_show.txt";
339  var testContent = "Show files test content";
340  var uploadPath = Path.Combine(_tempDir, testFileName);
341  File.WriteAllText(uploadPath, testContent);
342  _fileHandler.Upload(uploadPath, TestDirName);
343 
344  // Act
345  var files = _fileHandler.ShowFiles(new List<string> { TestDirName });
346 
347  // Assert
348  Assert.NotNull(files);
349  Assert.NotEmpty(files);
350  Assert.Contains(files, f => f.FileName.EndsWith(testFileName));
351 
352  var testFile = files[0];
353  Assert.True(testFile.FileSize > 0);
354  Assert.NotEmpty(testFile.CreatedBy);
355  }
356 
357  [Fact]
359  {
360  // Arrange
361  try { _fileHandler.DeleteDirectory(TestDirName); } catch { }
362  _fileHandler.CreateDirectory(TestDirName);
363 
364  var testFileName = "test_delete.txt";
365  var uploadPath = Path.Combine(_tempDir, testFileName);
366  File.WriteAllText(uploadPath, "Delete test");
367  _fileHandler.Upload(uploadPath, TestDirName);
368 
369  var remoteFilePath = $"{TestDirName}/{testFileName}";
370  Assert.True(_fileHandler.KifsFileExists(remoteFilePath));
371 
372  // Act
373  _fileHandler.DeleteFiles(new List<string> { remoteFilePath });
374 
375  // Assert
376  Assert.False(_fileHandler.KifsFileExists(remoteFilePath));
377  }
378 
379  [Fact]
381  {
382  // Arrange
383  try { _fileHandler.DeleteDirectory(TestDirName); } catch { }
384  _fileHandler.CreateDirectory(TestDirName);
385 
386  for (int i = 1; i <= 3; i++)
387  {
388  var fileName = $"test_delete_all_{i}.txt";
389  var filePath = Path.Combine(_tempDir, fileName);
390  File.WriteAllText(filePath, $"Content {i}");
391  _fileHandler.Upload(filePath, TestDirName);
392  }
393 
394  var files = _fileHandler.ShowFiles(new List<string> { TestDirName });
395  Assert.Equal(3, files.Count);
396 
397  // Act
398  _fileHandler.DeleteFilesInDirectory(TestDirName);
399 
400  // Assert
401  files = _fileHandler.ShowFiles(new List<string> { TestDirName });
402  Assert.Empty(files);
403  }
404 
405  [Fact]
407  {
408  // Arrange
409  try { _fileHandler.DeleteDirectory(TestDirName); } catch { }
410  _fileHandler.CreateDirectory(TestDirName);
411 
412  var testFileName = "test_exists.txt";
413  var uploadPath = Path.Combine(_tempDir, testFileName);
414  File.WriteAllText(uploadPath, "Exists test");
415  _fileHandler.Upload(uploadPath, TestDirName);
416 
417  // Act & Assert
418  var remoteFilePath = $"{TestDirName}/{testFileName}";
419  Assert.True(_fileHandler.KifsFileExists(remoteFilePath));
420  }
421 
422  [Fact]
424  {
425  // Arrange
426  try { _fileHandler.DeleteDirectory(TestDirName); } catch { }
427  _fileHandler.CreateDirectory(TestDirName);
428 
429  // Act & Assert
430  Assert.False(_fileHandler.KifsFileExists($"{TestDirName}/non_existing_file.txt"));
431  }
432 
433  #endregion
434 
435  #region Options Tests
436 
437  [Fact]
439  {
440  // Act
441  var options = new KineticaFileHandler.Options();
442 
443  // Assert
444  Assert.Equal(KineticaFileHandler.DefaultFileSizeToSplit, options.FileSizeToSplit);
445  Assert.Equal(KineticaFileHandler.DefaultThreadPoolSize, options.ThreadPoolSize);
446  Assert.Equal(100, options.MaxFilesPerBatch);
447  }
448 
449  [Fact]
451  {
452  // Act
453  var options = UploadOptions.Default;
454 
455  // Assert
456  Assert.True(options.Recursive);
457  Assert.Equal(-1, options.Ttl);
458  Assert.False(options.DeleteIfExists);
459  }
460 
461  [Fact]
463  {
464  // Act
465  var options = DownloadOptions.Default;
466 
467  // Assert
468  Assert.True(options.OverwriteExisting);
469  }
470 
471  #endregion
472 
473  #region Helper Classes
474 
475  private class TestUploadListener : IFileUploadListener
476  {
477  public bool MultiPartUploadCompleteCalled { get; private set; }
478  public bool PartUploadCalled { get; private set; }
479  public bool FullFileUploadCalled { get; private set; }
480  public List<FileOperationResult> Results { get; } = new List<FileOperationResult>();
481 
482  public void OnMultiPartUploadComplete(IList<FileOperationResult> results)
483  {
484  MultiPartUploadCompleteCalled = true;
485  Results.AddRange(results);
486  }
487 
488  public void OnPartUpload(FileOperationResult result)
489  {
490  PartUploadCalled = true;
491  Results.Add(result);
492  }
493 
494  public void OnFullFileUpload(FileOperationResult result)
495  {
496  FullFileUploadCalled = true;
497  Results.Add(result);
498  }
499  }
500 
501  #endregion
502  }
503 }
const long DefaultFileSizeToSplit
Default file size threshold for multi-part uploads (60 MB).
static DownloadOptions Default
Returns the default download options.
Interface for receiving callbacks during file upload operations.
Main class for handling file operations with Kinetica's KiFS (Kinetica File System).
const int DefaultThreadPoolSize
Default thread pool size for file operations.
Options for uploading files to KiFS.
Definition: UploadOptions.cs:6
Integration tests for KiFS (Kinetica File System) operations.
Options for configuring the KineticaFileHandler behavior.
Connection Options
Definition: Kinetica.cs:50
Options for downloading files from KiFS.
static UploadOptions Default
Returns the default upload options.
Contains the result of a file upload or download operation.
API to talk to Kinetica Database
Definition: Kinetica.cs:40