Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

C#: Make IT to manage redis. #116

Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 5 additions & 4 deletions .github/workflows/csharp.yml
Original file line number Diff line number Diff line change
Expand Up @@ -71,14 +71,14 @@ jobs:
working-directory: ./csharp
run: dotnet format --verify-no-changes --verbosity diagnostic

- name: Test dotnet ${{ matrix.dotnet }}
working-directory: ./csharp
run: dotnet test --framework net${{ matrix.dotnet }} "-l:html;LogFileName=TestReport.html" --results-directory . -warnaserror -- NUnit.WorkDirectory=$PWD

- uses: ./.github/workflows/test-benchmark
with:
language-flag: -csharp

- name: Test dotnet ${{ matrix.dotnet }}
working-directory: ./csharp
run: dotnet test --framework net${{ matrix.dotnet }} "-l:html;LogFileName=TestReport.html" --results-directory . -warnaserror

- name: Upload test reports
if: always()
continue-on-error: true
Expand All @@ -88,6 +88,7 @@ jobs:
path: |
csharp/TestReport.html
benchmarks/results/*
utils/clusters/**

lint-rust:
timeout-minutes: 10
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,12 @@
* Copyright GLIDE-for-Redis Project Contributors - SPDX Identifier: Apache-2.0
*/

namespace tests;
namespace tests.Integration;

using Glide;

