blob: ea93777ebde52a2136ae551341967235eaa037a6 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
namespace Apache.Ignite.Tests
{
using System;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Threading.Tasks;
using Ignite.Transactions;
using Internal;
using Internal.Buffers;
using Internal.Common;
using Internal.Proto;
using Internal.Transactions;
using Microsoft.Extensions.Logging;
using NUnit.Framework;
public static class TestUtils
{
public static readonly string SolutionDir = GetSolutionDir();
public static readonly string RepoRootDir = Path.Combine(GetSolutionDir(), "..", "..", "..");
public static bool IsWindows => RuntimeInformation.IsOSPlatform(OSPlatform.Windows);
public static void WaitForCondition(Func<bool> condition, int timeoutMs = 1000, Func<string>? messageFactory = null) =>
WaitForConditionAsync(() => Task.FromResult(condition()), timeoutMs, messageFactory).GetAwaiter().GetResult();
public static async Task WaitForConditionAsync(
Func<Task<bool>> condition,
int timeoutMs = 1000,
Func<string>? messageFactory = null)
{
if (await condition())
{
return;
}
var sw = Stopwatch.StartNew();
while (sw.ElapsedMilliseconds < timeoutMs)
{
if (await condition())
{
return;
}
await Task.Delay(10);
}
var message = "Condition not reached after " + sw.Elapsed;
if (messageFactory != null)
{
message += $" ({messageFactory()})";
}
Assert.Fail(message);
}
public static T GetFieldValue<T>(this object obj, string fieldName) => (T) GetNonPublicField(obj, fieldName).GetValue(obj)!;
public static void SetFieldValue(this object obj, string fieldName, object? value) =>
GetNonPublicField(obj, fieldName).SetValue(obj, value);
public static ILoggerFactory GetConsoleLoggerFactory(LogLevel minLevel) => new ConsoleLogger(minLevel);
public static void CheckByteArrayPoolLeak(int timeoutMs = 1000)
{
#if DEBUG
WaitForCondition(
condition: () => ByteArrayPool.CurrentlyRentedArrays.IsEmpty,
timeoutMs: timeoutMs,
messageFactory: () =>
{
var bufs = ByteArrayPool.CurrentlyRentedArrays
.Select(x => $"{x.Value.DeclaringType}.{x.Value.Name}")
.StringJoin();
return $"Leaked buffers: {bufs}";
});
#endif
}
internal static async Task ForceLazyTxStart(ITransaction tx, IIgnite client, PreferredNode preferredNode = default) =>
await LazyTransaction.EnsureStartedAsync(
tx,
client.GetFieldValue<ClientFailoverSocket>("_socket"),
preferredNode);
private static FieldInfo GetNonPublicField(object obj, string fieldName)
{
var field = obj.GetType().GetField(fieldName, BindingFlags.Instance | BindingFlags.NonPublic);
Assert.IsNotNull(field, $"Field '{fieldName}' not found in '{obj.GetType()}'");
return field!;
}
private static string GetSolutionDir()
{
var dir = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
while (dir != null && !File.Exists(Path.Combine(dir, "Apache.Ignite.sln")))
{
dir = Path.GetDirectoryName(dir);
}
if (dir == null)
{
throw new Exception("Failed to locate solution directory.");
}
return dir;
}
}
}