refactor: extract NATS.Server.JetStream.Tests project
Move 225 JetStream-related test files from NATS.Server.Tests into a dedicated NATS.Server.JetStream.Tests project. This includes root-level JetStream*.cs files, storage test files (FileStore, MemStore, StreamStoreContract), and the full JetStream/ subfolder tree (Api, Cluster, Consumers, MirrorSource, Snapshots, Storage, Streams). Updated all namespaces, added InternalsVisibleTo, registered in the solution file, and added the JETSTREAM_INTEGRATION_MATRIX define.
This commit is contained in:
104
tests/NATS.Server.JetStream.Tests/FileStoreEncryptionTests.cs
Normal file
104
tests/NATS.Server.JetStream.Tests/FileStoreEncryptionTests.cs
Normal file
@@ -0,0 +1,104 @@
|
||||
// Go: TestFileStoreEncryption server/filestore_test.go
|
||||
// Reference: golang/nats-server/server/filestore.go:816-907 (genEncryptionKeys, recoverAEK, setupAEK)
|
||||
// Tests that block files are encrypted at rest and can be recovered with the same key.
|
||||
|
||||
using System.Security.Cryptography;
|
||||
using NATS.Server.JetStream.Storage;
|
||||
|
||||
namespace NATS.Server.JetStream.Tests;
|
||||
|
||||
public class FileStoreEncryptionTests
|
||||
{
|
||||
[Fact]
|
||||
public async Task Encrypted_block_round_trips_message()
|
||||
{
|
||||
// Go: TestFileStoreEncryption server/filestore_test.go
|
||||
var dir = Directory.CreateTempSubdirectory();
|
||||
var key = new byte[32];
|
||||
RandomNumberGenerator.Fill(key);
|
||||
|
||||
await using (var store = new FileStore(new FileStoreOptions
|
||||
{
|
||||
Directory = dir.FullName,
|
||||
Cipher = StoreCipher.ChaCha,
|
||||
EncryptionKey = key,
|
||||
}))
|
||||
{
|
||||
await store.AppendAsync("test.subj", "hello encrypted"u8.ToArray(), default);
|
||||
}
|
||||
|
||||
// Raw block file should NOT contain plaintext
|
||||
var blkFiles = Directory.GetFiles(dir.FullName, "*.blk");
|
||||
blkFiles.ShouldNotBeEmpty();
|
||||
var raw = File.ReadAllBytes(blkFiles[0]);
|
||||
System.Text.Encoding.UTF8.GetString(raw).ShouldNotContain("hello encrypted");
|
||||
|
||||
// Recover with same key should return plaintext
|
||||
await using var recovered = new FileStore(new FileStoreOptions
|
||||
{
|
||||
Directory = dir.FullName,
|
||||
Cipher = StoreCipher.ChaCha,
|
||||
EncryptionKey = key,
|
||||
});
|
||||
var msg = await recovered.LoadAsync(1, default);
|
||||
msg.ShouldNotBeNull();
|
||||
System.Text.Encoding.UTF8.GetString(msg.Payload.Span).ShouldBe("hello encrypted");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Encrypted_block_with_aes_round_trips()
|
||||
{
|
||||
var dir = Directory.CreateTempSubdirectory();
|
||||
var key = new byte[32];
|
||||
RandomNumberGenerator.Fill(key);
|
||||
|
||||
await using (var store = new FileStore(new FileStoreOptions
|
||||
{
|
||||
Directory = dir.FullName,
|
||||
Cipher = StoreCipher.Aes,
|
||||
EncryptionKey = key,
|
||||
}))
|
||||
{
|
||||
await store.AppendAsync("aes.subj", "aes payload"u8.ToArray(), default);
|
||||
}
|
||||
|
||||
await using var recovered = new FileStore(new FileStoreOptions
|
||||
{
|
||||
Directory = dir.FullName,
|
||||
Cipher = StoreCipher.Aes,
|
||||
EncryptionKey = key,
|
||||
});
|
||||
var msg = await recovered.LoadAsync(1, default);
|
||||
msg.ShouldNotBeNull();
|
||||
System.Text.Encoding.UTF8.GetString(msg.Payload.Span).ShouldBe("aes payload");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Wrong_key_fails_to_decrypt()
|
||||
{
|
||||
var dir = Directory.CreateTempSubdirectory();
|
||||
var key1 = new byte[32];
|
||||
var key2 = new byte[32];
|
||||
RandomNumberGenerator.Fill(key1);
|
||||
RandomNumberGenerator.Fill(key2);
|
||||
|
||||
await using (var store = new FileStore(new FileStoreOptions
|
||||
{
|
||||
Directory = dir.FullName,
|
||||
Cipher = StoreCipher.ChaCha,
|
||||
EncryptionKey = key1,
|
||||
}))
|
||||
{
|
||||
await store.AppendAsync("secret", "data"u8.ToArray(), default);
|
||||
}
|
||||
|
||||
// Recovery with wrong key should throw InvalidDataException (from CryptographicException)
|
||||
var act = () => new FileStore(new FileStoreOptions
|
||||
{
|
||||
Directory = dir.FullName,
|
||||
Cipher = StoreCipher.ChaCha,
|
||||
EncryptionKey = key2,
|
||||
});
|
||||
Should.Throw<InvalidDataException>(act);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user