// TODO - need to start a new redis server for each test?
public class AsyncClientTests
public class GetAndSet
{
[OneTimeSetUp]
public void Setup()
{
Glide.Logger.SetLoggerConfig(Glide.Level.Info);
}

private async Task GetAndSetRandomValues(AsyncClient client)
{
var key = Guid.NewGuid().ToString();
Expand All @@ -27,7 +20,7 @@ private async Task GetAndSetRandomValues(AsyncClient client)
[Test]
public async Task GetReturnsLastSet()
{
using (var client = new AsyncClient("localhost", 6379, false))
using (var client = new AsyncClient("localhost", IntegrationTestBase.STANDALONE_PORTS[0], false))
{
await GetAndSetRandomValues(client);
}
Expand All @@ -36,7 +29,7 @@ public async Task GetReturnsLastSet()
[Test]
public async Task GetAndSetCanHandleNonASCIIUnicode()
{
using (var client = new AsyncClient("localhost", 6379, false))
using (var client = new AsyncClient("localhost", IntegrationTestBase.STANDALONE_PORTS[0], false))
{
var key = Guid.NewGuid().ToString();
var value = "שלום hello 汉字";
Expand All @@ -49,7 +42,7 @@ public async Task GetAndSetCanHandleNonASCIIUnicode()
[Test]
public async Task GetReturnsNull()
{
using (var client = new AsyncClient("localhost", 6379, false))
using (var client = new AsyncClient("localhost", IntegrationTestBase.STANDALONE_PORTS[0], false))
{
var result = await client.GetAsync(Guid.NewGuid().ToString());
Assert.That(result, Is.EqualTo(null));
Expand All @@ -59,7 +52,7 @@ public async Task GetReturnsNull()
[Test]
public async Task GetReturnsEmptyString()
{
using (var client = new AsyncClient("localhost", 6379, false))
using (var client = new AsyncClient("localhost", IntegrationTestBase.STANDALONE_PORTS[0], false))
{
var key = Guid.NewGuid().ToString();
var value = "";
Expand All @@ -72,7 +65,7 @@ public async Task GetReturnsEmptyString()
[Test]
public async Task HandleVeryLargeInput()
{
using (var client = new AsyncClient("localhost", 6379, false))
using (var client = new AsyncClient("localhost", IntegrationTestBase.STANDALONE_PORTS[0], false))
{
var key = Guid.NewGuid().ToString();
var value = Guid.NewGuid().ToString();
Expand All @@ -92,7 +85,7 @@ public async Task HandleVeryLargeInput()
[Test]
public void ConcurrentOperationsWork()
{
using (var client = new AsyncClient("localhost", 6379, false))
using (var client = new AsyncClient("localhost", IntegrationTestBase.STANDALONE_PORTS[0], false))
{
var operations = new List<Task>();

Expand Down
136 changes: 136 additions & 0 deletions csharp/tests/Integration/IntegrationTestBase.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
/**
* Copyright GLIDE-for-Redis Project Contributors - SPDX Identifier: Apache-2.0
*/

using System.Diagnostics;

// Note: All IT should be in the same namespace
namespace tests.Integration;

[SetUpFixture]
public class IntegrationTestBase
{
[OneTimeSetUp]
public void SetUp()
{
// Stop all if weren't stopped on previous test run
StopRedis(false);

// Delete dirs if stop failed due to https://github.com/aws/glide-for-redis/issues/849
Directory.Delete(Path.Combine(scriptDir, "clusters"), true);

// Start cluster
CLUSTER_PORTS = StartRedis(true);
// Start standalone
STANDALONE_PORTS = StartRedis(false);

// Get redis version
REDIS_VERSION = GetRedisVersion();

TestContext.Progress.WriteLine($"Cluster ports = {string.Join(',', CLUSTER_PORTS)}");
TestContext.Progress.WriteLine($"Standalone ports = {string.Join(',', STANDALONE_PORTS)}");
TestContext.Progress.WriteLine($"Redis version = {REDIS_VERSION}");
}

[OneTimeTearDown]
public void TearDown()
{
// Stop all
StopRedis(true);
}

public static List<uint> STANDALONE_PORTS { get; private set; } = new();
public static List<uint> CLUSTER_PORTS { get; private set; } = new();
public static Version REDIS_VERSION { get; private set; } = new();

private readonly string scriptDir;

// Nunit requires a public default constructor. These variables would be set in SetUp method.
public IntegrationTestBase()
{
STANDALONE_PORTS = new();
CLUSTER_PORTS = new();
REDIS_VERSION = new();

string path = TestContext.CurrentContext.WorkDirectory;
if (Path.GetFileName(path) != "csharp")
// Probably '-- NUnit.WorkDirectory=<path>' is missing in 'dotnet test' command line or .runsettings
throw new FileNotFoundException("`WorkDirectory` is incorrect or not defined.");
Yury-Fridlyand marked this conversation as resolved.
Show resolved Hide resolved

scriptDir = Path.Combine(path, "..", "utils");
}


public List<uint> StartRedis(bool cluster, bool tls = false, string? name = null)
{
var cmd = $"start {(cluster ? "--cluster-mode" : "-r 0")} {(tls ? " --tls" : "")} {(name != null ? " --prefix " + name : "")}";
return ParsePortsFromOutput(RunClusterManager(cmd, false));
}

/// <summary>
/// Stop <b>all</b> instances on the given <paramref name="name"/>.
/// </summary>
public void StopRedis(bool keepLogs, string? name = null)
{
var cmd = $"stop --prefix {name ?? "redis-cluster"} {(keepLogs ? "--keep-folder" : "")}";
RunClusterManager(cmd, true);
}


private string RunClusterManager(string cmd, bool ignoreExitCode)
{
var info = new ProcessStartInfo
{
WorkingDirectory = scriptDir,
FileName = "python3",
Arguments = "cluster_manager.py " + cmd,
UseShellExecute = false,
RedirectStandardOutput = true,
RedirectStandardError = true,
};
var script = Process.Start(info);
script?.WaitForExit();
var error = script?.StandardError.ReadToEnd();
var output = script?.StandardOutput.ReadToEnd();
var exit_code = script?.ExitCode;

TestContext.Progress.WriteLine($"cluster_manager.py stdout\n====\n{output}\n====\ncluster_manager.py stderr\n====\n{error}\n====\n");

if (!ignoreExitCode && exit_code != 0)
throw new ApplicationException($"cluster_manager.py script failed: exit code {exit_code}.");

return output ?? "";
}

private List<uint> ParsePortsFromOutput(string output)
{
var ports = new List<uint>();
foreach (var line in output.Split("\n"))
{
if (!line.StartsWith("CLUSTER_NODES="))
continue;

var addresses = line.Split("=")[1].Split(",");
foreach (var address in addresses)
ports.Add(uint.Parse(address.Split(":")[1]));
}
return ports;
}

private Version GetRedisVersion()
{
var info = new ProcessStartInfo
{
FileName = "redis-server",
Arguments = "-v",
UseShellExecute = false,
RedirectStandardOutput = true,
};
var proc = Process.Start(info);
proc?.WaitForExit();
var output = proc?.StandardOutput.ReadToEnd() ?? "";

// Redis server v=7.2.3 sha=00000000:0 malloc=jemalloc-5.3.0 bits=64 build=7504b1fedf883f2
return new Version(output.Split(" ")[2].Split("=")[1]);
}
}
9 changes: 9 additions & 0 deletions csharp/tests/Unit/Placeholder.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
/**
* Copyright GLIDE-for-Redis Project Contributors - SPDX Identifier: Apache-2.0
*/

namespace tests.Unit;

using Glide;

// John Travolta is looking for tests

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what-huh

Loading