public async Task KeysAndValues_SupportsFixedLengthStructs() { // Arrange var dummyOptions = new MixedStorageKVStoreOptions() { LogDirectory = _fixture.TempDirectory, LogFileNamePrefix = nameof(KeysAndValues_SupportsFixedLengthStructs), PageSizeBits = 12, MemorySizeBits = 13 // Limit to 8KB so we're testing both in-memory and disk-based operations }; var dummyStructInstance = new DummyFixedLengthStruct() { // Populate with dummy values DummyByte = byte.MaxValue, DummyShort = short.MaxValue, DummyLong = long.MaxValue }; int numRecords = 10000; using var testSubject = new MixedStorageKVStore <DummyFixedLengthStruct, DummyFixedLengthStruct>(dummyOptions); // Act and assert // Insert Parallel.For(0, numRecords, key => { DummyFixedLengthStruct localDummyStructInstance = dummyStructInstance; localDummyStructInstance.DummyInt = key; testSubject.Upsert(localDummyStructInstance, localDummyStructInstance); }); // Read List <Task <(Status, DummyFixedLengthStruct)> > readTasks = new(); for (int key = 0; key < numRecords; key++) { DummyFixedLengthStruct localDummyStructInstance = dummyStructInstance; localDummyStructInstance.DummyInt = key; readTasks.Add(ReadAsync(localDummyStructInstance, testSubject)); } await Task.WhenAll(readTasks).ConfigureAwait(false); // Verify for (int key = 0; key < numRecords; key++) { (Status status, DummyFixedLengthStruct result) = readTasks[key].Result; Assert.Equal(Status.OK, status); DummyFixedLengthStruct localDummyStructInstance = dummyStructInstance; localDummyStructInstance.DummyInt = key; Assert.Equal(localDummyStructInstance, result); } ; }
public async Task UpsertReadAsyncDelete_AreThreadSafe() { // Arrange var dummyOptions = new MixedStorageKVStoreOptions() { LogDirectory = _fixture.TempDirectory, LogFileNamePrefix = nameof(UpsertReadAsyncDelete_AreThreadSafe), PageSizeBits = 12, MemorySizeBits = 13 // Limit to 8KB so we're testing both in-memory and disk-based operations }; DummyClass dummyClassInstance = CreatePopulatedDummyClassInstance(); int numRecords = 10000; //using var testSubject = new ObjLogMixedStorageKVStore<int, DummyClass>(dummyOptions); //using var testSubject = new MemoryMixedStorageKVStore<int, DummyClass>(dummyOptions); using var testSubject = new MixedStorageKVStore <int, DummyClass>(dummyOptions); // Act and assert // Insert Parallel.For(0, numRecords, key => testSubject.Upsert(key, dummyClassInstance)); // Read await ReadAndVerifyValuesAsync(numRecords, testSubject, Status.OK, dummyClassInstance).ConfigureAwait(false); // Update dummyClassInstance.DummyInt = 20; dummyClassInstance.DummyString = "anotherDummyString"; Parallel.For(0, numRecords, key => testSubject.Upsert(key, dummyClassInstance)); // Verify updates await ReadAndVerifyValuesAsync(numRecords, testSubject, Status.OK, dummyClassInstance).ConfigureAwait(false); // Delete Parallel.For(0, numRecords, key => testSubject.Delete(key)); // Verify deletes await ReadAndVerifyValuesAsync(numRecords, testSubject, Status.NOTFOUND, null).ConfigureAwait(false); }
public async Task KeysAndValues_SupportsPrimitives() { // Arrange var dummyOptions = new MixedStorageKVStoreOptions() { LogDirectory = _fixture.TempDirectory, LogFileNamePrefix = nameof(KeysAndValues_SupportsPrimitives), PageSizeBits = 12, MemorySizeBits = 13 // Limit to 8KB so we're testing both in-memory and disk-based operations }; const int dummyValue = 12345; const int numRecords = 10000; using var testSubject = new MixedStorageKVStore <int, int>(dummyOptions); // Act and assert Parallel.For(0, numRecords, key => testSubject.Upsert(key, dummyValue)); await ReadAndVerifyValuesAsync(numRecords, testSubject, Status.OK, dummyValue).ConfigureAwait(false); }
public async Task KeysAndValues_SupportsObjects() { // Arrange var dummyOptions = new MixedStorageKVStoreOptions() { LogDirectory = _fixture.TempDirectory, LogFileNamePrefix = nameof(KeysAndValues_SupportsObjects), PageSizeBits = 12, MemorySizeBits = 13 // Limit to 8KB so we're testing both in-memory and disk-based operations }; int numRecords = 10000; using var testSubject = new MixedStorageKVStore <string, string>(dummyOptions); // Act and assert // Insert Parallel.For(0, numRecords, key => { string keyAsString = key.ToString(); testSubject.Upsert(keyAsString, keyAsString); }); // Read List <Task <(Status, string?)> > readTasks = new(); for (int key = 0; key < numRecords; key++) { readTasks.Add(ReadAsync(key.ToString(), testSubject)); } await Task.WhenAll(readTasks).ConfigureAwait(false); // Verify Parallel.For(0, numRecords, key => { (Status status, string?result) = readTasks[key].Result; Assert.Equal(Status.OK, status); Assert.Equal(key.ToString(), result); }); }
public void LogFiles_DeletedOnClose() { // Arrange string directory = Path.Combine(_fixture.TempDirectory, nameof(LogFiles_DeletedOnClose)); // Use a separate directory so the test is never affected by other tests var dummyOptions = new MixedStorageKVStoreOptions() { LogDirectory = directory, LogFileNamePrefix = nameof(LogFiles_DeletedOnClose), PageSizeBits = 9, // Minimum MemorySizeBits = 10 // Minimum }; DummyClass dummyClassInstance = CreatePopulatedDummyClassInstance(); int numRecords = 50; // Just enough to make sure log files are created. Segment size isn't exceeded (only 1 of each log file). var testSubject = new MixedStorageKVStore <int, DummyClass>(dummyOptions); Parallel.For(0, numRecords, key => testSubject.Upsert(key, dummyClassInstance)); // Creates log Assert.Single(Directory.EnumerateFiles(directory, $"{nameof(LogFiles_DeletedOnClose)}*")); // Log and object log // Act testSubject.Dispose(); // Assert Assert.Empty(Directory.EnumerateFiles(directory)); // Logs deleted }