From ab4517d4574ef50281f444c4a8d249b425e78a89 Mon Sep 17 00:00:00 2001 From: TedHartMS <15467143+TedHartMS@users.noreply.github.com> Date: Wed, 8 Jan 2025 14:51:23 -0800 Subject: [PATCH 01/36] net9 changes --- Directory.Build.props | 2 +- .../BDN.benchmark/Parsing/IntegerToResp.cs | 4 +-- benchmark/BDN.benchmark/Program.cs | 6 ++++- benchmark/Resp.benchmark/Program.cs | 4 +-- benchmark/Resp.benchmark/RespPerfBench.cs | 4 +-- .../Garnet.worker/Garnet.worker.csproj | 2 +- libs/common/EnumUtils.cs | 2 +- libs/common/FailoverOption.cs | 3 +-- libs/common/FileUtils.cs | 6 +++-- libs/common/Metrics/InfoMetricsType.cs | 3 +-- libs/host/Garnet.host.csproj | 2 ++ libs/server/Custom/CustomCommandManager.cs | 27 ++++++++++++------- libs/server/Custom/ExpandableMap.cs | 7 +++++ libs/server/Metrics/Info/GarnetInfoMetrics.cs | 5 ++-- .../Objects/SortedSet/SortedSetObjectImpl.cs | 10 +++---- .../SortedSetGeo/SortedSetGeoObjectImpl.cs | 4 +-- libs/server/Resp/RespCommandsInfo.cs | 6 ++--- libs/server/ServerConfig.cs | 4 +-- libs/server/StoreWrapper.cs | 2 +- libs/server/TLS/GarnetTlsOptions.cs | 4 +-- playground/ClusterStress/Program.cs | 2 +- .../CommandInfoUpdater/CommandDocsUpdater.cs | 6 ++--- .../CommandInfoUpdater/CommandInfoUpdater.cs | 8 +++--- playground/CommandInfoUpdater/CommonUtils.cs | 4 +-- .../EmbeddedPerformanceTest.cs | 4 +-- .../GarnetClientStress/StressTestUtil.cs | 3 +-- .../ClusterMigrateTests.cs | 2 +- .../ClusterRedirectTests.cs | 4 +-- test/Garnet.test.cluster/ClusterTestUtils.cs | 14 +++++----- test/Garnet.test/GarnetClientTests.cs | 4 +-- test/Garnet.test/HyperLogLogTests.cs | 2 +- test/Garnet.test/RespAdminCommandsTests.cs | 2 +- test/Garnet.test/RespAofTests.cs | 2 +- test/Garnet.test/RespCommandTests.cs | 2 +- test/Garnet.test/RespGetLowMemoryTests.cs | 4 +-- test/Garnet.test/RespSetTest.cs | 8 +++--- test/Garnet.test/RespSortedSetTests.cs | 14 +++++----- test/Garnet.test/RespTests.cs | 11 ++++---- test/Garnet.test/RespTlsTests.cs | 2 +- test/Garnet.test/TestProcedureHash.cs | 2 +- test/Garnet.test/TestProcedureSet.cs | 2 +- 41 files changed, 111 insertions(+), 98 deletions(-) diff --git a/Directory.Build.props b/Directory.Build.props index 872c0570d4..f1b10ff4da 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -1,7 +1,7 @@ - net8.0 + net8.0;net9.0 diff --git a/benchmark/BDN.benchmark/Parsing/IntegerToResp.cs b/benchmark/BDN.benchmark/Parsing/IntegerToResp.cs index 5e9df56387..d17d888c74 100644 --- a/benchmark/BDN.benchmark/Parsing/IntegerToResp.cs +++ b/benchmark/BDN.benchmark/Parsing/IntegerToResp.cs @@ -92,14 +92,14 @@ public void WriteInt32BulkString_AllAsciiLengths() .. UnsignedInt32MultiplesOfTen.Select(n => n * -1), .. UnsignedInt32MultiplesOfTen ]; - public static int[] UnsignedInt32MultiplesOfTen => Enumerable.Range(0, 10).Select(n => (int)Math.Pow(10, n)).ToArray(); + public static int[] UnsignedInt32MultiplesOfTen => [.. Enumerable.Range(0, 10).Select(n => (int)Math.Pow(10, n))]; // All multiples of 10 from 10^-19 to 10^19 public static long[] SignedInt64MultiplesOfTen => [ .. UnsignedInt64MultiplesOfTen.Select(n => n * -1), .. UnsignedInt64MultiplesOfTen ]; - public static long[] UnsignedInt64MultiplesOfTen => Enumerable.Range(0, 19).Select(n => (long)Math.Pow(10, n)).ToArray(); + public static long[] UnsignedInt64MultiplesOfTen => [.. Enumerable.Range(0, 19).Select(n => (long)Math.Pow(10, n))]; public static int[] SignedInt32Values => [int.MinValue, -1, 0, int.MaxValue]; public static long[] SignedInt64Values => [long.MinValue, -1, 0, long.MaxValue]; diff --git a/benchmark/BDN.benchmark/Program.cs b/benchmark/BDN.benchmark/Program.cs index 06f1b46bde..5993e595bc 100644 --- a/benchmark/BDN.benchmark/Program.cs +++ b/benchmark/BDN.benchmark/Program.cs @@ -19,6 +19,7 @@ public class BaseConfig : ManualConfig { public Job Net8BaseJob { get; } + public Job Net9BaseJob { get; } public BaseConfig() { @@ -30,9 +31,12 @@ public BaseConfig() Net8BaseJob = baseJob.WithRuntime(CoreRuntime.Core80) .WithEnvironmentVariables(new EnvironmentVariable("DOTNET_TieredPGO", "0")); + Net9BaseJob = baseJob.WithRuntime(CoreRuntime.Core90) + .WithEnvironmentVariables(new EnvironmentVariable("DOTNET_TieredPGO", "0")); AddJob( - Net8BaseJob.WithId(".NET 8") + Net8BaseJob.WithId(".NET 8"), + Net9BaseJob.WithId(".NET 9") ); } } \ No newline at end of file diff --git a/benchmark/Resp.benchmark/Program.cs b/benchmark/Resp.benchmark/Program.cs index cb3a151e8d..80d36f8b82 100644 --- a/benchmark/Resp.benchmark/Program.cs +++ b/benchmark/Resp.benchmark/Program.cs @@ -215,7 +215,7 @@ static void WaitForServer(Options opts) static void RunBasicCommandsBenchmark(Options opts) { - int[] threadBench = opts.NumThreads.ToArray(); + int[] threadBench = [.. opts.NumThreads]; int keyLen = opts.KeyLength; int valueLen = opts.ValueLength; @@ -275,7 +275,7 @@ static void RunBasicCommandsBenchmark(Options opts) static void RunHLLBenchmark(Options opts) { var bench = new RespPerfBench(opts, 0, redis); - int[] threadBench = opts.NumThreads.ToArray(); + int[] threadBench = [.. opts.NumThreads]; int loadThreads = 8; int loadBatchSize = opts.DbSize / loadThreads; diff --git a/benchmark/Resp.benchmark/RespPerfBench.cs b/benchmark/Resp.benchmark/RespPerfBench.cs index 74c535104a..ee52c7b778 100644 --- a/benchmark/Resp.benchmark/RespPerfBench.cs +++ b/benchmark/Resp.benchmark/RespPerfBench.cs @@ -501,7 +501,7 @@ private void MGetThreadRunner(int threadid, int NumOps, int BatchSize = 1 << 12) } if (idx > 0) { - var result = db.StringGet(getBatch.Take(idx).ToArray()); + var result = db.StringGet([.. getBatch.Take(idx)]); if (checkResults) { for (int k = 0; k < idx; k++) @@ -543,7 +543,7 @@ private void LoadDatabaseStringSet(int BatchSize = 1 << 12) { for (int b = 0; b < DbSize; b += BatchSize) { - db.StringSet(database.Skip(b).Take(BatchSize).ToArray()); + db.StringSet([.. database.Skip(b).Take(BatchSize)]); if (b > 0 && b % 1000000 == 0) Console.WriteLine(b); } diff --git a/hosting/Windows/Garnet.worker/Garnet.worker.csproj b/hosting/Windows/Garnet.worker/Garnet.worker.csproj index b8fad9da9f..ab255cf37b 100644 --- a/hosting/Windows/Garnet.worker/Garnet.worker.csproj +++ b/hosting/Windows/Garnet.worker/Garnet.worker.csproj @@ -1,7 +1,7 @@  - net8.0 + net8.0;net9.0 diff --git a/libs/common/EnumUtils.cs b/libs/common/EnumUtils.cs index 7ac88a6557..03b1209d80 100644 --- a/libs/common/EnumUtils.cs +++ b/libs/common/EnumUtils.cs @@ -42,7 +42,7 @@ public static IDictionary GetEnumNameToDescription() where T public static string[] GetEnumDescriptions(T value) where T : Enum { var nameToDesc = GetEnumNameToDescription(); - return value.ToString().Split(',').Select(f => nameToDesc.ContainsKey(f.Trim()) ? nameToDesc[f.Trim()] : f).ToArray(); + return [.. value.ToString().Split(',').Select(f => nameToDesc.ContainsKey(f.Trim()) ? nameToDesc[f.Trim()] : f)]; } /// diff --git a/libs/common/FailoverOption.cs b/libs/common/FailoverOption.cs index d4421d63e8..790f778876 100644 --- a/libs/common/FailoverOption.cs +++ b/libs/common/FailoverOption.cs @@ -50,8 +50,7 @@ public enum FailoverOption : byte /// public static class FailoverUtils { - static readonly byte[][] infoSections = Enum.GetValues() - .Select(x => Encoding.ASCII.GetBytes($"${x.ToString().Length}\r\n{x}\r\n")).ToArray(); + static readonly byte[][] infoSections = [.. Enum.GetValues().Select(x => Encoding.ASCII.GetBytes($"${x.ToString().Length}\r\n{x}\r\n"))]; /// /// Return resp formatted failover option diff --git a/libs/common/FileUtils.cs b/libs/common/FileUtils.cs index fed2418547..b926736d47 100644 --- a/libs/common/FileUtils.cs +++ b/libs/common/FileUtils.cs @@ -159,13 +159,15 @@ public static bool TryLoadAssemblies(IEnumerable assemblyPaths, out IEnu Assembly assembly; try { - assembly = AssemblyLoadContext.Default.LoadFromAssemblyPath(path); + // NET9 seems to hold the assembly locked if it's opened from the path directly, causing tests to fail. + //assembly = AssemblyLoadContext.Default.LoadFromAssemblyPath(path); + assembly = AssemblyLoadContext.Default.LoadFromStream(new FileStream(path, FileMode.Open, FileAccess.Read)); } catch (Exception ex) when (ex is IOException || ex is UnauthorizedAccessException || ex is NotSupportedException || ex is BadImageFormatException || ex is SecurityException) { - if (ex is FileLoadException && ex.Message == "Assembly with same name is already loaded") + if (ex is FileLoadException && ex.Message.Contains("Assembly with same name is already loaded")) { var assemblyName = AssemblyName.GetAssemblyName(path).Name; tmpAssemblies.Add(AssemblyLoadContext.Default.Assemblies.First(a => a.GetName().Name == assemblyName)); diff --git a/libs/common/Metrics/InfoMetricsType.cs b/libs/common/Metrics/InfoMetricsType.cs index 89c3e58183..766ff0341d 100644 --- a/libs/common/Metrics/InfoMetricsType.cs +++ b/libs/common/Metrics/InfoMetricsType.cs @@ -85,8 +85,7 @@ public enum InfoMetricsType : byte /// public static class InfoCommandUtils { - static readonly byte[][] infoSections = Enum.GetValues() - .Select(x => Encoding.ASCII.GetBytes($"${x.ToString().Length}\r\n{x}\r\n")).ToArray(); + static readonly byte[][] infoSections = [.. Enum.GetValues().Select(x => Encoding.ASCII.GetBytes($"${x.ToString().Length}\r\n{x}\r\n"))]; /// /// Return resp formatted info section diff --git a/libs/host/Garnet.host.csproj b/libs/host/Garnet.host.csproj index a4d034dd85..8b5fd962e0 100644 --- a/libs/host/Garnet.host.csproj +++ b/libs/host/Garnet.host.csproj @@ -39,6 +39,8 @@ + + diff --git a/libs/server/Custom/CustomCommandManager.cs b/libs/server/Custom/CustomCommandManager.cs index 4ca58d7b9a..337fae4c4b 100644 --- a/libs/server/Custom/CustomCommandManager.cs +++ b/libs/server/Custom/CustomCommandManager.cs @@ -47,8 +47,10 @@ internal int Register(string name, CommandType type, CustomRawStringFunctions cu var newCmd = new CustomRawStringCommand(name, (ushort)cmdId, type, customFunctions, expirationTicks); var setSuccessful = rawStringCommandMap.TrySetValue(cmdId, ref newCmd); Debug.Assert(setSuccessful); - if (commandInfo != null) customCommandsInfo.AddOrUpdate(name, commandInfo, (_, _) => commandInfo); - if (commandDocs != null) customCommandsDocs.AddOrUpdate(name, commandDocs, (_, _) => commandDocs); + if (commandInfo != null) + customCommandsInfo.AddOrUpdate(name, commandInfo, (_, _) => commandInfo); + if (commandDocs != null) + customCommandsDocs.AddOrUpdate(name, commandDocs, (_, _) => commandDocs); return cmdId; } @@ -61,8 +63,10 @@ internal int Register(string name, Func proc, RespCo var newCmd = new CustomTransaction(name, (byte)cmdId, proc); var setSuccessful = transactionProcMap.TrySetValue(cmdId, ref newCmd); Debug.Assert(setSuccessful); - if (commandInfo != null) customCommandsInfo.AddOrUpdate(name, commandInfo, (_, _) => commandInfo); - if (commandDocs != null) customCommandsDocs.AddOrUpdate(name, commandDocs, (_, _) => commandDocs); + if (commandInfo != null) + customCommandsInfo.AddOrUpdate(name, commandInfo, (_, _) => commandInfo); + if (commandDocs != null) + customCommandsDocs.AddOrUpdate(name, commandDocs, (_, _) => commandDocs); return cmdId; } @@ -101,13 +105,14 @@ internal int RegisterType(CustomObjectFactory factory) throw new Exception("Out of registration space"); Debug.Assert(scId <= byte.MaxValue); - var newSubCmd = new CustomObjectCommand(name, (byte)typeId, (byte)scId, commandType, wrapper.factory, - customObjectFunctions); + var newSubCmd = new CustomObjectCommand(name, (byte)typeId, (byte)scId, commandType, wrapper.factory, customObjectFunctions); var scSetSuccessful = wrapper.commandMap.TrySetValue(scId, ref newSubCmd); Debug.Assert(scSetSuccessful); - if (commandInfo != null) customCommandsInfo.AddOrUpdate(name, commandInfo, (_, _) => commandInfo); - if (commandDocs != null) customCommandsDocs.AddOrUpdate(name, commandDocs, (_, _) => commandDocs); + if (commandInfo != null) + customCommandsInfo.AddOrUpdate(name, commandInfo, (_, _) => commandInfo); + if (commandDocs != null) + customCommandsDocs.AddOrUpdate(name, commandDocs, (_, _) => commandDocs); return (typeId, scId); } @@ -132,8 +137,10 @@ internal int Register(string name, Func customProcedure, RespCo var setSuccessful = customProcedureMap.TrySetValue(cmdId, ref newCmd); Debug.Assert(setSuccessful); - if (commandInfo != null) customCommandsInfo.AddOrUpdate(name, commandInfo, (_, _) => commandInfo); - if (commandDocs != null) customCommandsDocs.AddOrUpdate(name, commandDocs, (_, _) => commandDocs); + if (commandInfo != null) + customCommandsInfo.AddOrUpdate(name, commandInfo, (_, _) => commandInfo); + if (commandDocs != null) + customCommandsDocs.AddOrUpdate(name, commandDocs, (_, _) => commandDocs); return cmdId; } diff --git a/libs/server/Custom/ExpandableMap.cs b/libs/server/Custom/ExpandableMap.cs index af2709a3cc..70fd37c6fc 100644 --- a/libs/server/Custom/ExpandableMap.cs +++ b/libs/server/Custom/ExpandableMap.cs @@ -261,6 +261,13 @@ internal bool TrySetValue(int id, ref T value, bool noExpansion, bool updateSize /// Item ID /// Map index private int GetIndexFromId(int id) => descIds ? minId - id : id; + + public void Clear() + { + if (Map is not null) + Array.Clear(Map); + ActualSize = 0; + } } /// diff --git a/libs/server/Metrics/Info/GarnetInfoMetrics.cs b/libs/server/Metrics/Info/GarnetInfoMetrics.cs index 6f22598846..4a2b21a3b9 100644 --- a/libs/server/Metrics/Info/GarnetInfoMetrics.cs +++ b/libs/server/Metrics/Info/GarnetInfoMetrics.cs @@ -12,7 +12,7 @@ namespace Garnet.server { class GarnetInfoMetrics { - public static readonly InfoMetricsType[] defaultInfo = Enum.GetValues() + public static readonly InfoMetricsType[] defaultInfo = [.. Enum.GetValues() .Where(e => e switch { InfoMetricsType.STOREHASHTABLE => false, @@ -20,8 +20,7 @@ class GarnetInfoMetrics InfoMetricsType.STOREREVIV => false, InfoMetricsType.OBJECTSTOREREVIV => false, _ => true - }) - .ToArray(); + })]; MetricsItem[] serverInfo = null; MetricsItem[] memoryInfo = null; diff --git a/libs/server/Objects/SortedSet/SortedSetObjectImpl.cs b/libs/server/Objects/SortedSet/SortedSetObjectImpl.cs index b1480f455e..db4c6828db 100644 --- a/libs/server/Objects/SortedSet/SortedSetObjectImpl.cs +++ b/libs/server/Objects/SortedSet/SortedSetObjectImpl.cs @@ -1015,10 +1015,9 @@ private void SortedSetPopMinOrMaxCount(ref ObjectInput input, ref SpanByteAndMem if (validLimit) { - elementsInLex = elementsInLex + elementsInLex = [.. elementsInLex .Skip(limit.Item1 > 0 ? limit.Item1 : 0) - .Take(limit.Item2 > 0 ? limit.Item2 : elementsInLex.Count) - .ToList(); + .Take(limit.Item2 > 0 ? limit.Item2 : elementsInLex.Count)]; } } catch (ArgumentException) @@ -1067,10 +1066,9 @@ private void SortedSetPopMinOrMaxCount(ref ObjectInput input, ref SpanByteAndMem if (doReverse) scoredElements.Reverse(); if (validLimit) { - scoredElements = scoredElements + scoredElements = [.. scoredElements .Skip(limit.Item1 > 0 ? limit.Item1 : 0) - .Take(limit.Item2 > 0 ? limit.Item2 : scoredElements.Count) - .ToList(); + .Take(limit.Item2 > 0 ? limit.Item2 : scoredElements.Count)]; } if (rem) diff --git a/libs/server/Objects/SortedSetGeo/SortedSetGeoObjectImpl.cs b/libs/server/Objects/SortedSetGeo/SortedSetGeoObjectImpl.cs index 66f627f841..e135e69ae0 100644 --- a/libs/server/Objects/SortedSetGeo/SortedSetGeoObjectImpl.cs +++ b/libs/server/Objects/SortedSetGeo/SortedSetGeoObjectImpl.cs @@ -409,7 +409,7 @@ private void GeoSearch(ref ObjectInput input, ref SpanByteAndMemory output) } // Check that we have the mandatory options - if (errorMessage == default && !((opts.FromMember || opts.FromLonLat) && (opts.ByRadius || opts.ByBox))) + if (errorMessage.IsEmpty && !((opts.FromMember || opts.FromLonLat) && (opts.ByRadius || opts.ByBox))) argNumError = true; // Check if we have a wrong number of arguments @@ -420,7 +420,7 @@ private void GeoSearch(ref ObjectInput input, ref SpanByteAndMemory output) } // Check if we encountered an error while checking the parse state - if (errorMessage != default) + if (!errorMessage.IsEmpty) { while (!RespWriteUtils.WriteError(errorMessage, ref curr, end)) ObjectUtils.ReallocateOutput(ref output, ref isMemory, ref ptr, ref ptrHandle, ref curr, ref end); diff --git a/libs/server/Resp/RespCommandsInfo.cs b/libs/server/Resp/RespCommandsInfo.cs index 0da1797398..95fec70bc4 100644 --- a/libs/server/Resp/RespCommandsInfo.cs +++ b/libs/server/Resp/RespCommandsInfo.cs @@ -184,8 +184,8 @@ private static bool TryInitializeRespCommandsInfo(ILogger logger = null) .Where(ci => !ci.Value.IsInternal) .ToDictionary(kvp => kvp.Key, kvp => kvp.Value, StringComparer.OrdinalIgnoreCase)); ExternalRespSubCommandsInfo = new ReadOnlyDictionary(tmpExternalSubCommandsInfo); - AllRespCommandNames = ImmutableHashSet.Create(StringComparer.OrdinalIgnoreCase, AllRespCommandsInfo.Keys.ToArray()); - ExternalRespCommandNames = ImmutableHashSet.Create(StringComparer.OrdinalIgnoreCase, ExternalRespCommandsInfo.Keys.ToArray()); + AllRespCommandNames = ImmutableHashSet.Create(StringComparer.OrdinalIgnoreCase, [.. AllRespCommandsInfo.Keys]); + ExternalRespCommandNames = ImmutableHashSet.Create(StringComparer.OrdinalIgnoreCase, [.. ExternalRespCommandsInfo.Keys]); FlattenedRespCommandsInfo = new ReadOnlyDictionary(tmpFlattenedRespCommandsInfo); AclCommandInfo = @@ -196,7 +196,7 @@ private static bool TryInitializeRespCommandsInfo(ILogger logger = null) .GroupBy(static t => t.Acl) .ToDictionary( static grp => grp.Key, - static grp => (IReadOnlyList)ImmutableArray.CreateRange(grp.Select(static t => t.CommandInfo)) + static grp => (IReadOnlyList)[.. grp.Select(static t => t.CommandInfo)] ) ); diff --git a/libs/server/ServerConfig.cs b/libs/server/ServerConfig.cs index 82de1b7023..13aa39a036 100644 --- a/libs/server/ServerConfig.cs +++ b/libs/server/ServerConfig.cs @@ -12,13 +12,13 @@ namespace Garnet.server { static class ServerConfig { - public static readonly HashSet DefaultConfigType = Enum.GetValues(). + public static readonly HashSet DefaultConfigType = [.. Enum.GetValues(). Where(e => e switch { ServerConfigType.NONE => false, ServerConfigType.ALL => false, _ => true - }).ToHashSet(); + })]; public static unsafe ServerConfigType GetConfig(Span parameter) { diff --git a/libs/server/StoreWrapper.cs b/libs/server/StoreWrapper.cs index 49b30eff39..ecd6757a87 100644 --- a/libs/server/StoreWrapper.cs +++ b/libs/server/StoreWrapper.cs @@ -26,7 +26,7 @@ namespace Garnet.server /// /// Wrapper for store and store-specific information /// - public sealed class StoreWrapper + public sealed class StoreWrapper : IDisposable { internal readonly string version; internal readonly string redisProtocolVersion; diff --git a/libs/server/TLS/GarnetTlsOptions.cs b/libs/server/TLS/GarnetTlsOptions.cs index 607a3076b5..973e0630a4 100644 --- a/libs/server/TLS/GarnetTlsOptions.cs +++ b/libs/server/TLS/GarnetTlsOptions.cs @@ -295,9 +295,7 @@ bool ValidateCertificateIssuer(X509Certificate2 certificateToValidate, X509Certi var chainBuilt = chain.Build(certificateToValidate); if (!chainBuilt) { - string[] errors = chain.ChainStatus - .Select(x => String.Format("{0} ({1})", x.StatusInformation.Trim(), x.Status)) - .ToArray(); + string[] errors = [.. chain.ChainStatus.Select(x => String.Format("{0} ({1})", x.StatusInformation.Trim(), x.Status))]; string certificateErrorsString = "Unknown errors."; if (errors != null && errors.Length > 0) certificateErrorsString = String.Join(", ", errors); diff --git a/playground/ClusterStress/Program.cs b/playground/ClusterStress/Program.cs index fcea43a3bb..a6d943c708 100644 --- a/playground/ClusterStress/Program.cs +++ b/playground/ClusterStress/Program.cs @@ -62,7 +62,7 @@ static void RunShardedBasicCommandsBenchmark(Options opts) if (!opts.SkipLoad) bench.LoadData(keyLen: opts.KeyLength, valueLen: opts.ValueLength, BatchSize: opts.BatchSize.First()); - int[] threadBench = opts.NumThreads.ToArray(); + int[] threadBench = [.. opts.NumThreads]; int keyLen = opts.KeyLength; int valueLen = opts.ValueLength; foreach (int BatchSize in opts.BatchSize) diff --git a/playground/CommandInfoUpdater/CommandDocsUpdater.cs b/playground/CommandInfoUpdater/CommandDocsUpdater.cs index 51c7fb7586..2c6d2affff 100644 --- a/playground/CommandInfoUpdater/CommandDocsUpdater.cs +++ b/playground/CommandInfoUpdater/CommandDocsUpdater.cs @@ -212,7 +212,7 @@ private static IReadOnlyDictionary GetUpdatedCommandsDo : existingCommandsDocs[command.Command].SubCommands.Select(sc => sc.Name).ToArray(); var remainingSubCommands = existingSubCommands == null ? null : command.SubCommands == null ? existingSubCommands : - existingSubCommands.Except(command.SubCommands.Keys).ToArray(); + [.. existingSubCommands.Except(command.SubCommands.Keys)]; // Create updated command docs based on existing command var existingCommandDoc = existingCommandsDocs[command.Command]; @@ -227,7 +227,7 @@ private static IReadOnlyDictionary GetUpdatedCommandsDo existingCommandDoc.Arguments, remainingSubCommands == null || remainingSubCommands.Length == 0 ? null - : existingCommandDoc.SubCommands.Where(sc => remainingSubCommands.Contains(sc.Name)).ToArray()); + : [.. existingCommandDoc.SubCommands.Where(sc => remainingSubCommands.Contains(sc.Name))]); updatedCommandsDocs.Add(updatedCommandDoc.Name, updatedCommandDoc); } @@ -267,7 +267,7 @@ private static IReadOnlyDictionary GetUpdatedCommandsDo // Update sub-commands to contain supported sub-commands only updatedSubCommandsDocs = command.SubCommands == null ? null - : baseCommandDocs.SubCommands.Where(sc => command.SubCommands.Keys.Contains(sc.Name)).ToList(); + : [.. baseCommandDocs.SubCommands.Where(sc => command.SubCommands.Keys.Contains(sc.Name))]; } // Create updated command docs based on base command & updated sub-commands diff --git a/playground/CommandInfoUpdater/CommandInfoUpdater.cs b/playground/CommandInfoUpdater/CommandInfoUpdater.cs index 60efda2511..8c68c52bf5 100644 --- a/playground/CommandInfoUpdater/CommandInfoUpdater.cs +++ b/playground/CommandInfoUpdater/CommandInfoUpdater.cs @@ -238,7 +238,7 @@ private static IReadOnlyDictionary GetUpdatedCommandsI : existingCommandsInfo[command.Command].SubCommands.Select(sc => sc.Name).ToArray(); var remainingSubCommands = existingSubCommands == null ? null : command.SubCommands == null ? existingSubCommands : - existingSubCommands.Except(command.SubCommands.Keys).ToArray(); + [.. existingSubCommands.Except(command.SubCommands.Keys)]; // Create updated command info based on existing command var existingCommand = existingCommandsInfo[command.Command]; @@ -257,7 +257,7 @@ private static IReadOnlyDictionary GetUpdatedCommandsI KeySpecifications = existingCommand.KeySpecifications, SubCommands = remainingSubCommands == null || remainingSubCommands.Length == 0 ? null - : existingCommand.SubCommands.Where(sc => remainingSubCommands.Contains(sc.Name)).ToArray() + : [.. existingCommand.SubCommands.Where(sc => remainingSubCommands.Contains(sc.Name))] }; updatedCommandsInfo.Add(updatedCommand.Name, updatedCommand); @@ -272,7 +272,7 @@ private static IReadOnlyDictionary GetUpdatedCommandsI if (existingCommandsInfo.ContainsKey(command.Command)) { updatedSubCommands = existingCommandsInfo[command.Command].SubCommands == null - ? new List() + ? [] : [.. existingCommandsInfo[command.Command].SubCommands]; // Add sub-commands with updated queried command info @@ -294,7 +294,7 @@ private static IReadOnlyDictionary GetUpdatedCommandsI // Update sub-commands to contain supported sub-commands only updatedSubCommands = command.SubCommands == null ? null - : baseCommand.SubCommands.Where(sc => command.SubCommands.ContainsKey(sc.Name)).ToList(); + : [.. baseCommand.SubCommands.Where(sc => command.SubCommands.ContainsKey(sc.Name))]; } // Create updated command info based on base command & updated sub-commands diff --git a/playground/CommandInfoUpdater/CommonUtils.cs b/playground/CommandInfoUpdater/CommonUtils.cs index 63503c8bb3..75f35ed95c 100644 --- a/playground/CommandInfoUpdater/CommonUtils.cs +++ b/playground/CommandInfoUpdater/CommonUtils.cs @@ -105,8 +105,8 @@ internal static (IDictionary, IDictionary(existingCommandsInfo[supportedCommand.Command] .SubCommands .Select(sc => sc.Name)); - subCommandsToAdd = supportedCommand.SubCommands - .Where(subCommand => !existingSubCommands.Contains(subCommand.Key)).Select(sc => sc.Value).ToArray(); + subCommandsToAdd = [.. supportedCommand.SubCommands + .Where(subCommand => !existingSubCommands.Contains(subCommand.Key)).Select(sc => sc.Value)]; } // If there are sub-commands to add, add a new supported command with the sub-commands to add diff --git a/playground/Embedded.perftest/EmbeddedPerformanceTest.cs b/playground/Embedded.perftest/EmbeddedPerformanceTest.cs index 8cf9e277f0..4fd3318b92 100644 --- a/playground/Embedded.perftest/EmbeddedPerformanceTest.cs +++ b/playground/Embedded.perftest/EmbeddedPerformanceTest.cs @@ -56,8 +56,8 @@ public EmbeddedPerformanceTest(EmbeddedRespServer server, Options opts, ILoggerF if (opts.OpPercent == null || opts.OpWorkload == null) throw new Exception("OpPercent and OpWorkload must be specified!"); - opPercent = opts.OpPercent.ToArray(); - opWorkload = opts.OpWorkload.ToArray(); + opPercent = [.. opts.OpPercent]; + opWorkload = [.. opts.OpWorkload]; if (opPercent.Length != opWorkload.Length) throw new Exception($"opPercent {opWorkload.Length} and opWorkload {opWorkload.Length} mismatch!"); diff --git a/playground/GarnetClientStress/StressTestUtil.cs b/playground/GarnetClientStress/StressTestUtil.cs index 83877aca14..4bcd4893ce 100644 --- a/playground/GarnetClientStress/StressTestUtil.cs +++ b/playground/GarnetClientStress/StressTestUtil.cs @@ -20,8 +20,7 @@ public class StressTestUtils public static string RandomValue(Random r, int valueSize) { - return new string(Enumerable.Repeat(ascii_chars, valueSize) - .Select(s => s[r.Next(s.Length)]).ToArray()); + return new string([.. Enumerable.Repeat(ascii_chars, valueSize).Select(s => s[r.Next(s.Length)])]); } public static T NotNull(T argument, string parameterName) where T : class => argument ?? throw new ArgumentNullException(parameterName); diff --git a/test/Garnet.test.cluster/ClusterMigrateTests.cs b/test/Garnet.test.cluster/ClusterMigrateTests.cs index 60fcc71586..3e9661f1c2 100644 --- a/test/Garnet.test.cluster/ClusterMigrateTests.cs +++ b/test/Garnet.test.cluster/ClusterMigrateTests.cs @@ -800,7 +800,7 @@ private string DoZCOUNT(int nodeIndex, byte[] key, out int count, out string add address = ((IPEndPoint)server.EndPoint).Address.ToString(); port = ((IPEndPoint)server.EndPoint).Port; slot = ClusterTestUtils.HashSlot(key); - return ("OK", ((RedisResult[])result).Select(x => (string)x).ToList()); + return ("OK", [.. ((RedisResult[])result).Select(x => (string)x)]); } catch (Exception e) { diff --git a/test/Garnet.test.cluster/ClusterRedirectTests.cs b/test/Garnet.test.cluster/ClusterRedirectTests.cs index cdf6607b01..887d290ad2 100644 --- a/test/Garnet.test.cluster/ClusterRedirectTests.cs +++ b/test/Garnet.test.cluster/ClusterRedirectTests.cs @@ -647,7 +647,7 @@ public void ClusterSingleKeyRedirectionTests() context.CreateInstances(Shards, cleanClusterConfig: true); context.CreateConnection(); - var connections = ClusterTestUtils.CreateLightRequestConnections(Enumerable.Range(Port, Shards).ToArray()); + var connections = ClusterTestUtils.CreateLightRequestConnections([.. Enumerable.Range(Port, Shards)]); _ = context.clusterTestUtils.SimpleSetupCluster(logger: context.logger); //1. Regular operation redirect responses @@ -712,7 +712,7 @@ public void ClusterMultiKeyRedirectionTests() context.CreateInstances(Shards, cleanClusterConfig: true); context.CreateConnection(); - var connections = ClusterTestUtils.CreateLightRequestConnections(Enumerable.Range(Port, Shards).ToArray()); + var connections = ClusterTestUtils.CreateLightRequestConnections([.. Enumerable.Range(Port, Shards)]); _ = context.clusterTestUtils.SimpleSetupCluster(logger: context.logger); //1. test regular operation redirection diff --git a/test/Garnet.test.cluster/ClusterTestUtils.cs b/test/Garnet.test.cluster/ClusterTestUtils.cs index b4002cc698..6897e2dceb 100644 --- a/test/Garnet.test.cluster/ClusterTestUtils.cs +++ b/test/Garnet.test.cluster/ClusterTestUtils.cs @@ -117,10 +117,10 @@ private void ThrowException(string msg) } public IPEndPoint[] GetEndpoints() - => endpoints.Select(x => (IPEndPoint)x).ToArray(); + => [.. endpoints.Select(x => (IPEndPoint)x)]; public IPEndPoint[] GetEndpointsWithout(IPEndPoint endPoint) => - endpoints.Select(x => (IPEndPoint)x).Where(x => x.Port != endPoint.Port || x.Address != endPoint.Address).ToArray(); + [.. endpoints.Select(x => (IPEndPoint)x).Where(x => x.Port != endPoint.Port || x.Address != endPoint.Address)]; public RedisResult Execute(IPEndPoint endPoint, string cmd, ICollection args, bool skipLogging = false, ILogger logger = null) { @@ -140,7 +140,7 @@ public RedisResult Execute(IPEndPoint endPoint, string cmd, ICollection } public RedisResult NodesV2(IPEndPoint endPoint, ILogger logger = null) - => Execute(endPoint, "cluster", new List { "nodes" }, skipLogging: true, logger); + => Execute(endPoint, "cluster", ["nodes"], skipLogging: true, logger); public string NodesMyself(IPEndPoint endPoint, ClusterInfoTag tag, ILogger logger) { @@ -246,7 +246,7 @@ public string ClusterMyId(IPEndPoint source, ILogger logger = null) private static List<(int, int)>[] GetSlotRanges(int primary_count) { - List<(int, int)>[] slotRanges = new List<(int, int)>[primary_count]; + var slotRanges = new List<(int, int)>[primary_count]; int slotCount = 16384; for (int i = 0; i < primary_count; i++) @@ -1050,7 +1050,7 @@ public void BumpEpoch(IPEndPoint endPoint, bool waitForSync = false, ILogger log public void WaitForConfigPropagation(int fromNode, List nodes = null, ILogger logger = null) { if (nodes == null) - nodes = Enumerable.Range(0, endpoints.Count).ToList(); + nodes = [.. Enumerable.Range(0, endpoints.Count)]; var fromNodeConfig = ClusterNodes(fromNode, logger: logger); while (true) { @@ -1393,7 +1393,7 @@ public List GetKeysInSlot(int nodeIndex, int slot, int keyCount, ILogger var server = redis.GetServer((IPEndPoint)endpoints[nodeIndex]); var resp = server.Execute("cluster", "getkeysinslot", $"{slot}", $"{keyCount}"); - return ((RedisResult[])resp).Select(x => Encoding.ASCII.GetBytes((string)x)).ToList(); + return [.. ((RedisResult[])resp).Select(x => Encoding.ASCII.GetBytes((string)x))]; } catch (Exception ex) { @@ -2342,7 +2342,7 @@ public string GetMultiKey(int nodeIndex, List keys, out List get try { var result = server.Execute("mget", args, CommandFlags.NoRedirect); - getResult = ((RedisResult[])result).Select(x => (byte[])x).ToList(); + getResult = [.. ((RedisResult[])result).Select(x => (byte[])x)]; return "OK"; } catch (Exception e) diff --git a/test/Garnet.test/GarnetClientTests.cs b/test/Garnet.test/GarnetClientTests.cs index 56498b2fcc..b5c38fe346 100644 --- a/test/Garnet.test/GarnetClientTests.cs +++ b/test/Garnet.test/GarnetClientTests.cs @@ -501,7 +501,7 @@ public async Task CanDoBulkDeleteTests([Values] bool useStringType) var sc = new CancellationTokenSource(); var t = sc.Token; ManualResetEventSlim mrObj = new(false); - var tDeletingK = Task.Run(async () => { await DeleteKeysWithCT(keys.Skip(iterationSize).Take(iterationSize).ToArray(), null, mrObj, t); }); + var tDeletingK = Task.Run(async () => { await DeleteKeysWithCT([.. keys.Skip(iterationSize).Take(iterationSize)], null, mrObj, t); }); // send the cancellation so the task throws an exception sc.Cancel(); @@ -530,7 +530,7 @@ public async Task CanDoBulkDeleteTests([Values] bool useStringType) ManualResetEventSlim mrObj = new(false); // try delete using Memory type - var tDeletingKeysMB = Task.Run(async () => { await DeleteKeysWithCT(null, keysMemoryByte.Skip(iterationSize).Take(iterationSize).ToArray(), mrObj, t, true); }); + var tDeletingKeysMB = Task.Run(async () => { _ = await DeleteKeysWithCT(null, [.. keysMemoryByte.Skip(iterationSize).Take(iterationSize)], mrObj, t, true); }); sc.Cancel(); mrObj.Set(); Assert.Throws(() => tDeletingKeysMB.Wait(sc.Token)); diff --git a/test/Garnet.test/HyperLogLogTests.cs b/test/Garnet.test/HyperLogLogTests.cs index 646cfd86d4..87a91ed689 100644 --- a/test/Garnet.test/HyperLogLogTests.cs +++ b/test/Garnet.test/HyperLogLogTests.cs @@ -516,7 +516,7 @@ public RedisValue[] RandomRedisValueSubseq(List list, int count) public static List ToList(RedisValue[] rss) { - return rss.Select(x => (long)x).ToList(); + return [.. rss.Select(x => (long)x)]; } [Test] diff --git a/test/Garnet.test/RespAdminCommandsTests.cs b/test/Garnet.test/RespAdminCommandsTests.cs index 7bf4f07f06..0a3bdda676 100644 --- a/test/Garnet.test/RespAdminCommandsTests.cs +++ b/test/Garnet.test/RespAdminCommandsTests.cs @@ -198,7 +198,7 @@ public void SeSaveRecoverObjectTest() { var db = redis.GetDatabase(0); db.ListLeftPush(key, ldata); - ldata = ldata.Select(x => x).Reverse().ToArray(); + ldata = [.. ldata.Select(x => x).Reverse()]; returned_data_before_recovery = db.ListRange(key); ClassicAssert.AreEqual(ldata, returned_data_before_recovery); diff --git a/test/Garnet.test/RespAofTests.cs b/test/Garnet.test/RespAofTests.cs index 9cae04773e..d8d2fbff9a 100644 --- a/test/Garnet.test/RespAofTests.cs +++ b/test/Garnet.test/RespAofTests.cs @@ -629,7 +629,7 @@ public void AofListObjectStoreRecoverTest() var count = db.ListLeftPush(key, ldata); ClassicAssert.AreEqual(4, count); - ldata = ldata.Select(x => x).Reverse().ToArray(); + ldata = [.. ldata.Select(x => x).Reverse()]; returned_data_before_recovery = db.ListRange(key); ClassicAssert.AreEqual(ldata, returned_data_before_recovery); } diff --git a/test/Garnet.test/RespCommandTests.cs b/test/Garnet.test/RespCommandTests.cs index 8059ee3c25..643d700238 100644 --- a/test/Garnet.test/RespCommandTests.cs +++ b/test/Garnet.test/RespCommandTests.cs @@ -54,7 +54,7 @@ public void Setup() public void TearDown() { server.Dispose(); - TestUtils.DeleteDirectory(TestUtils.MethodTestDir); + TestUtils.DeleteDirectory(TestUtils.MethodTestDir, wait: true); TestUtils.DeleteDirectory(Directory.GetParent(extTestDir)?.FullName); } diff --git a/test/Garnet.test/RespGetLowMemoryTests.cs b/test/Garnet.test/RespGetLowMemoryTests.cs index ff39389a7e..e7fff41990 100644 --- a/test/Garnet.test/RespGetLowMemoryTests.cs +++ b/test/Garnet.test/RespGetLowMemoryTests.cs @@ -58,7 +58,7 @@ public void ScatterGatherGet() tasks[i] = (input[offset].Value, db.StringGetAsync(input[offset].Key)); } - Task.WaitAll(tasks.Select(r => r.Item2).ToArray()); + Task.WaitAll([.. tasks.Select(r => r.Item2)]); for (int i = 0; i < numGets; i++) ClassicAssert.AreEqual(tasks[i].Item1, tasks[i].Item2.Result); } @@ -79,7 +79,7 @@ public void ScatterGatherMGet() var result = db.StringSet(input); ClassicAssert.IsTrue(result); - var results = db.StringGet(input.Select(r => (RedisKey)r.Key).ToArray()); + var results = db.StringGet([.. input.Select(r => (RedisKey)r.Key)]); for (int i = 0; i < length; i++) ClassicAssert.AreEqual(input[i].Value, results[i]); } diff --git a/test/Garnet.test/RespSetTest.cs b/test/Garnet.test/RespSetTest.cs index 59344b462d..120fe04a4f 100644 --- a/test/Garnet.test/RespSetTest.cs +++ b/test/Garnet.test/RespSetTest.cs @@ -556,7 +556,7 @@ public void CanDoSdiff(string key1, string key2) result = db.SetCombine(SetOperation.Difference, [new RedisKey(key1), new RedisKey(key2), new RedisKey(key3)]); ClassicAssert.AreEqual(2, result.Length); - strResult = result.Select(r => r.ToString()).ToArray(); + strResult = [.. result.Select(r => r.ToString())]; expectedResult = ["b", "d"]; ClassicAssert.IsTrue(expectedResult.OrderBy(t => t).SequenceEqual(strResult.OrderBy(t => t))); @@ -651,7 +651,7 @@ public void CanDoSmoveBasic(string source, string destination) ClassicAssert.IsTrue(expectedResult.OrderBy(t => t).SequenceEqual(strResult.OrderBy(t => t))); membersResult = db.SetMembers(destination); - strResult = membersResult.Select(r => r.ToString()).ToArray(); + strResult = [.. membersResult.Select(r => r.ToString())]; expectedResult = ["three", "two"]; ClassicAssert.IsTrue(expectedResult.OrderBy(t => t).SequenceEqual(strResult.OrderBy(t => t))); @@ -662,7 +662,7 @@ public void CanDoSmoveBasic(string source, string destination) ClassicAssert.IsFalse(exists); membersResult = db.SetMembers(destination); - strResult = membersResult.Select(r => r.ToString()).ToArray(); + strResult = [.. membersResult.Select(r => r.ToString())]; expectedResult = ["three", "two", "one"]; ClassicAssert.IsTrue(expectedResult.OrderBy(t => t).SequenceEqual(strResult.OrderBy(t => t))); } @@ -1571,7 +1571,7 @@ public void CheckIfMemberExistsInSetLC(string valuesInput, string findInput, str db.SetAdd(key, value); } - var actualResult = db.SetContains(key, find.Select(x => (RedisValue)x).ToArray()); + var actualResult = db.SetContains(key, [.. find.Select(x => (RedisValue)x)]); CollectionAssert.AreEqual(expectedResult, actualResult); } diff --git a/test/Garnet.test/RespSortedSetTests.cs b/test/Garnet.test/RespSortedSetTests.cs index 1742d6d107..be7cf6adb2 100644 --- a/test/Garnet.test/RespSortedSetTests.cs +++ b/test/Garnet.test/RespSortedSetTests.cs @@ -296,13 +296,13 @@ public void AddWithOptionsErrorConditions() foreach (var argCombination in argCombinations) { - args = argCombination.Union(sampleEntries).ToArray(); + args = [.. argCombination.Union(sampleEntries)]; ex = Assert.Throws(() => db.Execute("ZADD", args)); ClassicAssert.AreEqual(Encoding.ASCII.GetString(CmdStrings.RESP_ERR_GT_LT_NX_NOT_COMPATIBLE), ex.Message); } // INCR option supports only one score-element pair - args = new[] { key, "INCR" }.Union(sampleEntries).ToArray(); + args = [.. new[] { key, "INCR" }.Union(sampleEntries)]; ex = Assert.Throws(() => db.Execute("ZADD", args)); ClassicAssert.AreEqual(Encoding.ASCII.GetString(CmdStrings.RESP_ERR_INCR_SUPPORTS_ONLY_SINGLE_PAIR), ex.Message); @@ -372,7 +372,7 @@ public void AddRemove() ClassicAssert.AreEqual(expectedResponse, actualValue); // remove all entries - var removed = db.SortedSetRemove(key, entries.Select(e => e.Element).ToArray()); + var removed = db.SortedSetRemove(key, [.. entries.Select(e => e.Element)]); ClassicAssert.AreEqual(entries.Length, removed); // length should be 0 @@ -398,7 +398,7 @@ public void AddRemove() ClassicAssert.AreEqual(expectedResponse, actualValue); // remove the single entry - removed = db.SortedSetRemove(key, entries.Take(1).Select(e => e.Element).ToArray()); + removed = db.SortedSetRemove(key, [.. entries.Take(1).Select(e => e.Element)]); ClassicAssert.AreEqual(1, removed); // length should be 0 @@ -440,7 +440,7 @@ public void AddRemove() ClassicAssert.AreEqual(expectedResponse, actualValue); // remaining entries removed - removed = db.SortedSetRemove(key, entries.Select(e => e.Element).ToArray()); + removed = db.SortedSetRemove(key, [.. entries.Select(e => e.Element)]); ClassicAssert.AreEqual(entries.Length - 1, removed); keyExists = db.KeyExists(key); @@ -1435,7 +1435,7 @@ public void CanDoZInterWithSE(int numKeys, string command, string[] expectedValu { var resultWithScores = db.SortedSetCombineWithScores(SetOperation.Intersect, command.Contains("WEIGHTS") ? [new RedisKey("zset1"), new RedisKey("zset2")] : - Enumerable.Range(1, numKeys).Select(i => new RedisKey($"zset{i}")).ToArray(), + [.. Enumerable.Range(1, numKeys).Select(i => new RedisKey($"zset{i}"))], command.Contains("WEIGHTS") ? [2.0, 3.0] : null, command.Contains("MAX") ? Aggregate.Max : command.Contains("MIN") ? Aggregate.Min : Aggregate.Sum); @@ -1450,7 +1450,7 @@ public void CanDoZInterWithSE(int numKeys, string command, string[] expectedValu else { var result = db.SortedSetCombine(SetOperation.Intersect, - Enumerable.Range(1, numKeys).Select(i => new RedisKey($"zset{i}")).ToArray()); + [.. Enumerable.Range(1, numKeys).Select(i => new RedisKey($"zset{i}"))]); ClassicAssert.AreEqual(expectedValues.Length, result.Length); for (int i = 0; i < expectedValues.Length; i++) diff --git a/test/Garnet.test/RespTests.cs b/test/Garnet.test/RespTests.cs index 86c0adfa96..435f6372b8 100644 --- a/test/Garnet.test/RespTests.cs +++ b/test/Garnet.test/RespTests.cs @@ -193,7 +193,7 @@ public void MultiSetGet() var result = db.StringSet(input, When.NotExists); ClassicAssert.IsTrue(result); - var value = db.StringGet(input.Select(e => e.Key).ToArray()); + var value = db.StringGet([.. input.Select(e => e.Key)]); ClassicAssert.AreEqual(length, value.Length); for (int i = 0; i < length; i++) @@ -203,7 +203,7 @@ public void MultiSetGet() result = db.StringSet(input); ClassicAssert.IsTrue(result); - value = db.StringGet(input.Select(e => e.Key).ToArray()); + value = db.StringGet([.. input.Select(e => e.Key)]); ClassicAssert.AreEqual(length, value.Length); for (int i = 0; i < length; i++) @@ -216,7 +216,7 @@ public void MultiSetGet() result = db.StringSet(input, When.NotExists); ClassicAssert.IsFalse(result); - value = db.StringGet(input.Select(e => e.Key).ToArray()); + value = db.StringGet([.. input.Select(e => e.Key)]); ClassicAssert.AreEqual(length, value.Length); for (int i = 0; i < length; i++) @@ -229,7 +229,7 @@ public void MultiSetGet() result = db.StringSet(input, When.NotExists); ClassicAssert.IsTrue(result); - value = db.StringGet(input.Select(e => e.Key).ToArray()); + value = db.StringGet([.. input.Select(e => e.Key)]); ClassicAssert.AreEqual(length, value.Length); for (int i = 0; i < length; i++) @@ -1080,8 +1080,7 @@ public void SingleDeleteWithObjectStoreDisabled() private string GetRandomString(int len) { const string chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; - return new string(Enumerable.Repeat(chars, len) - .Select(s => s[r.Next(s.Length)]).ToArray()); + return new string([.. Enumerable.Repeat(chars, len).Select(s => s[r.Next(s.Length)])]); } [Test] diff --git a/test/Garnet.test/RespTlsTests.cs b/test/Garnet.test/RespTlsTests.cs index 7e61240516..d7e6ea0c21 100644 --- a/test/Garnet.test/RespTlsTests.cs +++ b/test/Garnet.test/RespTlsTests.cs @@ -90,7 +90,7 @@ public void TlsMultiSetGet() var result = db.StringSet(input); ClassicAssert.IsTrue(result); - var value = db.StringGet(input.Select(e => e.Key).ToArray()); + var value = db.StringGet([.. input.Select(e => e.Key)]); ClassicAssert.AreEqual(length, value.Length); for (int i = 0; i < length; i++) diff --git a/test/Garnet.test/TestProcedureHash.cs b/test/Garnet.test/TestProcedureHash.cs index 570a5f3312..cc51de2700 100644 --- a/test/Garnet.test/TestProcedureHash.cs +++ b/test/Garnet.test/TestProcedureHash.cs @@ -56,7 +56,7 @@ private static bool TestAPI(TGarnetApi api, ref CustomProcedureInput } // HSET - var status = api.HashSet(myHash, pairs.Take(pairs.Length - 2).ToArray(), out var count); + var status = api.HashSet(myHash, [.. pairs.Take(pairs.Length - 2)], out var count); if (status != GarnetStatus.OK || count != pairs.Length - 2) return false; diff --git a/test/Garnet.test/TestProcedureSet.cs b/test/Garnet.test/TestProcedureSet.cs index 17f782a8f8..2f33531bd4 100644 --- a/test/Garnet.test/TestProcedureSet.cs +++ b/test/Garnet.test/TestProcedureSet.cs @@ -51,7 +51,7 @@ private static bool TestAPI(TGarnetApi api, ref CustomProcedureInput elements[i] = GetNextArg(ref procInput, ref offset); } - var status = api.SetAdd(setA, elements.Take(9).ToArray(), out var count); + var status = api.SetAdd(setA, [.. elements.Take(9)], out var count); if (status != GarnetStatus.OK || count != 9) return false; From 5f996a00aea6c4da30882e8f3bc3cd211850846c Mon Sep 17 00:00:00 2001 From: TedHartMS <15467143+TedHartMS@users.noreply.github.com> Date: Thu, 9 Jan 2025 12:03:55 -0800 Subject: [PATCH 02/36] Collection expression fix --- libs/storage/Tsavorite/cs/test/OverflowBucketLockTableTests.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/storage/Tsavorite/cs/test/OverflowBucketLockTableTests.cs b/libs/storage/Tsavorite/cs/test/OverflowBucketLockTableTests.cs index 72f7298a79..4cb0324b69 100644 --- a/libs/storage/Tsavorite/cs/test/OverflowBucketLockTableTests.cs +++ b/libs/storage/Tsavorite/cs/test/OverflowBucketLockTableTests.cs @@ -317,7 +317,7 @@ FixedLengthLockableKeyStruct createKey() KeyHash = keyHash, }; } - return Enumerable.Range(0, numRecords).Select(ii => createKey()).ToArray(); + return [.. Enumerable.Range(0, numRecords).Select(ii => createKey())]; } void AssertSorted(FixedLengthLockableKeyStruct[] keys, int count) From 8b3d9662278ad8aff1663015163cf385346f1397 Mon Sep 17 00:00:00 2001 From: Tal Zaccai Date: Thu, 9 Jan 2025 16:29:17 -0700 Subject: [PATCH 03/36] Fixing SYSLIB0057 --- benchmark/Resp.benchmark/BenchUtils.cs | 4 ++-- libs/server/TLS/CertificateUtils.cs | 4 ++++ libs/server/TLS/GarnetTlsOptions.cs | 4 ++++ playground/GarnetClientStress/StressTestUtil.cs | 11 ++++++++++- samples/GarnetClientSample/GarnetClientSamples.cs | 11 ++++++++++- 5 files changed, 30 insertions(+), 4 deletions(-) diff --git a/benchmark/Resp.benchmark/BenchUtils.cs b/benchmark/Resp.benchmark/BenchUtils.cs index 00e462e708..e95a210bf0 100644 --- a/benchmark/Resp.benchmark/BenchUtils.cs +++ b/benchmark/Resp.benchmark/BenchUtils.cs @@ -4,10 +4,10 @@ using System.Collections.Generic; using System.Diagnostics; using System.Net.Security; -using System.Security.Cryptography.X509Certificates; using System.Text; using Garnet.common; using Garnet.server; +using Garnet.server.TLS; using StackExchange.Redis; namespace Resp.benchmark @@ -62,7 +62,7 @@ public static SslClientAuthenticationOptions GetTlsOptions(string tlsHost, strin { return new SslClientAuthenticationOptions { - ClientCertificates = [new X509Certificate2(certFile, certPassword)], + ClientCertificates = [CertificateUtils.GetMachineCertificateByFile(certFile, certPassword)], TargetHost = tlsHost, AllowRenegotiation = false, RemoteCertificateValidationCallback = (sender, certificate, chain, sslPolicyErrors) => true, diff --git a/libs/server/TLS/CertificateUtils.cs b/libs/server/TLS/CertificateUtils.cs index 672626f6e9..ddad3c5e47 100644 --- a/libs/server/TLS/CertificateUtils.cs +++ b/libs/server/TLS/CertificateUtils.cs @@ -58,7 +58,11 @@ public static X509Certificate2 GetMachineCertificateBySubjectName(string subject /// public static X509Certificate2 GetMachineCertificateByFile(string fileName, string password) { +#if NET9_0_OR_GREATER + return X509CertificateLoader.LoadPkcs12FromFile(fileName, password); +#else return new X509Certificate2(fileName, password); +#endif } } } \ No newline at end of file diff --git a/libs/server/TLS/GarnetTlsOptions.cs b/libs/server/TLS/GarnetTlsOptions.cs index 973e0630a4..68db7c8355 100644 --- a/libs/server/TLS/GarnetTlsOptions.cs +++ b/libs/server/TLS/GarnetTlsOptions.cs @@ -257,7 +257,11 @@ X509Certificate2 GetCertificateIssuer(string issuerCertificatePath) { try { +#if NET9_0_OR_GREATER + issuer = X509CertificateLoader.LoadCertificateFromFile(issuerCertificatePath); +#else issuer = new X509Certificate2(issuerCertificatePath); +#endif } catch (Exception ex) { diff --git a/playground/GarnetClientStress/StressTestUtil.cs b/playground/GarnetClientStress/StressTestUtil.cs index 4bcd4893ce..aa90ec6098 100644 --- a/playground/GarnetClientStress/StressTestUtil.cs +++ b/playground/GarnetClientStress/StressTestUtil.cs @@ -25,11 +25,20 @@ public static string RandomValue(Random r, int valueSize) public static T NotNull(T argument, string parameterName) where T : class => argument ?? throw new ArgumentNullException(parameterName); + private static X509Certificate2 GetClientCertificate(string filename, string password) + { +#if NET9_0_OR_GREATER + return X509CertificateLoader.LoadPkcs12FromFile(filename, password); +#else + return new X509Certificate2(filename, password); +#endif + } + public static SslClientAuthenticationOptions GetTlsOptions(string tlsHost) { return new SslClientAuthenticationOptions { - ClientCertificates = [new X509Certificate2("testcert.pfx", "placeholder")], + ClientCertificates = [GetClientCertificate("testcert.pfx", "placeholder")], TargetHost = tlsHost, AllowRenegotiation = false, RemoteCertificateValidationCallback = (sender, certificate, chain, sslPolicyErrors) => true, diff --git a/samples/GarnetClientSample/GarnetClientSamples.cs b/samples/GarnetClientSample/GarnetClientSamples.cs index 19882557cb..49d510925a 100644 --- a/samples/GarnetClientSample/GarnetClientSamples.cs +++ b/samples/GarnetClientSample/GarnetClientSamples.cs @@ -252,9 +252,18 @@ async Task SetGetMemoryAsync() Console.WriteLine("SetGetMemoryAsync: Success"); } + static X509Certificate2 GetClientCertificate(string filename, string password) + { +#if NET9_0_OR_GREATER + return X509CertificateLoader.LoadPkcs12FromFile(filename, password); +#else + return new X509Certificate2(filename, password); +#endif + } + SslClientAuthenticationOptions GetSslOpts() => useTLS ? new() { - ClientCertificates = [new X509Certificate2("testcert.pfx", "placeholder")], + ClientCertificates = [GetClientCertificate("testcert.pfx", "placeholder")], TargetHost = "GarnetTest", RemoteCertificateValidationCallback = (sender, certificate, chain, sslPolicyErrors) => true, } : null; From 44874e1a4b23f81cdfd4295ac80e295ecedb059d Mon Sep 17 00:00:00 2001 From: Tal Zaccai Date: Thu, 9 Jan 2025 16:48:46 -0700 Subject: [PATCH 04/36] Removing ServicePointManager --- playground/GarnetClientStress/Program.cs | 5 ----- 1 file changed, 5 deletions(-) diff --git a/playground/GarnetClientStress/Program.cs b/playground/GarnetClientStress/Program.cs index 793e6dda6f..b622bb71ce 100644 --- a/playground/GarnetClientStress/Program.cs +++ b/playground/GarnetClientStress/Program.cs @@ -24,11 +24,6 @@ static void Main(string[] args) private static void ConfigureGlobalRuntimeSettings() { ThreadPool.SetMinThreads(workerThreads: 1000, completionPortThreads: 1000); - ServicePointManager.UseNagleAlgorithm = false; - ServicePointManager.Expect100Continue = false; - ServicePointManager.CheckCertificateRevocationList = false; - ServicePointManager.DefaultConnectionLimit = 1024; - ServicePointManager.ReusePort = true; } } } \ No newline at end of file From 2340ba5aa67e1957de326d47caa9aad1dfcbb851 Mon Sep 17 00:00:00 2001 From: Tal Zaccai Date: Thu, 16 Jan 2025 14:09:02 -0700 Subject: [PATCH 05/36] Temporary fix for RedisCallErrors test failing in .net9 --- test/Garnet.test/LuaScriptTests.cs | 55 +++++++++++++++--------------- 1 file changed, 28 insertions(+), 27 deletions(-) diff --git a/test/Garnet.test/LuaScriptTests.cs b/test/Garnet.test/LuaScriptTests.cs index ace0593340..7abeb7daa2 100644 --- a/test/Garnet.test/LuaScriptTests.cs +++ b/test/Garnet.test/LuaScriptTests.cs @@ -5,6 +5,7 @@ using System.Linq; using System.Text; using System.Threading.Tasks; +using Garnet.server; using NUnit.Framework; using NUnit.Framework.Legacy; using StackExchange.Redis; @@ -534,6 +535,19 @@ public void ScriptExistsMultiple() } } + private void DoErroneousRedisCall(IDatabase db, string[] args, string expectedError) + { + // This is a temporary fix to address a regression in .NET9, an open issue can be found here - https://github.com/dotnet/runtime/issues/111242 + // Once the issue is resolved this test will fail and the #if can be removed permanently. +#if NET9_0_OR_GREATER + expectedError = "ERR Method Debug.Fail failed with 'Expected error message on the stack"; +#endif + + var exc = Assert.Throws(() => db.ScriptEvaluate($"return redis.call({string.Join(',', args)})")); + ClassicAssert.IsNotNull(exc); + StringAssert.StartsWith(expectedError, exc!.Message); + } + [Test] public void RedisCallErrors() { @@ -544,43 +558,30 @@ public void RedisCallErrors() var db = redis.GetDatabase(); // No args - { - var exc = ClassicAssert.Throws(() => db.ScriptEvaluate("return redis.call()")); - ClassicAssert.IsTrue(exc.Message.StartsWith("ERR Please specify at least one argument for this redis lib call")); - } + DoErroneousRedisCall(db, [], + Encoding.ASCII.GetString( + CmdStrings.LUA_ERR_Please_specify_at_least_one_argument_for_this_redis_lib_call)); // Unknown command - { - var exc = ClassicAssert.Throws(() => db.ScriptEvaluate("return redis.call('123')")); - ClassicAssert.IsTrue(exc.Message.StartsWith("ERR Unknown Redis command called from script")); - } + DoErroneousRedisCall(db, ["'123'"], + Encoding.ASCII.GetString(CmdStrings.LUA_ERR_Unknown_Redis_command_called_from_script)); + + var badArgumentsMessage = + Encoding.ASCII.GetString(CmdStrings + .LUA_ERR_Lua_redis_lib_command_arguments_must_be_strings_or_integers); // Bad command type - { - var exc = ClassicAssert.Throws(() => db.ScriptEvaluate("return redis.call({ foo = 'bar'})")); - ClassicAssert.IsTrue(exc.Message.StartsWith("ERR Lua redis lib command arguments must be strings or integers")); - } + DoErroneousRedisCall(db, ["{ foo = 'bar'}"], badArgumentsMessage); // GET bad arg type - { - var exc = ClassicAssert.Throws(() => db.ScriptEvaluate("return redis.call('GET', { foo = 'bar' })")); - ClassicAssert.IsTrue(exc.Message.StartsWith("ERR Lua redis lib command arguments must be strings or integers")); - } + DoErroneousRedisCall(db, ["'GET'", "{ foo = 'bar'}"], badArgumentsMessage); // SET bad arg types - { - var exc1 = ClassicAssert.Throws(() => db.ScriptEvaluate("return redis.call('SET', 'hello', { foo = 'bar' })")); - ClassicAssert.IsTrue(exc1.Message.StartsWith("ERR Lua redis lib command arguments must be strings or integers")); - - var exc2 = ClassicAssert.Throws(() => db.ScriptEvaluate("return redis.call('SET', { foo = 'bar' }, 'world')")); - ClassicAssert.IsTrue(exc2.Message.StartsWith("ERR Lua redis lib command arguments must be strings or integers")); - } + DoErroneousRedisCall(db, ["'SET'", "'hello'", "{ foo = 'bar'}"], badArgumentsMessage); + DoErroneousRedisCall(db, ["'SET'", "{ foo = 'bar'}", "'world'"], badArgumentsMessage); // Other bad arg types - { - var exc = ClassicAssert.Throws(() => db.ScriptEvaluate("return redis.call('DEL', { foo = 'bar' })")); - ClassicAssert.IsTrue(exc.Message.StartsWith("ERR Lua redis lib command arguments must be strings or integers")); - } + DoErroneousRedisCall(db, ["'DEL'", "{ foo = 'bar'}", "'world'"], badArgumentsMessage); } [Test] From 8059a3a5eddba017c897901fcf28cc6cfcbe11ea Mon Sep 17 00:00:00 2001 From: Tal Zaccai Date: Fri, 17 Jan 2025 16:39:36 -0700 Subject: [PATCH 06/36] some fixes --- .editorconfig | 3 ++- libs/common/FileUtils.cs | 4 ++-- libs/server/Custom/CustomCommandManager.cs | 4 ++-- libs/server/Custom/ExpandableMap.cs | 14 -------------- test/Garnet.test/TestUtils.cs | 10 +++++----- 5 files changed, 11 insertions(+), 24 deletions(-) diff --git a/.editorconfig b/.editorconfig index 02bfe584ee..1a4ac9d3bc 100644 --- a/.editorconfig +++ b/.editorconfig @@ -58,7 +58,7 @@ dotnet_diagnostic.IDE0303.severity = warning # Use collection expression for builder dotnet_diagnostic.IDE0304.severity = warning # Use collection expression for fluent -dotnet_diagnostic.IDE0305.severity = warning +dotnet_diagnostic.IDE0305.severity = suggestion # Miscellaneous style rules dotnet_separate_import_directive_groups = false @@ -66,6 +66,7 @@ file_header_template = Copyright (c) Microsoft Corporation.\nLicensed under the dotnet_sort_system_directives_first = true dotnet_style_predefined_type_for_locals_parameters_members = true:suggestion dotnet_style_predefined_type_for_member_access = true:suggestion +dotnet_style_prefer_collection_expression = true:suggestion # avoid this. unless absolutely necessary dotnet_style_qualification_for_field = false:suggestion diff --git a/libs/common/FileUtils.cs b/libs/common/FileUtils.cs index b926736d47..3562d0b80f 100644 --- a/libs/common/FileUtils.cs +++ b/libs/common/FileUtils.cs @@ -160,8 +160,8 @@ public static bool TryLoadAssemblies(IEnumerable assemblyPaths, out IEnu try { // NET9 seems to hold the assembly locked if it's opened from the path directly, causing tests to fail. - //assembly = AssemblyLoadContext.Default.LoadFromAssemblyPath(path); - assembly = AssemblyLoadContext.Default.LoadFromStream(new FileStream(path, FileMode.Open, FileAccess.Read)); + using var fileStream = new FileStream(path, FileMode.Open, FileAccess.Read); + assembly = AssemblyLoadContext.Default.LoadFromStream(fileStream); } catch (Exception ex) when (ex is IOException || ex is UnauthorizedAccessException || ex is NotSupportedException || ex is BadImageFormatException || diff --git a/libs/server/Custom/CustomCommandManager.cs b/libs/server/Custom/CustomCommandManager.cs index 8110bfa55e..8ea876c407 100644 --- a/libs/server/Custom/CustomCommandManager.cs +++ b/libs/server/Custom/CustomCommandManager.cs @@ -58,9 +58,9 @@ internal int Register(string name, CommandType type, CustomRawStringFunctions cu var newCmd = new CustomRawStringCommand(name, (ushort)extId, type, customFunctions, expirationTicks); var setSuccessful = rawStringCommandMap.TrySetValue(cmdId, ref newCmd); Debug.Assert(setSuccessful); - if (commandInfo != null) + if (commandInfo != null) customCommandsInfo.AddOrUpdate(name, commandInfo, (_, _) => commandInfo); - if (commandDocs != null) + if (commandDocs != null) customCommandsDocs.AddOrUpdate(name, commandDocs, (_, _) => commandDocs); return extId; } diff --git a/libs/server/Custom/ExpandableMap.cs b/libs/server/Custom/ExpandableMap.cs index 27658283ce..9e7c14b91c 100644 --- a/libs/server/Custom/ExpandableMap.cs +++ b/libs/server/Custom/ExpandableMap.cs @@ -248,20 +248,6 @@ internal bool TrySetValue(int id, ref T value, bool noExpansion, bool updateSize return true; } - /// - /// Maps map index to item ID - /// - /// Map index - /// Item ID - private int GetIdFromIndex(int index) => descIds ? minId - index : index; - - /// - /// Maps an item ID to a map index - /// - /// Item ID - /// Map index - private int GetIndexFromId(int id) => descIds ? minId - id : id; - public void Clear() { if (Map is not null) diff --git a/test/Garnet.test/TestUtils.cs b/test/Garnet.test/TestUtils.cs index 9bf375a706..c5c6e32e82 100644 --- a/test/Garnet.test/TestUtils.cs +++ b/test/Garnet.test/TestUtils.cs @@ -561,7 +561,7 @@ public static GarnetServerOptions GetGarnetServerOptions( tlsServerOptionsOverride: null, clusterTlsClientOptionsOverride: new SslClientAuthenticationOptions { - ClientCertificates = certificates ?? [new X509Certificate2(certFile, certPassword)], + ClientCertificates = certificates ?? [CertificateUtils.GetMachineCertificateByFile(certFile, certPassword)], TargetHost = "GarnetTest", AllowRenegotiation = false, RemoteCertificateValidationCallback = ValidateServerCertificate, @@ -667,7 +667,7 @@ public static ConfigurationOptions GetConfig( ( new SslClientAuthenticationOptions { - ClientCertificates = certificates ?? [new X509Certificate2(certFile, certPassword)], + ClientCertificates = certificates ?? [CertificateUtils.GetMachineCertificateByFile(certFile, certPassword)], TargetHost = "GarnetTest", AllowRenegotiation = false, RemoteCertificateValidationCallback = ValidateServerCertificate, @@ -684,7 +684,7 @@ public static GarnetClient GetGarnetClient(bool useTLS = false, bool recordLaten { sslOptions = new SslClientAuthenticationOptions { - ClientCertificates = [new X509Certificate2(certFile, certPassword)], + ClientCertificates = [CertificateUtils.GetMachineCertificateByFile(certFile, certPassword)], TargetHost = "GarnetTest", AllowRenegotiation = false, RemoteCertificateValidationCallback = ValidateServerCertificate, @@ -700,7 +700,7 @@ public static GarnetClientSession GetGarnetClientSession(bool useTLS = false, bo { sslOptions = new SslClientAuthenticationOptions { - ClientCertificates = [new X509Certificate2(certFile, certPassword)], + ClientCertificates = [CertificateUtils.GetMachineCertificateByFile(certFile, certPassword)], TargetHost = "GarnetTest", AllowRenegotiation = false, RemoteCertificateValidationCallback = ValidateServerCertificate, @@ -716,7 +716,7 @@ public static LightClientRequest CreateRequest(LightClient.OnResponseDelegateUns { sslOptions = new SslClientAuthenticationOptions { - ClientCertificates = [new X509Certificate2(certFile, certPassword)], + ClientCertificates = [CertificateUtils.GetMachineCertificateByFile(certFile, certPassword)], TargetHost = "GarnetTest", AllowRenegotiation = false, RemoteCertificateValidationCallback = ValidateServerCertificate, From 84cc8cd6131fcce3af6876e274282e6e51e1f078 Mon Sep 17 00:00:00 2001 From: darrenge Date: Wed, 22 Jan 2025 13:57:46 -0800 Subject: [PATCH 07/36] Added .net90 to CI and the Nightly GitHub Action --- .github/workflows/ci.yml | 29 +++++++++++++++++++++++------ .github/workflows/nightly.yml | 16 ++++++++++++---- 2 files changed, 35 insertions(+), 10 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 5f17bb7e4c..956e6fb7f3 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -46,15 +46,20 @@ jobs: steps: - name: Check out code uses: actions/checkout@v4 - - name: Setup .NET + - name: Setup .NET 8.0 uses: actions/setup-dotnet@v4 with: dotnet-version: 8.0.x + - name: Setup .NET 9.0 + uses: actions/setup-dotnet@v4 + with: + dotnet-version: 9.0.x - name: Install dependencies run: dotnet restore Garnet.sln - name: Check style format run: dotnet format Garnet.sln --no-restore --verify-no-changes --verbosity diagnostic + format-tsavorite: name: Format Tsavorite needs: changes @@ -63,10 +68,14 @@ jobs: steps: - name: Check out code uses: actions/checkout@v4 - - name: Setup .NET + - name: Setup .NET 8.0 uses: actions/setup-dotnet@v4 with: dotnet-version: 8.0.x + - name: Setup .NET 9.0 + uses: actions/setup-dotnet@v4 + with: + dotnet-version: 9.0.x - name: Install dependencies run: dotnet restore libs/storage/Tsavorite/cs/Tsavorite.sln - name: Check style format @@ -81,17 +90,21 @@ jobs: fail-fast: false matrix: os: [ ubuntu-latest, windows-latest ] - framework: [ 'net8.0' ] + framework: [ 'net8.0' , 'net9.0'] configuration: [ 'Debug', 'Release' ] test: [ 'Garnet.test', 'Garnet.test.cluster' ] if: needs.changes.outputs.garnet == 'true' steps: - name: Check out code uses: actions/checkout@v4 - - name: Setup .NET + - name: Setup .NET 8.0 uses: actions/setup-dotnet@v4 with: dotnet-version: 8.0.x + - name: Setup .NET 9.0 + uses: actions/setup-dotnet@v4 + with: + dotnet-version: 9.0.x - name: Install dependencies run: dotnet restore - name: Build Garnet @@ -115,7 +128,7 @@ jobs: fail-fast: false matrix: os: [ ubuntu-latest, windows-latest ] - framework: [ 'net8.0' ] + framework: [ 'net8.0', 'net9.0' ] configuration: [ 'Debug', 'Release' ] if: needs.changes.outputs.tsavorite == 'true' steps: @@ -131,10 +144,14 @@ jobs: - name: Set environment variable for Windows run: echo ("RunAzureTests=yes") >> $env:GITHUB_ENV if: ${{ matrix.os == 'windows-latest' }} - - name: Setup .NET + - name: Setup .NET 8.0 uses: actions/setup-dotnet@v4 with: dotnet-version: 8.0.x + - name: Setup .NET 9.0 + uses: actions/setup-dotnet@v4 + with: + dotnet-version: 9.0.x - name: Setup Node.js for Azurite uses: actions/setup-node@v4 with: diff --git a/.github/workflows/nightly.yml b/.github/workflows/nightly.yml index 5c9264a090..5b626c36c2 100644 --- a/.github/workflows/nightly.yml +++ b/.github/workflows/nightly.yml @@ -16,16 +16,20 @@ jobs: fail-fast: false matrix: os: [ ubuntu-22.04, ubuntu-20.04, windows-2022, windows-2019 ] - framework: [ 'net8.0' ] + framework: [ 'net8.0', 'net9.0' ] configuration: [ 'Debug', 'Release' ] test: [ 'Garnet.test', 'Garnet.test.cluster' ] steps: - name: Check out code uses: actions/checkout@v4 - - name: Setup .NET + - name: Setup .NET 8.0 uses: actions/setup-dotnet@v4 with: dotnet-version: 8.0.x + - name: Setup .NET 9.0 + uses: actions/setup-dotnet@v4 + with: + dotnet-version: 9.0.x - name: Install dependencies run: dotnet restore - name: Check style format @@ -50,7 +54,7 @@ jobs: fail-fast: false matrix: os: [ ubuntu-22.04, ubuntu-20.04, windows-2022, windows-2019 ] - framework: [ 'net8.0' ] + framework: [ 'net8.0', 'net9.0' ] configuration: [ 'Debug', 'Release' ] steps: - name: Check out code @@ -61,10 +65,14 @@ jobs: - name: Set environment variable for Windows run: echo ("RunAzureTests=yes") >> $env:GITHUB_ENV if: ${{ matrix.os == 'windows-latest' }} - - name: Setup .NET + - name: Setup .NET 8.0 uses: actions/setup-dotnet@v4 with: dotnet-version: 8.0.x + - name: Setup .NET 9.0 + uses: actions/setup-dotnet@v4 + with: + dotnet-version: 9.0.x - name: Setup Node.js for Azurite uses: actions/setup-node@v4 with: From d0d948a6a3e1d81aa715aad505c09769890f73a0 Mon Sep 17 00:00:00 2001 From: darrenge Date: Wed, 22 Jan 2025 14:15:47 -0800 Subject: [PATCH 08/36] Fixed Garnet Worker to be both .net80 and .net90 and updated ADO pipelines to use net9.0 --- .azure/pipelines/azure-pipelines-compliance.yml | 4 ++++ .azure/pipelines/azure-pipelines.yml | 11 +++++++++++ .github/workflows/ci.yml | 1 - hosting/Windows/Garnet.worker/Garnet.worker.csproj | 2 +- 4 files changed, 16 insertions(+), 2 deletions(-) diff --git a/.azure/pipelines/azure-pipelines-compliance.yml b/.azure/pipelines/azure-pipelines-compliance.yml index ef0f8eb21f..b06c37a6c9 100644 --- a/.azure/pipelines/azure-pipelines-compliance.yml +++ b/.azure/pipelines/azure-pipelines-compliance.yml @@ -21,6 +21,10 @@ jobs: displayName: 'Use .NET Core sdk 8.0.x' inputs: version: 8.0.x + - task: UseDotNet@2 + displayName: 'Use .NET Core sdk 9.0.x' + inputs: + version: 9.0.x - task: NuGetToolInstaller@1 displayName: Nuget Tool Installer inputs: diff --git a/.azure/pipelines/azure-pipelines.yml b/.azure/pipelines/azure-pipelines.yml index f0b47badd0..c4ec25e32d 100644 --- a/.azure/pipelines/azure-pipelines.yml +++ b/.azure/pipelines/azure-pipelines.yml @@ -31,6 +31,12 @@ jobs: packageType: 'sdk' version: '8.0.x' + - task: UseDotNet@2 + displayName: Use .NET 9.0 + inputs: + packageType: 'sdk' + version: '9.0.x' + - task: NodeTool@0 displayName: Node Tool inputs: @@ -118,6 +124,11 @@ jobs: inputs: packageType: 'sdk' version: '8.0.x' + - task: UseDotNet@2 + displayName: Use .NET 9.0 + inputs: + packageType: 'sdk' + version: '9.0.x' - bash: | sudo npm install -g azurite diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 956e6fb7f3..e762363db4 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -59,7 +59,6 @@ jobs: - name: Check style format run: dotnet format Garnet.sln --no-restore --verify-no-changes --verbosity diagnostic - format-tsavorite: name: Format Tsavorite needs: changes diff --git a/hosting/Windows/Garnet.worker/Garnet.worker.csproj b/hosting/Windows/Garnet.worker/Garnet.worker.csproj index ab255cf37b..92b32e2675 100644 --- a/hosting/Windows/Garnet.worker/Garnet.worker.csproj +++ b/hosting/Windows/Garnet.worker/Garnet.worker.csproj @@ -1,7 +1,7 @@  - net8.0;net9.0 + net8.0;net9.0 From 121d14f6a963b62dd526e68bbad0525bb629534a Mon Sep 17 00:00:00 2001 From: darrenge Date: Wed, 22 Jan 2025 14:49:02 -0800 Subject: [PATCH 09/36] Updated Tsav CI that runs in ADO when mirrored --- .azure/pipelines/azure-pipelines-tsavorite.yml | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/.azure/pipelines/azure-pipelines-tsavorite.yml b/.azure/pipelines/azure-pipelines-tsavorite.yml index 2a238fd6bb..5a61cf4e84 100644 --- a/.azure/pipelines/azure-pipelines-tsavorite.yml +++ b/.azure/pipelines/azure-pipelines-tsavorite.yml @@ -31,6 +31,12 @@ jobs: packageType: 'sdk' version: '8.0.x' + - task: UseDotNet@2 + displayName: Use .NET 9.0 + inputs: + packageType: 'sdk' + version: '9.0.x' + - task: NodeTool@0 displayName: Node Tool inputs: @@ -126,6 +132,12 @@ jobs: packageType: 'sdk' version: '8.0.x' + - task: UseDotNet@2 + displayName: Use .NET 9.0 + inputs: + packageType: 'sdk' + version: '9.0.x' + - bash: | sudo npm install -g azurite sudo mkdir azurite From faae98af2a1f1f3888619a484e21d96b9d9da8db Mon Sep 17 00:00:00 2001 From: Tal Zaccai Date: Wed, 22 Jan 2025 20:39:29 -0700 Subject: [PATCH 10/36] Fix to RedisCallErrors --- test/Garnet.test/LuaScriptTests.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/Garnet.test/LuaScriptTests.cs b/test/Garnet.test/LuaScriptTests.cs index 13f60ca79c..db31d45f76 100644 --- a/test/Garnet.test/LuaScriptTests.cs +++ b/test/Garnet.test/LuaScriptTests.cs @@ -558,7 +558,7 @@ private void DoErroneousRedisCall(IDatabase db, string[] args, string expectedEr // This is a temporary fix to address a regression in .NET9, an open issue can be found here - https://github.com/dotnet/runtime/issues/111242 // Once the issue is resolved this test will fail and the #if can be removed permanently. #if NET9_0_OR_GREATER - expectedError = "ERR Method Debug.Fail failed with 'Expected error message on the stack"; + expectedError = "ERR External component has thrown an exception."; #endif var exc = Assert.Throws(() => db.ScriptEvaluate($"return redis.call({string.Join(',', args)})")); From 2b672109488ec7db787979636c99265ed6d4c712 Mon Sep 17 00:00:00 2001 From: Tal Zaccai Date: Wed, 22 Jan 2025 21:00:29 -0700 Subject: [PATCH 11/36] test --- test/Garnet.test/LuaScriptTests.cs | 6 ------ 1 file changed, 6 deletions(-) diff --git a/test/Garnet.test/LuaScriptTests.cs b/test/Garnet.test/LuaScriptTests.cs index db31d45f76..2ce27b589b 100644 --- a/test/Garnet.test/LuaScriptTests.cs +++ b/test/Garnet.test/LuaScriptTests.cs @@ -555,12 +555,6 @@ public void ScriptExistsMultiple() private void DoErroneousRedisCall(IDatabase db, string[] args, string expectedError) { - // This is a temporary fix to address a regression in .NET9, an open issue can be found here - https://github.com/dotnet/runtime/issues/111242 - // Once the issue is resolved this test will fail and the #if can be removed permanently. -#if NET9_0_OR_GREATER - expectedError = "ERR External component has thrown an exception."; -#endif - var exc = Assert.Throws(() => db.ScriptEvaluate($"return redis.call({string.Join(',', args)})")); ClassicAssert.IsNotNull(exc); StringAssert.StartsWith(expectedError, exc!.Message); From 3e3ed56c6ecb71f5f44a2b4120ec6a2c626d4111 Mon Sep 17 00:00:00 2001 From: Tal Zaccai Date: Wed, 22 Jan 2025 21:19:02 -0700 Subject: [PATCH 12/36] fix --- test/Garnet.test/LuaScriptTests.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/test/Garnet.test/LuaScriptTests.cs b/test/Garnet.test/LuaScriptTests.cs index 2ce27b589b..f1a3e634a7 100644 --- a/test/Garnet.test/LuaScriptTests.cs +++ b/test/Garnet.test/LuaScriptTests.cs @@ -557,7 +557,11 @@ private void DoErroneousRedisCall(IDatabase db, string[] args, string expectedEr { var exc = Assert.Throws(() => db.ScriptEvaluate($"return redis.call({string.Join(',', args)})")); ClassicAssert.IsNotNull(exc); + // This is a temporary fix to address a regression in .NET9, an open issue can be found here - https://github.com/dotnet/runtime/issues/111242 + // Once the issue is resolved the #if can be removed permanently. +#if !NET9_0_OR_GREATER StringAssert.StartsWith(expectedError, exc!.Message); +#endif } [Test] From d94a323480b21c15de0f78b29833c982580457c4 Mon Sep 17 00:00:00 2001 From: Tal Zaccai Date: Wed, 22 Jan 2025 21:44:48 -0700 Subject: [PATCH 13/36] Skipping RedisCallErrors test --- test/Garnet.test/LuaScriptTests.cs | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/test/Garnet.test/LuaScriptTests.cs b/test/Garnet.test/LuaScriptTests.cs index f1a3e634a7..8f2a89e96b 100644 --- a/test/Garnet.test/LuaScriptTests.cs +++ b/test/Garnet.test/LuaScriptTests.cs @@ -557,16 +557,18 @@ private void DoErroneousRedisCall(IDatabase db, string[] args, string expectedEr { var exc = Assert.Throws(() => db.ScriptEvaluate($"return redis.call({string.Join(',', args)})")); ClassicAssert.IsNotNull(exc); - // This is a temporary fix to address a regression in .NET9, an open issue can be found here - https://github.com/dotnet/runtime/issues/111242 - // Once the issue is resolved the #if can be removed permanently. -#if !NET9_0_OR_GREATER StringAssert.StartsWith(expectedError, exc!.Message); -#endif } [Test] public void RedisCallErrors() { + // This is a temporary fix to address a regression in .NET9, an open issue can be found here - https://github.com/dotnet/runtime/issues/111242 + // Once the issue is resolved the #if can be removed permanently. +#if NET9_0_OR_GREATER + Assert.Ignore("Ignoring this test on .NET 9"); +#endif + // Testing that our error replies for redis.call match Redis behavior // // TODO: exact matching of the hash and line number would also be nice, but that is trickier From a74e6640208b7fddd4d1425cedb8d9268e337729 Mon Sep 17 00:00:00 2001 From: Tal Zaccai Date: Thu, 23 Jan 2025 11:52:45 -0700 Subject: [PATCH 14/36] Reverting ignored test --- test/Garnet.test/LuaScriptTests.cs | 6 ------ 1 file changed, 6 deletions(-) diff --git a/test/Garnet.test/LuaScriptTests.cs b/test/Garnet.test/LuaScriptTests.cs index 8f2a89e96b..2ce27b589b 100644 --- a/test/Garnet.test/LuaScriptTests.cs +++ b/test/Garnet.test/LuaScriptTests.cs @@ -563,12 +563,6 @@ private void DoErroneousRedisCall(IDatabase db, string[] args, string expectedEr [Test] public void RedisCallErrors() { - // This is a temporary fix to address a regression in .NET9, an open issue can be found here - https://github.com/dotnet/runtime/issues/111242 - // Once the issue is resolved the #if can be removed permanently. -#if NET9_0_OR_GREATER - Assert.Ignore("Ignoring this test on .NET 9"); -#endif - // Testing that our error replies for redis.call match Redis behavior // // TODO: exact matching of the hash and line number would also be nice, but that is trickier From 02146697096ec5df9deb39d30ba203c2ff4a8447 Mon Sep 17 00:00:00 2001 From: Tal Zaccai Date: Thu, 23 Jan 2025 11:59:04 -0700 Subject: [PATCH 15/36] Updating CI --- .github/workflows/ci.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index e762363db4..afb2269925 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -106,6 +106,9 @@ jobs: dotnet-version: 9.0.x - name: Install dependencies run: dotnet restore + - name: Set environment variables + if: ${{ matrix.framework == 'net9.0' }} + run: echo "DOTNET_LegacyExceptionHandling=1" >> $GITHUB_ENV - name: Build Garnet run: dotnet build --configuration ${{ matrix.configuration }} - name: Run tests ${{ matrix.test }} From ebd5f056008972839d84d8c307c7a7c91d9e3f96 Mon Sep 17 00:00:00 2001 From: Tal Zaccai Date: Thu, 23 Jan 2025 12:19:04 -0700 Subject: [PATCH 16/36] CI fix --- .github/workflows/ci.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index afb2269925..483712be68 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -108,6 +108,7 @@ jobs: run: dotnet restore - name: Set environment variables if: ${{ matrix.framework == 'net9.0' }} + shell: bash run: echo "DOTNET_LegacyExceptionHandling=1" >> $GITHUB_ENV - name: Build Garnet run: dotnet build --configuration ${{ matrix.configuration }} From 3fc3ffe108cd20a2fb590e472ed3d49184e2e9a6 Mon Sep 17 00:00:00 2001 From: Tal Zaccai Date: Thu, 23 Jan 2025 13:37:07 -0700 Subject: [PATCH 17/36] Ignoring RedisCallErrors test when environment variable is not set --- test/Garnet.test/LuaScriptTests.cs | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/test/Garnet.test/LuaScriptTests.cs b/test/Garnet.test/LuaScriptTests.cs index 2ce27b589b..9fde83bc5d 100644 --- a/test/Garnet.test/LuaScriptTests.cs +++ b/test/Garnet.test/LuaScriptTests.cs @@ -563,6 +563,17 @@ private void DoErroneousRedisCall(IDatabase db, string[] args, string expectedEr [Test] public void RedisCallErrors() { + // This is a temporary fix to address a regression in .NET9, an open issue can be found here - https://github.com/dotnet/runtime/issues/111242 + // Once the issue is resolved the #if can be removed permanently, as well as the environment variable setting in the CI. +#if NET9_0_OR_GREATER + var legacyExceptionHandlingEnvVarName = "DOTNET_LegacyExceptionHandling"; + var legacyExceptionHandlingEnvVarValue = Environment.GetEnvironmentVariable(legacyExceptionHandlingEnvVarName); + if (string.IsNullOrEmpty(legacyExceptionHandlingEnvVarValue)) + { + Assert.Ignore($"Ignoring test when {legacyExceptionHandlingEnvVarName} environment variable is not set."); + } +#endif + // Testing that our error replies for redis.call match Redis behavior // // TODO: exact matching of the hash and line number would also be nice, but that is trickier From 027fe0e37c582c86e8c28a89547ba6d7a0a1aebf Mon Sep 17 00:00:00 2001 From: darrenge Date: Fri, 24 Jan 2025 14:30:07 -0800 Subject: [PATCH 18/36] Added net90 to the external release pipeline. Required changed to publish profile. GitHub release section working now. Need to finish Nuget. The actual GH Release task and Nuget Push are disabled at this point. --- .../azure-pipelines-external-release.yml | 10 +- .azure/pipelines/createbinaries.ps1 | 111 +++++++++++++----- .../PublishProfiles/linux-arm64-based.pubxml | 32 +++-- .../PublishProfiles/linux-x64-based.pubxml | 10 +- .../PublishProfiles/osx-arm64-based.pubxml | 11 +- .../PublishProfiles/osx-x64-based.pubxml | 11 +- .../PublishProfiles/portable.pubxml | 11 +- .../win-arm64-based-readytorun.pubxml | 11 +- .../win-x64-based-readytorun.pubxml | 11 +- 9 files changed, 161 insertions(+), 57 deletions(-) diff --git a/.azure/pipelines/azure-pipelines-external-release.yml b/.azure/pipelines/azure-pipelines-external-release.yml index a5f8317435..2f8bcfd146 100644 --- a/.azure/pipelines/azure-pipelines-external-release.yml +++ b/.azure/pipelines/azure-pipelines-external-release.yml @@ -41,6 +41,10 @@ jobs: displayName: Use .NET Core sdk 8.0.x inputs: version: 8.0.x + - task: UseDotNet@2 + displayName: Use .NET Core sdk 9.0.x + inputs: + version: 9.0.x - task: DotNetCoreCLI@2 displayName: dotnet build @@ -152,10 +156,10 @@ jobs: workingDirectory: .azure/pipelines - task: CopyFiles@2 - displayName: 'Copy Zipped Files to Artifacts dir: $(Build.artifactstagingdirectory)' + displayName: 'Copy Zipped Files (both net80 and net90 in zipped file) to Artifacts dir: $(Build.artifactstagingdirectory)' inputs: Contents: '**' - SourceFolder: '$(Build.SourcesDirectory)/main/GarnetServer/bin/Release/net8.0/publish/output' + SourceFolder: '$(Build.SourcesDirectory)/main/GarnetServer/bin/Release/publish/output' TargetFolder: $(build.artifactstagingdirectory) - task: PublishBuildArtifacts@1 @@ -163,6 +167,7 @@ jobs: - task: GitHubRelease@1 displayName: 'Create the GitHub release' + enabled: false inputs: action: 'create' gitHubConnection: ADO_to_Github_ServiceConnection @@ -188,6 +193,7 @@ jobs: - task: NuGetCommand@2 displayName: 'Push both packages to NuGet.org' + enabled: false inputs: command: push packagesToPush: '$(Build.ArtifactStagingDirectory)/**/*.nupkg' diff --git a/.azure/pipelines/createbinaries.ps1 b/.azure/pipelines/createbinaries.ps1 index 2b8e4e9aca..d35cd7abf4 100644 --- a/.azure/pipelines/createbinaries.ps1 +++ b/.azure/pipelines/createbinaries.ps1 @@ -31,13 +31,13 @@ param ( ################## CleanUpFiles ##################### # -# Publishes the files and clean it up so only the necessary files will be ready to be zipped +# After build is published, this cleans it up so only the necessary files will be ready to be zipped # ###################################################### function CleanUpFiles { - param ($publishFolder, $platform) + param ($publishFolder, $platform, $framework) - $publishPath = "$basePath/main/GarnetServer/bin/Release/net8.0/publish/$publishFolder" + $publishPath = "$basePath/main/GarnetServer/bin/Release/$framework/publish/$publishFolder" $garnetServerEXE = "$publishPath/GarnetServer.exe" $excludeGarnetServerPDB = 'GarnetServer.pdb' @@ -85,46 +85,93 @@ Set-Location $basePath/main/GarnetServer if ($mode -eq 0 -or $mode -eq 1) { Write-Host "** Publish ... **" dotnet publish GarnetServer.csproj -p:PublishProfile=linux-arm64-based -f:net8.0 - dotnet publish GarnetServer.csproj -p:PublishProfile=linux-x64-based -f:net8.0 - dotnet publish GarnetServer.csproj -p:PublishProfile=osx-arm64-based -f:net8.0 - dotnet publish GarnetServer.csproj -p:PublishProfile=osx-x64-based -f:net8.0 - dotnet publish GarnetServer.csproj -p:PublishProfile=portable -f:net8.0 - dotnet publish GarnetServer.csproj -p:PublishProfile=win-arm64-based-readytorun -f:net8.0 - dotnet publish GarnetServer.csproj -p:PublishProfile=win-x64-based-readytorun -f:net8.0 + dotnet publish GarnetServer.csproj -p:PublishProfile=linux-x64-based -f:net8.0 + dotnet publish GarnetServer.csproj -p:PublishProfile=osx-arm64-based -f:net8.0 + dotnet publish GarnetServer.csproj -p:PublishProfile=osx-x64-based -f:net8.0 + dotnet publish GarnetServer.csproj -p:PublishProfile=portable -f:net8.0 + dotnet publish GarnetServer.csproj -p:PublishProfile=win-arm64-based-readytorun -f:net8.0 + dotnet publish GarnetServer.csproj -p:PublishProfile=win-x64-based-readytorun -f:net8.0 + + dotnet publish GarnetServer.csproj -p:PublishProfile=linux-arm64-based -f:net9.0 + dotnet publish GarnetServer.csproj -p:PublishProfile=linux-x64-based -f:net9.0 + dotnet publish GarnetServer.csproj -p:PublishProfile=osx-arm64-based -f:net9.0 + dotnet publish GarnetServer.csproj -p:PublishProfile=osx-x64-based -f:net9.0 + dotnet publish GarnetServer.csproj -p:PublishProfile=portable -f:net9.0 + dotnet publish GarnetServer.csproj -p:PublishProfile=win-arm64-based-readytorun -f:net9.0 + dotnet publish GarnetServer.csproj -p:PublishProfile=win-x64-based-readytorun -f:net9.0 # Clean up all the extra files - CleanUpFiles "linux-arm64" "linux-x64" - CleanUpFiles "linux-x64" "linux-x64" - CleanUpFiles "osx-arm64" "linux-x64" - CleanUpFiles "osx-x64" "linux-x64" - #CleanUpFiles "portable" "win-x64" # don't clean up all files for portable ... leave as is - CleanUpFiles "win-x64" "win-x64" - CleanUpFiles "win-arm64" "win-x64" + CleanUpFiles "linux-arm64" "linux-x64" "net8.0" + CleanUpFiles "linux-x64" "linux-x64" "net8.0" + CleanUpFiles "osx-arm64" "linux-x64" "net8.0" + CleanUpFiles "osx-x64" "linux-x64" "net8.0" + #CleanUpFiles "portable" "win-x64" "net8.0" # don't clean up all files for portable ... leave as is + CleanUpFiles "win-x64" "win-x64" "net8.0" + CleanUpFiles "win-arm64" "win-x64" "net8.0" + + CleanUpFiles "linux-arm64" "linux-x64" "net9.0" + CleanUpFiles "linux-x64" "linux-x64" "net9.0" + CleanUpFiles "osx-arm64" "linux-x64" "net9.0" + CleanUpFiles "osx-x64" "linux-x64" "net9.0" + #CleanUpFiles "portable" "win-x64" "net9.0" # don't clean up all files for portable ... leave as is + CleanUpFiles "win-x64" "win-x64" "net9.0" + CleanUpFiles "win-arm64" "win-x64" "net9.0" } if ($mode -eq 0 -or $mode -eq 2) { - # Make sure the publish folder exists as basic check files are actually published before trying to zip - $publishedFilesFolder = "$basePath/main/GarnetServer/bin/Release/net8.0/publish" - if (!(Test-Path $publishedFilesFolder)) { - Write-Error "$publishedFilesFolder does not exist. Run .\CreateBinaries 1 to publish the binaries first." + # Make sure at publish folders are there as basic check files are actually published before trying to zip + $publishedFilesFolderNet8 = "$basePath/main/GarnetServer/bin/Release/net8.0/publish" + $publishedFilesFolderNet9 = "$basePath/main/GarnetServer/bin/Release/net9.0/publish" + + if (!(Test-Path $publishedFilesFolderNet8) -or !(Test-Path $publishedFilesFolderNet9)) { + Write-Error "$publishedFilesFolderNet8 or $publishedFilesFolderNet9 does not exist. Run .\CreateBinaries 1 to publish the binaries first." + Set-Location $lastPwd exit } - - # Create the directories - if (!(Test-Path $basePath/main/GarnetServer/bin/Release/net8.0/publish/output)) { - mkdir $basePath/main/GarnetServer/bin/Release/net8.0/publish/output + + # Create the directories - both net80 and net90 will be in the same zip file. + $directories = @("linux-arm64", "linux-x64", "osx-arm64", "osx-x64", "portable", "win-arm64", "win-x64") + $sourceFramework = @("net8.0", "net9.0") + $baseSourcePath = "$basePath/main/GarnetServer/bin/Release" + $destinationPath = "$basePath/main/GarnetServer/bin/Release/publish" + + # Make all the directories needed + if (!(Test-Path $destinationPath)) { + mkdir "$destinationPath/output" + } + Set-Location "$destinationPath/output" + + foreach ($dir in $directories) { + if (!(Test-Path (Join-Path -Path $destinationPath -ChildPath $dir))) { + mkdir (Join-Path -Path $destinationPath -ChildPath $dir) + } } - Set-Location $basePath/main/GarnetServer/bin/Release/net8.0/publish/output - # Compress the files + foreach ($dir in $directories) { + foreach ($version in $sourceFramework) { + $sourcePath = Join-Path -Path $baseSourcePath -ChildPath "$version\publish\$dir" + $destDirPath = Join-Path -Path $destinationPath -ChildPath $dir + $destVersionPath = Join-Path -Path $destDirPath -ChildPath $version + + if (!(Test-Path $destVersionPath)) { + mkdir $destVersionPath + } + + Copy-Item -Path "$sourcePath\*" -Destination $destVersionPath -Recurse -Force + } + } + + Set-Location "$destinationPath/output" + + # Compress the files - both net80 and net90 in the same zip file Write-Host "** Compressing the files ... **" - 7z a -mmt20 -mx5 -scsWIN win-x64-based-readytorun.zip ../win-x64/* - 7z a -mmt20 -mx5 -scsWIN win-arm64-based-readytorun.zip ../win-arm64/* - 7z a -scsUTF-8 linux-x64-based.tar ../linux-x64/* - 7z a -scsUTF-8 linux-arm64-based.tar ../linux-arm64/* - 7z a -scsUTF-8 osx-x64-based.tar ../osx-x64/* - 7z a -scsUTF-8 osx-arm64-based.tar ../osx-arm64/* + 7z a -mmt20 -mx5 -scsWIN -r win-x64-based-readytorun.zip ../win-x64/* + 7z a -mmt20 -mx5 -scsWIN -r win-arm64-based-readytorun.zip ../win-arm64/* + 7z a -scsUTF-8 -r linux-x64-based.tar ../linux-x64/* + 7z a -scsUTF-8 -r linux-arm64-based.tar ../linux-arm64/* + 7z a -scsUTF-8 -r osx-x64-based.tar ../osx-x64/* + 7z a -scsUTF-8 -r osx-arm64-based.tar ../osx-arm64/* 7z a -mmt20 -mx5 -sdel linux-x64-based.tar.xz linux-x64-based.tar 7z a -mmt20 -mx5 -sdel linux-arm64-based.tar.xz linux-arm64-based.tar 7z a -mmt20 -mx5 -sdel osx-x64-based.tar.xz osx-x64-based.tar diff --git a/main/GarnetServer/Properties/PublishProfiles/linux-arm64-based.pubxml b/main/GarnetServer/Properties/PublishProfiles/linux-arm64-based.pubxml index f3fcef046b..5d2e057b2d 100644 --- a/main/GarnetServer/Properties/PublishProfiles/linux-arm64-based.pubxml +++ b/main/GarnetServer/Properties/PublishProfiles/linux-arm64-based.pubxml @@ -3,15 +3,23 @@ https://go.microsoft.com/fwlink/?LinkID=208121. --> - - Release - Any CPU - bin\Release\net8.0\publish\linux-arm64\ - FileSystem - <_TargetId>Folder - net8.0 - linux-arm64 - false - true - - \ No newline at end of file + + Release + Any CPU + FileSystem + <_TargetId>Folder + net8.0;net9.0 + linux-arm64 + false + true + + + + bin\Release\net8.0\publish\linux-arm64\ + + + + bin\Release\net9.0\publish\linux-arm64\ + + + diff --git a/main/GarnetServer/Properties/PublishProfiles/linux-x64-based.pubxml b/main/GarnetServer/Properties/PublishProfiles/linux-x64-based.pubxml index 49c61f6121..b81d7b436c 100644 --- a/main/GarnetServer/Properties/PublishProfiles/linux-x64-based.pubxml +++ b/main/GarnetServer/Properties/PublishProfiles/linux-x64-based.pubxml @@ -9,9 +9,17 @@ https://go.microsoft.com/fwlink/?LinkID=208121. bin\Release\net8.0\publish\linux-x64\ FileSystem <_TargetId>Folder - net8.0 + net8.0;net9.0 linux-x64 false true + + + bin\Release\net8.0\publish\linux-x64\ + + + + bin\Release\net9.0\publish\linux-x64\ + \ No newline at end of file diff --git a/main/GarnetServer/Properties/PublishProfiles/osx-arm64-based.pubxml b/main/GarnetServer/Properties/PublishProfiles/osx-arm64-based.pubxml index a8ede61b7a..539c32a94c 100644 --- a/main/GarnetServer/Properties/PublishProfiles/osx-arm64-based.pubxml +++ b/main/GarnetServer/Properties/PublishProfiles/osx-arm64-based.pubxml @@ -6,12 +6,19 @@ https://go.microsoft.com/fwlink/?LinkID=208121. Release Any CPU - bin\Release\net8.0\publish\osx-arm64\ FileSystem <_TargetId>Folder - net8.0 + net8.0;net9.0 osx-arm64 false true + + + bin\Release\net8.0\publish\osx-arm64\ + + + + bin\Release\net9.0\publish\osx-arm64\ + \ No newline at end of file diff --git a/main/GarnetServer/Properties/PublishProfiles/osx-x64-based.pubxml b/main/GarnetServer/Properties/PublishProfiles/osx-x64-based.pubxml index 14715051d3..385acfa711 100644 --- a/main/GarnetServer/Properties/PublishProfiles/osx-x64-based.pubxml +++ b/main/GarnetServer/Properties/PublishProfiles/osx-x64-based.pubxml @@ -6,12 +6,19 @@ https://go.microsoft.com/fwlink/?LinkID=208121. Release Any CPU - bin\Release\net8.0\publish\osx-x64\ FileSystem <_TargetId>Folder - net8.0 + net8.0;net9.0 osx-x64 false true + + + bin\Release\net8.0\publish\osx-x64\ + + + + bin\Release\net9.0\publish\osx-x64\ + \ No newline at end of file diff --git a/main/GarnetServer/Properties/PublishProfiles/portable.pubxml b/main/GarnetServer/Properties/PublishProfiles/portable.pubxml index a48466510a..ccf19e6a15 100644 --- a/main/GarnetServer/Properties/PublishProfiles/portable.pubxml +++ b/main/GarnetServer/Properties/PublishProfiles/portable.pubxml @@ -6,10 +6,17 @@ https://go.microsoft.com/fwlink/?LinkID=208121. Release Any CPU - bin\Release\net8.0\publish\portable\ FileSystem <_TargetId>Folder - net8.0 + net8.0;net9.0 false + + + bin\Release\net8.0\publish\portable\ + + + + bin\Release\net9.0\publish\portable\ + \ No newline at end of file diff --git a/main/GarnetServer/Properties/PublishProfiles/win-arm64-based-readytorun.pubxml b/main/GarnetServer/Properties/PublishProfiles/win-arm64-based-readytorun.pubxml index c02cd8414f..a2cf6e89f1 100644 --- a/main/GarnetServer/Properties/PublishProfiles/win-arm64-based-readytorun.pubxml +++ b/main/GarnetServer/Properties/PublishProfiles/win-arm64-based-readytorun.pubxml @@ -6,13 +6,20 @@ https://go.microsoft.com/fwlink/?LinkID=208121. Release Any CPU - bin\Release\net8.0\publish\win-arm64\ FileSystem <_TargetId>Folder - net8.0 + net8.0;net9.0 win-arm64 false true true + + + bin\Release\net8.0\publish\win-arm64\ + + + + bin\Release\net9.0\publish\win-arm64\ + \ No newline at end of file diff --git a/main/GarnetServer/Properties/PublishProfiles/win-x64-based-readytorun.pubxml b/main/GarnetServer/Properties/PublishProfiles/win-x64-based-readytorun.pubxml index 0dbb866b72..645e8752f5 100644 --- a/main/GarnetServer/Properties/PublishProfiles/win-x64-based-readytorun.pubxml +++ b/main/GarnetServer/Properties/PublishProfiles/win-x64-based-readytorun.pubxml @@ -6,13 +6,20 @@ https://go.microsoft.com/fwlink/?LinkID=208121. Release Any CPU - bin\Release\net8.0\publish\win-x64\ FileSystem <_TargetId>Folder - net8.0 + net8.0;net9.0 win-x64 false true true + + + bin\Release\net8.0\publish\win-x64\ + + + + bin\Release\net9.0\publish\win-x64\ + \ No newline at end of file From 0d668ecc05c0d5b6289d2dd2d60a318fb4816088 Mon Sep 17 00:00:00 2001 From: darrenge Date: Fri, 24 Jan 2025 14:54:40 -0800 Subject: [PATCH 19/36] Fixed bug in compressed file directory --- .azure/pipelines/createbinaries.ps1 | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/.azure/pipelines/createbinaries.ps1 b/.azure/pipelines/createbinaries.ps1 index d35cd7abf4..5a5e615c34 100644 --- a/.azure/pipelines/createbinaries.ps1 +++ b/.azure/pipelines/createbinaries.ps1 @@ -135,12 +135,13 @@ if ($mode -eq 0 -or $mode -eq 2) { $sourceFramework = @("net8.0", "net9.0") $baseSourcePath = "$basePath/main/GarnetServer/bin/Release" $destinationPath = "$basePath/main/GarnetServer/bin/Release/publish" + $zipfiledestinationPath = "$destinationPath/output" - # Make all the directories needed - if (!(Test-Path $destinationPath)) { - mkdir "$destinationPath/output" + # Make the destination path where the compressed files will be + if (!(Test-Path $zipfiledestinationPath)) { + mkdir $zipfiledestinationPath } - Set-Location "$destinationPath/output" + Set-Location $zipfiledestinationPath foreach ($dir in $directories) { if (!(Test-Path (Join-Path -Path $destinationPath -ChildPath $dir))) { From 2cedd73245598aaa1fbe873bb04fbc8a112aac6a Mon Sep 17 00:00:00 2001 From: darrenge Date: Fri, 24 Jan 2025 15:20:22 -0800 Subject: [PATCH 20/36] Another try on fixing the destination directory issue --- .azure/pipelines/createbinaries.ps1 | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.azure/pipelines/createbinaries.ps1 b/.azure/pipelines/createbinaries.ps1 index 5a5e615c34..8abfd35c20 100644 --- a/.azure/pipelines/createbinaries.ps1 +++ b/.azure/pipelines/createbinaries.ps1 @@ -138,6 +138,9 @@ if ($mode -eq 0 -or $mode -eq 2) { $zipfiledestinationPath = "$destinationPath/output" # Make the destination path where the compressed files will be + if (!(Test-Path $destinationPath)) { + mkdir $destinationPath + } if (!(Test-Path $zipfiledestinationPath)) { mkdir $zipfiledestinationPath } @@ -163,8 +166,6 @@ if ($mode -eq 0 -or $mode -eq 2) { } } - Set-Location "$destinationPath/output" - # Compress the files - both net80 and net90 in the same zip file Write-Host "** Compressing the files ... **" 7z a -mmt20 -mx5 -scsWIN -r win-x64-based-readytorun.zip ../win-x64/* From c82efda526174e3936fd1bcf7d483e71c8ac7261 Mon Sep 17 00:00:00 2001 From: darrenge Date: Wed, 29 Jan 2025 15:58:18 -0800 Subject: [PATCH 21/36] Added CodeQL.yml which is custom so it works with net90 as well. Updated GarnetHost to get all the runtimes --- .github/workflows/codeql.yml | 104 +++++++++++++++++++++++++++++++++++ libs/host/Garnet.host.csproj | 4 +- 2 files changed, 107 insertions(+), 1 deletion(-) create mode 100644 .github/workflows/codeql.yml diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml new file mode 100644 index 0000000000..9448aba251 --- /dev/null +++ b/.github/workflows/codeql.yml @@ -0,0 +1,104 @@ +# +# Auto generated YML file to run CodeQL except for build steps at the bottom which needed to be manual since using net90 +# +name: "CodeQL Advanced" + +on: + push: + branches: [ "main" ] + pull_request: + branches: [ "main" ] + schedule: + - cron: '38 11 * * 1' + +jobs: + analyze: + name: Analyze (${{ matrix.language }}) + # Runner size impacts CodeQL analysis time. To learn more, please see: + # - https://gh.io/recommended-hardware-resources-for-running-codeql + # - https://gh.io/supported-runners-and-hardware-resources + # - https://gh.io/using-larger-runners (GitHub.com only) + # Consider using larger runners or machines with greater resources for possible analysis time improvements. + runs-on: ubuntu-latest + permissions: + # required for all workflows + security-events: write + + # required to fetch internal or private CodeQL packs + packages: read + + # only required for workflows in private repositories + actions: read + contents: read + + strategy: + fail-fast: false + matrix: + include: + - language: csharp + build-mode: manual + - language: javascript-typescript + build-mode: none + # CodeQL supports the following values keywords for 'language': 'c-cpp', 'csharp', 'go', 'java-kotlin', 'javascript-typescript', 'python', 'ruby', 'swift' + # Use `c-cpp` to analyze code written in C, C++ or both + # Use 'java-kotlin' to analyze code written in Java, Kotlin or both + # Use 'javascript-typescript' to analyze code written in JavaScript, TypeScript or both + # To learn more about changing the languages that are analyzed or customizing the build mode for your analysis, + # see https://docs.github.com/en/code-security/code-scanning/creating-an-advanced-setup-for-code-scanning/customizing-your-advanced-setup-for-code-scanning. + # If you are analyzing a compiled language, you can modify the 'build-mode' for that language to customize how + # your codebase is analyzed, see https://docs.github.com/en/code-security/code-scanning/creating-an-advanced-setup-for-code-scanning/codeql-code-scanning-for-compiled-languages + steps: + - name: Check if manual build mode + if: ${{ matrix.build-mode == 'manual' }} + run: echo "Manual build mode detected" + + - name: Checkout repository + uses: actions/checkout@v4 + + # Initializes the CodeQL tools for scanning. + - name: Initialize CodeQL + uses: github/codeql-action/init@v3 + with: + languages: ${{ matrix.language }} + build-mode: ${{ matrix.build-mode }} + # If you wish to specify custom queries, you can do so here or in a config file. + # By default, queries listed here will override any specified in a config file. + # Prefix the list here with "+" to use these queries and those in the config file. + + # For more details on CodeQL's query packs, refer to: https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs + # queries: security-extended,security-and-quality + + # If the analyze step fails for one of the languages you are analyzing with + # "We were unable to automatically build your code", modify the matrix above + # to set the build mode to "manual" for that language. Then modify this step + # to build your code. + # ℹ️ Command-line programs to run using the OS shell. + # 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun + - name: Setup .NET 8.0 + if: ${{ matrix.build-mode == 'manual' }} + uses: actions/setup-dotnet@v4 + with: + dotnet-version: 8.0.x + + - name: Setup .NET 9.0 + if: ${{ matrix.build-mode == 'manual' }} + uses: actions/setup-dotnet@v4 + with: + dotnet-version: 9.0.x + + - name: Install dependencies + if: ${{ matrix.build-mode == 'manual' }} + run: dotnet restore + + - name: Build Garnet net80 + if: ${{ matrix.build-mode == 'manual' }} + run: dotnet build -f net8.0 + + - name: Build Garnet net90 + if: ${{ matrix.build-mode == 'manual' }} + run: dotnet build -f net9.0 + + - name: Perform CodeQL Analysis + uses: github/codeql-action/analyze@v3 + with: + category: "/language:${{matrix.language}}" diff --git a/libs/host/Garnet.host.csproj b/libs/host/Garnet.host.csproj index 94d1909678..b4e663b03e 100644 --- a/libs/host/Garnet.host.csproj +++ b/libs/host/Garnet.host.csproj @@ -43,7 +43,9 @@ - + + + From 37e1cbdb09d1f7e08749791834dc06e8f947d4c5 Mon Sep 17 00:00:00 2001 From: darrenge Date: Thu, 30 Jan 2025 10:41:20 -0800 Subject: [PATCH 22/36] Set RunTImes to only be packed once since they are C++ and not dependent on framework --- libs/host/Garnet.host.csproj | 2 -- 1 file changed, 2 deletions(-) diff --git a/libs/host/Garnet.host.csproj b/libs/host/Garnet.host.csproj index b4e663b03e..d76359ff5c 100644 --- a/libs/host/Garnet.host.csproj +++ b/libs/host/Garnet.host.csproj @@ -43,8 +43,6 @@ - - From 078c297b8f98bdeb685b31211fe573be64458ba7 Mon Sep 17 00:00:00 2001 From: Tal Zaccai Date: Thu, 30 Jan 2025 12:49:19 -0700 Subject: [PATCH 23/36] Fixed broken merge --- libs/server/Custom/ExpandableMap.cs | 7 ------- 1 file changed, 7 deletions(-) diff --git a/libs/server/Custom/ExpandableMap.cs b/libs/server/Custom/ExpandableMap.cs index 126d7a9561..3960f4fb01 100644 --- a/libs/server/Custom/ExpandableMap.cs +++ b/libs/server/Custom/ExpandableMap.cs @@ -232,13 +232,6 @@ private bool TrySetValueUnsafe(int id, ref T value, bool noExpansion) TryUpdateActualSize(id); return true; } - - public void Clear() - { - if (Map is not null) - Array.Clear(Map); - ActualSize = 0; - } } /// From 039499fd6bf1c01ba2984f90f26b02a6bb28484b Mon Sep 17 00:00:00 2001 From: darrenge Date: Thu, 30 Jan 2025 14:20:12 -0800 Subject: [PATCH 24/36] Added WorkFlow dispatch and commented out net90 --- .github/workflows/codeql.yml | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index 9448aba251..a812f03b1f 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -4,6 +4,7 @@ name: "CodeQL Advanced" on: + workflow_dispatch: push: branches: [ "main" ] pull_request: @@ -80,11 +81,11 @@ jobs: with: dotnet-version: 8.0.x - - name: Setup .NET 9.0 - if: ${{ matrix.build-mode == 'manual' }} - uses: actions/setup-dotnet@v4 - with: - dotnet-version: 9.0.x + #- name: Setup .NET 9.0 + # if: ${{ matrix.build-mode == 'manual' }} + # uses: actions/setup-dotnet@v4 + # with: + # dotnet-version: 9.0.x - name: Install dependencies if: ${{ matrix.build-mode == 'manual' }} @@ -94,9 +95,9 @@ jobs: if: ${{ matrix.build-mode == 'manual' }} run: dotnet build -f net8.0 - - name: Build Garnet net90 - if: ${{ matrix.build-mode == 'manual' }} - run: dotnet build -f net9.0 + # - name: Build Garnet net90 + # if: ${{ matrix.build-mode == 'manual' }} + # run: dotnet build -f net9.0 - name: Perform CodeQL Analysis uses: github/codeql-action/analyze@v3 From 9f3b2a6444d3cd8de2a6d494f1d0394ed59e07ca Mon Sep 17 00:00:00 2001 From: darrenge Date: Thu, 30 Jan 2025 14:29:03 -0800 Subject: [PATCH 25/36] Added net90 to CodeQL --- .github/workflows/codeql.yml | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index a812f03b1f..67d37846db 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -81,11 +81,11 @@ jobs: with: dotnet-version: 8.0.x - #- name: Setup .NET 9.0 - # if: ${{ matrix.build-mode == 'manual' }} - # uses: actions/setup-dotnet@v4 - # with: - # dotnet-version: 9.0.x + - name: Setup .NET 9.0 + if: ${{ matrix.build-mode == 'manual' }} + uses: actions/setup-dotnet@v4 + with: + dotnet-version: 9.0.x - name: Install dependencies if: ${{ matrix.build-mode == 'manual' }} @@ -95,9 +95,9 @@ jobs: if: ${{ matrix.build-mode == 'manual' }} run: dotnet build -f net8.0 - # - name: Build Garnet net90 - # if: ${{ matrix.build-mode == 'manual' }} - # run: dotnet build -f net9.0 + - name: Build Garnet net90 + if: ${{ matrix.build-mode == 'manual' }} + run: dotnet build -f net9.0 - name: Perform CodeQL Analysis uses: github/codeql-action/analyze@v3 From ff9e9e4417309c96775167e9698310bcd79feb27 Mon Sep 17 00:00:00 2001 From: darrenge Date: Thu, 30 Jan 2025 14:45:32 -0800 Subject: [PATCH 26/36] Enabled the Create GH Release and Push Nuget packages tasks so it is all ready to go when merged --- .azure/pipelines/azure-pipelines-external-release.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.azure/pipelines/azure-pipelines-external-release.yml b/.azure/pipelines/azure-pipelines-external-release.yml index 2f8bcfd146..141a3f1c61 100644 --- a/.azure/pipelines/azure-pipelines-external-release.yml +++ b/.azure/pipelines/azure-pipelines-external-release.yml @@ -167,7 +167,6 @@ jobs: - task: GitHubRelease@1 displayName: 'Create the GitHub release' - enabled: false inputs: action: 'create' gitHubConnection: ADO_to_Github_ServiceConnection @@ -193,7 +192,6 @@ jobs: - task: NuGetCommand@2 displayName: 'Push both packages to NuGet.org' - enabled: false inputs: command: push packagesToPush: '$(Build.ArtifactStagingDirectory)/**/*.nupkg' From 9cbe7f5cef6c38258d419ce852fdcb9e050f6953 Mon Sep 17 00:00:00 2001 From: Tal Zaccai Date: Tue, 18 Feb 2025 15:44:31 -0800 Subject: [PATCH 27/36] format --- libs/cluster/Server/ClusterProvider.cs | 2 +- libs/common/HashSlotUtils.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/libs/cluster/Server/ClusterProvider.cs b/libs/cluster/Server/ClusterProvider.cs index ede739bf71..f2278b278a 100644 --- a/libs/cluster/Server/ClusterProvider.cs +++ b/libs/cluster/Server/ClusterProvider.cs @@ -263,7 +263,7 @@ public MetricsItem[] GetReplicationInfo() if (!serverOptions.EnableCluster) { return (replicationManager.ReplicationOffset, default); - }; + } return (replicationManager.ReplicationOffset, replicationManager.GetReplicaInfo()); } diff --git a/libs/common/HashSlotUtils.cs b/libs/common/HashSlotUtils.cs index 99cf67aa26..3fbb6a6c25 100644 --- a/libs/common/HashSlotUtils.cs +++ b/libs/common/HashSlotUtils.cs @@ -102,7 +102,7 @@ public static unsafe ushort HashSlot(byte* keyPtr, int ksize) var end = keyPtr + ksize; // Find first occurence of '{' - while (startPtr < end && *startPtr != '{') { startPtr++; }; + while (startPtr < end && *startPtr != '{') { startPtr++; } // Return early if did not find '{' if (startPtr == end) return (ushort)(Hash(keyPtr, ksize) & 16383); From 1554339467833d629f8ffe1107a3743d9bf7ded7 Mon Sep 17 00:00:00 2001 From: Tal Zaccai Date: Tue, 18 Feb 2025 15:56:29 -0800 Subject: [PATCH 28/36] format --- libs/storage/Tsavorite/cs/test/DeltaLogTests.cs | 3 ++- .../storage/Tsavorite/cs/test/LockableUnsafeContextTests.cs | 6 ++++-- libs/storage/Tsavorite/cs/test/ReproReadCacheTest.cs | 3 ++- 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/libs/storage/Tsavorite/cs/test/DeltaLogTests.cs b/libs/storage/Tsavorite/cs/test/DeltaLogTests.cs index 8637dff556..d502fbd46d 100644 --- a/libs/storage/Tsavorite/cs/test/DeltaLogTests.cs +++ b/libs/storage/Tsavorite/cs/test/DeltaLogTests.cs @@ -78,7 +78,8 @@ public void DeltaLogTest1([Values] TestUtils.DeviceType deviceType) ClassicAssert.AreEqual(len, _len); for (int j = 0; j < len; j++) { - unsafe { ClassicAssert.AreEqual((byte)_len, *(byte*)(address + j)); }; + unsafe { ClassicAssert.AreEqual((byte)_len, *(byte*)(address + j)); } + ; } } ClassicAssert.AreEqual(TotalCount, i, $"i={i} and TotalCount={TotalCount}"); diff --git a/libs/storage/Tsavorite/cs/test/LockableUnsafeContextTests.cs b/libs/storage/Tsavorite/cs/test/LockableUnsafeContextTests.cs index f49401afb3..54e0452d30 100644 --- a/libs/storage/Tsavorite/cs/test/LockableUnsafeContextTests.cs +++ b/libs/storage/Tsavorite/cs/test/LockableUnsafeContextTests.cs @@ -1336,7 +1336,8 @@ void updater(int key, int iter) default: Assert.Fail($"Unexpected updateOp {updateOp}"); return; - }; + } + ; ClassicAssert.IsFalse(status.IsFaulted, $"Unexpected UpdateOp {updateOp}, status {status}"); } catch (Exception) @@ -1477,7 +1478,8 @@ void updater(int key, int iter) default: Assert.Fail($"Unexpected updateOp {updateOp}"); return; - }; + } + ; ClassicAssert.IsFalse(status.IsFaulted, $"Unexpected UpdateOp {updateOp}, status {status}"); lastUpdaterKeys[2] = key; } diff --git a/libs/storage/Tsavorite/cs/test/ReproReadCacheTest.cs b/libs/storage/Tsavorite/cs/test/ReproReadCacheTest.cs index 6881d5e9a1..dbacbc5332 100644 --- a/libs/storage/Tsavorite/cs/test/ReproReadCacheTest.cs +++ b/libs/storage/Tsavorite/cs/test/ReproReadCacheTest.cs @@ -78,7 +78,8 @@ public void Setup() kvSettings.ReadCachePageSize = 1L << 12; kvSettings.ReadCacheSecondChanceFraction = 0.1; kvSettings.ReadCacheEnabled = true; - }; + } + ; continue; } if (arg is DeviceType deviceType) From e633959a77cbc74cf4c44e0b475f3879606a803a Mon Sep 17 00:00:00 2001 From: darrenge Date: Wed, 19 Feb 2025 15:08:47 -0800 Subject: [PATCH 29/36] Added 9.0 to dot net restore. Not for test matrix but for build. --- .github/workflows/ci-bdnbenchmark.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci-bdnbenchmark.yml b/.github/workflows/ci-bdnbenchmark.yml index a0b6921562..fcbafd2997 100644 --- a/.github/workflows/ci-bdnbenchmark.yml +++ b/.github/workflows/ci-bdnbenchmark.yml @@ -49,7 +49,9 @@ jobs: - name: Setup .NET uses: actions/setup-dotnet@v4 with: - dotnet-version: 8.0.x + dotnet-version: | + 8.0.x + 9.0.x - name: Install dependencies run: dotnet restore From f15a60d275335c0aa7061597b8f44597df441d2a Mon Sep 17 00:00:00 2001 From: darrenge Date: Thu, 20 Feb 2025 08:59:22 -0800 Subject: [PATCH 30/36] Updated BDN expected values --- test/BDNPerfTests/BDN_Benchmark_Config.json | 30 ++++++++++----------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/test/BDNPerfTests/BDN_Benchmark_Config.json b/test/BDNPerfTests/BDN_Benchmark_Config.json index da7782f563..1ab74d73b6 100644 --- a/test/BDNPerfTests/BDN_Benchmark_Config.json +++ b/test/BDNPerfTests/BDN_Benchmark_Config.json @@ -50,7 +50,7 @@ "expected_HSetNx_AOF": 9600, "expected_HStrLen_AOF": 6400, "expected_HVals_AOF": 3200, - "expected_HSetDel_None": 16000, + "expected_HSetDel_None": 100000, "expected_HExists_None": 6400, "expected_HGet_None": 6400, "expected_HGetAll_None": 3200, @@ -81,7 +81,7 @@ "expected_ZMScore_ACL": 0, "expected_ZPopMax_ACL": 6400, "expected_ZPopMin_ACL": 6400, - "expected_ZRandMember_ACL": 1184, + "expected_ZRandMember_ACL": 6005, "expected_ZRange_ACL": 0, "expected_ZRangeStore_ACL": 0, "expected_ZRank_ACL": 0, @@ -108,7 +108,7 @@ "expected_ZPopMax_AOF": 48001, "expected_ZPopMin_AOF": 48001, "expected_ZRandMember_AOF": 1184, - "expected_ZRange_AOF": 28000, + "expected_ZRange_AOF": 209588, "expected_ZRangeStore_AOF": 12800, "expected_ZRank_AOF": 13600, "expected_ZRemRangeByLex_AOF": 111201, @@ -126,7 +126,7 @@ "expected_ZDiffStore_None": 27200, "expected_ZIncrby_None": 12000, "expected_ZInter_None": 34400, - "expected_ZInterCard_None": 34400, + "expected_ZInterCard_None": 222071, "expected_ZInterStore_None": 79200, "expected_ZLexCount_None": 66400, "expected_ZMPop_None": 59201, @@ -233,7 +233,7 @@ "expected_Digest_Managed,None": 1984, "expected_LookupHit_Native,None": 1984, "expected_LookupMiss_Native,None": 1984, - "expected_LoadOuterHit_Native,None": 1984, + "expected_LoadOuterHit_Native,None": 2700, "expected_LoadInnerHit_Native,None": 2350, "expected_LoadMiss_Native,None": 1984, "expected_Digest_Native,None": 1984, @@ -303,40 +303,40 @@ "expected_Eval_Managed,Limit": 0, "expected_EvalSha_Managed,Limit": 0, "expected_SmallScript_Managed,Limit": 0, - "expected_LargeScript_Managed,Limit": 16, - "expected_ArrayReturn_Managed,Limit": 0, + "expected_LargeScript_Managed,Limit": 22, + "expected_ArrayReturn_Managed,Limit": 1, "expected_ScriptLoad_Managed,None": 9600, "expected_ScriptExistsTrue_Managed,None": 0, "expected_ScriptExistsFalse_Managed,None": 0, "expected_Eval_Managed,None": 0, "expected_EvalSha_Managed,None": 0, "expected_SmallScript_Managed,None": 0, - "expected_LargeScript_Managed,None": 16, - "expected_ArrayReturn_Managed,None": 0, + "expected_LargeScript_Managed,None": 26, + "expected_ArrayReturn_Managed,None": 1, "expected_ScriptLoad_Native,None": 9600, "expected_ScriptExistsTrue_Native,None": 0, "expected_ScriptExistsFalse_Native,None": 0, "expected_Eval_Native,None": 0, "expected_EvalSha_Native,None": 0, "expected_SmallScript_Native,None": 0, - "expected_LargeScript_Native,None": 16, - "expected_ArrayReturn_Native,None": 0, + "expected_LargeScript_Native,None": 26, + "expected_ArrayReturn_Native,None": 1, "expected_ScriptLoad_Tracked,Limit": 9600, "expected_ScriptExistsTrue_Tracked,Limit": 0, "expected_ScriptExistsFalse_Tracked,Limit": 0, "expected_Eval_Tracked,Limit": 0, "expected_EvalSha_Tracked,Limit": 0, "expected_SmallScript_Tracked,Limit": 0, - "expected_LargeScript_Tracked,Limit": 31, - "expected_ArrayReturn_Tracked,Limit": 0, + "expected_LargeScript_Tracked,Limit": 48, + "expected_ArrayReturn_Tracked,Limit": 1, "expected_ScriptLoad_Tracked,None": 9600, "expected_ScriptExistsTrue_Tracked,None": 0, "expected_ScriptExistsFalse_Tracked,None": 0, "expected_Eval_Tracked,None": 0, "expected_EvalSha_Tracked,None": 0, "expected_SmallScript_Tracked,None": 0, - "expected_LargeScript_Tracked,None": 31, - "expected_ArrayReturn_Tracked,None": 0 + "expected_LargeScript_Tracked,None": 52, + "expected_ArrayReturn_Tracked,None": 1 }, "BDN.benchmark.Operations.ModuleOperations.*": { "expected_ModuleNoOpRawStringReadCommand_ACL": 0, From fbfd10bd3e218cb8c6de34dfea3fb0973cc53b50 Mon Sep 17 00:00:00 2001 From: darrenge Date: Thu, 20 Feb 2025 10:35:13 -0800 Subject: [PATCH 31/36] Trying to run BDN on net90 framework. --- .github/workflows/ci-bdnbenchmark.yml | 2 +- test/BDNPerfTests/BDN_Benchmark_Config.json | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/ci-bdnbenchmark.yml b/.github/workflows/ci-bdnbenchmark.yml index fcbafd2997..77fb2588d6 100644 --- a/.github/workflows/ci-bdnbenchmark.yml +++ b/.github/workflows/ci-bdnbenchmark.yml @@ -40,7 +40,7 @@ jobs: fail-fast: false matrix: os: [ ubuntu-latest, windows-latest ] - framework: [ 'net8.0' ] + framework: [ 'net8.0', 'net9.0' ] configuration: [ 'Release' ] test: [ 'Operations.BasicOperations', 'Operations.ObjectOperations', 'Operations.HashObjectOperations', 'Operations.SortedSetOperations', 'Cluster.ClusterMigrate', 'Cluster.ClusterOperations', 'Lua.LuaScripts', 'Lua.LuaScriptCacheOperations','Lua.LuaRunnerOperations','Operations.CustomOperations', 'Operations.RawStringOperations', 'Operations.ScriptOperations', 'Operations.ModuleOperations', 'Operations.PubSubOperations', 'Network.BasicOperations', 'Network.RawStringOperations' ] steps: diff --git a/test/BDNPerfTests/BDN_Benchmark_Config.json b/test/BDNPerfTests/BDN_Benchmark_Config.json index 1ab74d73b6..20675dc5e6 100644 --- a/test/BDNPerfTests/BDN_Benchmark_Config.json +++ b/test/BDNPerfTests/BDN_Benchmark_Config.json @@ -58,8 +58,8 @@ "expected_HIncrbyFloat_None": 14400, "expected_HKeys_None": 3200, "expected_HLen_None": 3200, - "expected_HMGet_None": 9600, - "expected_HMSet_None": 16000, + "expected_HMGet_None": 67000, + "expected_HMSet_None": 114000, "expected_HRandField_None": 8800, "expected_HScan_None": 776, "expected_HSetNx_None": 9600, @@ -100,7 +100,7 @@ "expected_ZDiffStore_AOF": 27200, "expected_ZIncrby_AOF": 12000, "expected_ZInter_AOF": 34400, - "expected_ZInterCard_AOF": 34400, + "expected_ZInterCard_AOF": 212000, "expected_ZInterStore_AOF": 123200, "expected_ZLexCount_AOF": 66400, "expected_ZMPop_AOF": 59201, @@ -192,7 +192,7 @@ "expected_ConstructSmall_Managed,Limit": 2097602, "expected_ConstructLarge_Managed,Limit": 2100666, "expected_CompileForSessionSmall_Managed,Limit": 1984, - "expected_CompileForSessionLarge_Managed,Limit": 1984, + "expected_CompileForSessionLarge_Managed,Limit": 3000, "expected_ResetParametersSmall_Managed,None": 1984, "expected_ResetParametersLarge_Managed,None": 1984, "expected_ConstructSmall_Managed,None": 2097674, @@ -303,7 +303,7 @@ "expected_Eval_Managed,Limit": 0, "expected_EvalSha_Managed,Limit": 0, "expected_SmallScript_Managed,Limit": 0, - "expected_LargeScript_Managed,Limit": 22, + "expected_LargeScript_Managed,Limit": 26, "expected_ArrayReturn_Managed,Limit": 1, "expected_ScriptLoad_Managed,None": 9600, "expected_ScriptExistsTrue_Managed,None": 0, From 752eddc2dd402ed5d15b4896ea1a43244b578f5f Mon Sep 17 00:00:00 2001 From: darrenge Date: Thu, 20 Feb 2025 13:11:15 -0800 Subject: [PATCH 32/36] Updated values because of the new Net90 BDN test runs --- test/BDNPerfTests/BDN_Benchmark_Config.json | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/test/BDNPerfTests/BDN_Benchmark_Config.json b/test/BDNPerfTests/BDN_Benchmark_Config.json index 20675dc5e6..e6dad4ed5b 100644 --- a/test/BDNPerfTests/BDN_Benchmark_Config.json +++ b/test/BDNPerfTests/BDN_Benchmark_Config.json @@ -95,7 +95,7 @@ "expected_ZUnionStore_ACL": 0, "expected_ZAddRem_AOF": 18400, "expected_ZCard_AOF": 3200, - "expected_ZCount_AOF": 20000, + "expected_ZCount_AOF": 135000, "expected_ZDiff_AOF": 25600, "expected_ZDiffStore_AOF": 27200, "expected_ZIncrby_AOF": 12000, @@ -127,13 +127,13 @@ "expected_ZIncrby_None": 12000, "expected_ZInter_None": 34400, "expected_ZInterCard_None": 222071, - "expected_ZInterStore_None": 79200, + "expected_ZInterStore_None": 537000, "expected_ZLexCount_None": 66400, "expected_ZMPop_None": 59201, "expected_ZMScore_None": 6400, "expected_ZPopMax_None": 48001, "expected_ZPopMin_None": 48001, - "expected_ZRandMember_None": 1184, + "expected_ZRandMember_None": 7150, "expected_ZRange_None": 28000, "expected_ZRangeStore_None": 12800, "expected_ZRank_None": 13600, @@ -327,7 +327,7 @@ "expected_Eval_Tracked,Limit": 0, "expected_EvalSha_Tracked,Limit": 0, "expected_SmallScript_Tracked,Limit": 0, - "expected_LargeScript_Tracked,Limit": 48, + "expected_LargeScript_Tracked,Limit": 1800, "expected_ArrayReturn_Tracked,Limit": 1, "expected_ScriptLoad_Tracked,None": 9600, "expected_ScriptExistsTrue_Tracked,None": 0, @@ -345,7 +345,7 @@ "expected_ModuleNoOpObjReadCommand_ACL": 3200, "expected_ModuleNoOpProc_ACL": 0, "expected_ModuleNoOpTxn_ACL": 0, - "expected_ModuleJsonGetCommand_ACL": 72800, + "expected_ModuleJsonGetCommand_ACL": 400000, "expected_ModuleJsonSetCommand_ACL": 223200, "expected_ModuleNoOpRawStringReadCommand_AOF": 0, "expected_ModuleNoOpRawStringRmwCommand_AOF": 0, @@ -353,8 +353,8 @@ "expected_ModuleNoOpObjReadCommand_AOF": 3200, "expected_ModuleNoOpProc_AOF": 0, "expected_ModuleNoOpTxn_AOF": 0, - "expected_ModuleJsonGetCommand_AOF": 72800, - "expected_ModuleJsonSetCommand_AOF": 223200, + "expected_ModuleJsonGetCommand_AOF": 405000, + "expected_ModuleJsonSetCommand_AOF": 1550000, "expected_ModuleNoOpRawStringReadCommand_None": 0, "expected_ModuleNoOpRawStringRmwCommand_None": 0, "expected_ModuleNoOpObjRmwCommand_None": 3200, From 2aca4b436b7c2b9c21f4ac31e64ed4838dd96eef Mon Sep 17 00:00:00 2001 From: darrenge Date: Thu, 20 Feb 2025 14:28:19 -0800 Subject: [PATCH 33/36] Update some of the expected in the Operations.SortedSetOperations BDN to handle Net 9.0 --- test/BDNPerfTests/BDN_Benchmark_Config.json | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/test/BDNPerfTests/BDN_Benchmark_Config.json b/test/BDNPerfTests/BDN_Benchmark_Config.json index e6dad4ed5b..2328cdb5a1 100644 --- a/test/BDNPerfTests/BDN_Benchmark_Config.json +++ b/test/BDNPerfTests/BDN_Benchmark_Config.json @@ -96,7 +96,7 @@ "expected_ZAddRem_AOF": 18400, "expected_ZCard_AOF": 3200, "expected_ZCount_AOF": 135000, - "expected_ZDiff_AOF": 25600, + "expected_ZDiff_AOF": 147000, "expected_ZDiffStore_AOF": 27200, "expected_ZIncrby_AOF": 12000, "expected_ZInter_AOF": 34400, @@ -119,7 +119,7 @@ "expected_ZScore_AOF": 6400, "expected_ZUnion_AOF": 34400, "expected_ZUnionStore_AOF": 129600, - "expected_ZAddRem_None": 18400, + "expected_ZAddRem_None": 119000, "expected_ZCard_None": 3200, "expected_ZCount_None": 20000, "expected_ZDiff_None": 25600, @@ -134,8 +134,8 @@ "expected_ZPopMax_None": 48001, "expected_ZPopMin_None": 48001, "expected_ZRandMember_None": 7150, - "expected_ZRange_None": 28000, - "expected_ZRangeStore_None": 12800, + "expected_ZRange_None": 181000, + "expected_ZRangeStore_None": 572000, "expected_ZRank_None": 13600, "expected_ZRemRangeByLex_None": 111201, "expected_ZRemRangeByRank_None": 84801, @@ -143,7 +143,7 @@ "expected_ZRevRank_None": 13600, "expected_ZScan_None": 776, "expected_ZScore_None": 6400, - "expected_ZUnion_None": 34400, + "expected_ZUnion_None": 220000, "expected_ZUnionStore_None": 84800 }, "BDN.benchmark.Cluster.ClusterOperations.*": { From 5f81eae43320342de88032f864b6cceefa84e91d Mon Sep 17 00:00:00 2001 From: darrenge Date: Thu, 20 Feb 2025 15:45:27 -0800 Subject: [PATCH 34/36] Getting net90 expected values narrowed down. Just seems to be a couple that are a bit variant. --- test/BDNPerfTests/BDN_Benchmark_Config.json | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/test/BDNPerfTests/BDN_Benchmark_Config.json b/test/BDNPerfTests/BDN_Benchmark_Config.json index 2328cdb5a1..fc79c08598 100644 --- a/test/BDNPerfTests/BDN_Benchmark_Config.json +++ b/test/BDNPerfTests/BDN_Benchmark_Config.json @@ -1,7 +1,7 @@ { "_comment": "NOTE: If adding a new BDN perf test to this file, you will need to add the name to the test: line in ci-bdnbenchmark.yml (~line 45). This ensures all the tests are not ran sequentially when ran as github action.", "_comment2": "NOTE: The BDN Perf name in the ci-bdnbenchmark.yml file test: line should NOT have the BDN.benchmark prefix and the .* ending. It needs to be this way for the reporting part of the BDN Charts.", - "_comment3": "NOTE: The expected values are the Allocated results from BDN tests.", + "_comment3": "NOTE: The expected values are the Allocated results from BDN tests. The values listed here are used for Windows / Linux and Net 8.0 and Net 9.0. In the case where one configuration is higher, set that higher value here.", "BDN.benchmark.Operations.BasicOperations.*": { "expected_InlinePing_ACL": 0, @@ -43,7 +43,7 @@ "expected_HIncrbyFloat_AOF": 14400, "expected_HKeys_AOF": 3200, "expected_HLen_AOF": 3200, - "expected_HMGet_AOF": 9600, + "expected_HMGet_AOF": 64000, "expected_HMSet_AOF": 16000, "expected_HRandField_AOF": 8800, "expected_HScan_AOF": 776, @@ -121,11 +121,11 @@ "expected_ZUnionStore_AOF": 129600, "expected_ZAddRem_None": 119000, "expected_ZCard_None": 3200, - "expected_ZCount_None": 20000, - "expected_ZDiff_None": 25600, + "expected_ZCount_None": 130000, + "expected_ZDiff_None": 179000, "expected_ZDiffStore_None": 27200, "expected_ZIncrby_None": 12000, - "expected_ZInter_None": 34400, + "expected_ZInter_None": 224000, "expected_ZInterCard_None": 222071, "expected_ZInterStore_None": 537000, "expected_ZLexCount_None": 66400, @@ -227,7 +227,7 @@ "expected_Digest_Managed,Limit": 2000, "expected_LookupHit_Managed,None": 1984, "expected_LookupMiss_Managed,None": 1984, - "expected_LoadOuterHit_Managed,None": 1984, + "expected_LoadOuterHit_Managed,None": 3000, "expected_LoadInnerHit_Managed,None": 2097760, "expected_LoadMiss_Managed,None": 2000, "expected_Digest_Managed,None": 1984, From 2cf0856dafca9f6e32671ac35aca7f15aeaf912c Mon Sep 17 00:00:00 2001 From: darrenge Date: Fri, 21 Feb 2025 15:52:16 -0800 Subject: [PATCH 35/36] Fixed a bug in the BDN script and updated expected values. --- test/BDNPerfTests/BDN_Benchmark_Config.json | 78 ++++++++++----------- test/BDNPerfTests/run_bdnperftest.ps1 | 3 +- 2 files changed, 41 insertions(+), 40 deletions(-) diff --git a/test/BDNPerfTests/BDN_Benchmark_Config.json b/test/BDNPerfTests/BDN_Benchmark_Config.json index fc79c08598..feaf448261 100644 --- a/test/BDNPerfTests/BDN_Benchmark_Config.json +++ b/test/BDNPerfTests/BDN_Benchmark_Config.json @@ -31,7 +31,7 @@ "expected_HMGet_ACL": 0, "expected_HMSet_ACL": 0, "expected_HRandField_ACL": 0, - "expected_HScan_ACL": 776, + "expected_HScan_ACL": 5100, "expected_HSetNx_ACL": 0, "expected_HStrLen_ACL": 0, "expected_HVals_ACL": 0, @@ -43,26 +43,26 @@ "expected_HIncrbyFloat_AOF": 14400, "expected_HKeys_AOF": 3200, "expected_HLen_AOF": 3200, - "expected_HMGet_AOF": 64000, + "expected_HMGet_AOF": 76000, "expected_HMSet_AOF": 16000, "expected_HRandField_AOF": 8800, - "expected_HScan_AOF": 776, - "expected_HSetNx_AOF": 9600, - "expected_HStrLen_AOF": 6400, + "expected_HScan_AOF": 4900, + "expected_HSetNx_AOF": 69000, + "expected_HStrLen_AOF": 47000, "expected_HVals_AOF": 3200, - "expected_HSetDel_None": 100000, + "expected_HSetDel_None": 120000, "expected_HExists_None": 6400, "expected_HGet_None": 6400, "expected_HGetAll_None": 3200, - "expected_HIncrby_None": 14400, + "expected_HIncrby_None": 58400, "expected_HIncrbyFloat_None": 14400, "expected_HKeys_None": 3200, "expected_HLen_None": 3200, "expected_HMGet_None": 67000, "expected_HMSet_None": 114000, "expected_HRandField_None": 8800, - "expected_HScan_None": 776, - "expected_HSetNx_None": 9600, + "expected_HScan_None": 4500, + "expected_HSetNx_None": 74000, "expected_HStrLen_None": 6400, "expected_HVals_None": 3200 }, @@ -81,7 +81,7 @@ "expected_ZMScore_ACL": 0, "expected_ZPopMax_ACL": 6400, "expected_ZPopMin_ACL": 6400, - "expected_ZRandMember_ACL": 6005, + "expected_ZRandMember_ACL": 7400, "expected_ZRange_ACL": 0, "expected_ZRangeStore_ACL": 0, "expected_ZRank_ACL": 0, @@ -96,10 +96,10 @@ "expected_ZAddRem_AOF": 18400, "expected_ZCard_AOF": 3200, "expected_ZCount_AOF": 135000, - "expected_ZDiff_AOF": 147000, + "expected_ZDiff_AOF": 303000, "expected_ZDiffStore_AOF": 27200, "expected_ZIncrby_AOF": 12000, - "expected_ZInter_AOF": 34400, + "expected_ZInter_AOF": 221000, "expected_ZInterCard_AOF": 212000, "expected_ZInterStore_AOF": 123200, "expected_ZLexCount_AOF": 66400, @@ -107,25 +107,25 @@ "expected_ZMScore_AOF": 6400, "expected_ZPopMax_AOF": 48001, "expected_ZPopMin_AOF": 48001, - "expected_ZRandMember_AOF": 1184, + "expected_ZRandMember_AOF": 6900, "expected_ZRange_AOF": 209588, - "expected_ZRangeStore_AOF": 12800, - "expected_ZRank_AOF": 13600, + "expected_ZRangeStore_AOF": 580000, + "expected_ZRank_AOF": 100000, "expected_ZRemRangeByLex_AOF": 111201, "expected_ZRemRangeByRank_AOF": 84801, "expected_ZRemRangeByScore_AOF": 84001, - "expected_ZRevRank_AOF": 13600, - "expected_ZScan_AOF": 776, + "expected_ZRevRank_AOF": 87600, + "expected_ZScan_AOF": 4800, "expected_ZScore_AOF": 6400, - "expected_ZUnion_AOF": 34400, - "expected_ZUnionStore_AOF": 129600, - "expected_ZAddRem_None": 119000, + "expected_ZUnion_AOF": 260000, + "expected_ZUnionStore_AOF": 452600, + "expected_ZAddRem_None": 149000, "expected_ZCard_None": 3200, - "expected_ZCount_None": 130000, + "expected_ZCount_None": 150000, "expected_ZDiff_None": 179000, "expected_ZDiffStore_None": 27200, "expected_ZIncrby_None": 12000, - "expected_ZInter_None": 224000, + "expected_ZInter_None": 250000, "expected_ZInterCard_None": 222071, "expected_ZInterStore_None": 537000, "expected_ZLexCount_None": 66400, @@ -134,17 +134,17 @@ "expected_ZPopMax_None": 48001, "expected_ZPopMin_None": 48001, "expected_ZRandMember_None": 7150, - "expected_ZRange_None": 181000, + "expected_ZRange_None": 320000, "expected_ZRangeStore_None": 572000, - "expected_ZRank_None": 13600, + "expected_ZRank_None": 86000, "expected_ZRemRangeByLex_None": 111201, "expected_ZRemRangeByRank_None": 84801, "expected_ZRemRangeByScore_None": 84001, - "expected_ZRevRank_None": 13600, + "expected_ZRevRank_None": 80000, "expected_ZScan_None": 776, "expected_ZScore_None": 6400, "expected_ZUnion_None": 220000, - "expected_ZUnionStore_None": 84800 + "expected_ZUnionStore_None": 528000 }, "BDN.benchmark.Cluster.ClusterOperations.*": { "expected_Get_DSV": 0, @@ -193,7 +193,7 @@ "expected_ConstructLarge_Managed,Limit": 2100666, "expected_CompileForSessionSmall_Managed,Limit": 1984, "expected_CompileForSessionLarge_Managed,Limit": 3000, - "expected_ResetParametersSmall_Managed,None": 1984, + "expected_ResetParametersSmall_Managed,None": 3000, "expected_ResetParametersLarge_Managed,None": 1984, "expected_ConstructSmall_Managed,None": 2097674, "expected_ConstructLarge_Managed,None": 2100738, @@ -201,21 +201,21 @@ "expected_CompileForSessionLarge_Managed,None": 1984, "expected_ResetParametersSmall_Native,None": 1984, "expected_ResetParametersLarge_Native,None": 1984, - "expected_ConstructSmall_Native,None": 2400, + "expected_ConstructSmall_Native,None": 3024, "expected_ConstructLarge_Native,None": 5500, "expected_CompileForSessionSmall_Native,None": 2000, "expected_CompileForSessionLarge_Native,None": 1984, "expected_ResetParametersSmall_Tracked,Limit": 1984, "expected_ResetParametersLarge_Tracked,Limit": 1984, "expected_ConstructSmall_Tracked,Limit": 2400, - "expected_ConstructLarge_Tracked,Limit": 5500, + "expected_ConstructLarge_Tracked,Limit": 6500, "expected_CompileForSessionSmall_Tracked,Limit": 1984, "expected_CompileForSessionLarge_Tracked,Limit": 1984, "expected_ResetParametersSmall_Tracked,None": 1984, "expected_ResetParametersLarge_Tracked,None": 1984, "expected_ConstructSmall_Tracked,None": 2400, "expected_ConstructLarge_Tracked,None": 5500, - "expected_CompileForSessionSmall_Tracked,None": 1984, + "expected_CompileForSessionSmall_Tracked,None": 3000, "expected_CompileForSessionLarge_Tracked,None": 1984 }, "BDN.benchmark.Lua.LuaScriptCacheOperations.*": { @@ -236,12 +236,12 @@ "expected_LoadOuterHit_Native,None": 2700, "expected_LoadInnerHit_Native,None": 2350, "expected_LoadMiss_Native,None": 1984, - "expected_Digest_Native,None": 1984, + "expected_Digest_Native,None": 3000, "expected_LookupHit_Tracked,Limit": 2000, "expected_LookupMiss_Tracked,Limit": 2000, - "expected_LoadOuterHit_Tracked,Limit": 1984, + "expected_LoadOuterHit_Tracked,Limit": 3000, "expected_LoadInnerHit_Tracked,Limit": 2350, - "expected_LoadMiss_Tracked,Limit": 1984, + "expected_LoadMiss_Tracked,Limit": 2700, "expected_Digest_Tracked,Limit": 1984, "expected_LookupHit_Tracked,None": 1984, "expected_LookupMiss_Tracked,None": 1984, @@ -327,7 +327,7 @@ "expected_Eval_Tracked,Limit": 0, "expected_EvalSha_Tracked,Limit": 0, "expected_SmallScript_Tracked,Limit": 0, - "expected_LargeScript_Tracked,Limit": 1800, + "expected_LargeScript_Tracked,Limit": 2800, "expected_ArrayReturn_Tracked,Limit": 1, "expected_ScriptLoad_Tracked,None": 9600, "expected_ScriptExistsTrue_Tracked,None": 0, @@ -335,22 +335,22 @@ "expected_Eval_Tracked,None": 0, "expected_EvalSha_Tracked,None": 0, "expected_SmallScript_Tracked,None": 0, - "expected_LargeScript_Tracked,None": 52, + "expected_LargeScript_Tracked,None": 1000, "expected_ArrayReturn_Tracked,None": 1 }, "BDN.benchmark.Operations.ModuleOperations.*": { "expected_ModuleNoOpRawStringReadCommand_ACL": 0, "expected_ModuleNoOpRawStringRmwCommand_ACL": 0, "expected_ModuleNoOpObjRmwCommand_ACL": 3200, - "expected_ModuleNoOpObjReadCommand_ACL": 3200, + "expected_ModuleNoOpObjReadCommand_ACL": 21000, "expected_ModuleNoOpProc_ACL": 0, "expected_ModuleNoOpTxn_ACL": 0, "expected_ModuleJsonGetCommand_ACL": 400000, "expected_ModuleJsonSetCommand_ACL": 223200, "expected_ModuleNoOpRawStringReadCommand_AOF": 0, "expected_ModuleNoOpRawStringRmwCommand_AOF": 0, - "expected_ModuleNoOpObjRmwCommand_AOF": 3200, - "expected_ModuleNoOpObjReadCommand_AOF": 3200, + "expected_ModuleNoOpObjRmwCommand_AOF": 24000, + "expected_ModuleNoOpObjReadCommand_AOF": 26000, "expected_ModuleNoOpProc_AOF": 0, "expected_ModuleNoOpTxn_AOF": 0, "expected_ModuleJsonGetCommand_AOF": 405000, @@ -361,7 +361,7 @@ "expected_ModuleNoOpObjReadCommand_None": 3200, "expected_ModuleNoOpProc_None": 0, "expected_ModuleNoOpTxn_None": 0, - "expected_ModuleJsonGetCommand_None": 72800, + "expected_ModuleJsonGetCommand_None": 430000, "expected_ModuleJsonSetCommand_None": 223200 }, "BDN.benchmark.Network.RawStringOperations.*": { diff --git a/test/BDNPerfTests/run_bdnperftest.ps1 b/test/BDNPerfTests/run_bdnperftest.ps1 index f3f72a0efe..376f16420a 100644 --- a/test/BDNPerfTests/run_bdnperftest.ps1 +++ b/test/BDNPerfTests/run_bdnperftest.ps1 @@ -48,6 +48,7 @@ function AnalyzeResult { if ($warnonly) { Write-Host "** << PERF REGRESSION WARNING! >> The BDN benchmark found Allocated value ($dblfoundResultValue) is above the acceptable threshold of $UpperBound (Expected value $expectedResultValue + $acceptablePercentRange%)" Write-Host "** " + return $true # Since it is warning, don't want to cause a fail } else { Write-Host "** << PERF REGRESSION FAIL! >> The BDN benchmark found Allocated value ($dblfoundResultValue) is above the acceptable threshold of $UpperBound (Expected value $expectedResultValue + $acceptablePercentRange%)" @@ -235,7 +236,7 @@ Get-Content $resultsFile | ForEach-Object { # Check if found value is not equal to expected value Write-Host "** Config: "$expectedResultsArray[$currentExpectedProp, 0].Substring(2) $expectedResultsArray[$currentExpectedProp, 1] - $currentResults = AnalyzeResult $foundValue $expectedResultsArray[$currentExpectedProp, 2] $acceptableAllocatedRange $true + $currentResults = AnalyzeResult $foundValue $expectedResultsArray[$currentExpectedProp, 2] $acceptableAllocatedRange $false if ($currentResults -eq $false) { $testSuiteResult = $false } From 7c6d6e29e8b6ae77d6b91fd940f0fad164f2a854 Mon Sep 17 00:00:00 2001 From: Vasileios Zois Date: Thu, 27 Feb 2025 10:11:43 -0800 Subject: [PATCH 36/36] address new codeQL requirement --- libs/cluster/Session/RespClusterReplicationCommands.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/cluster/Session/RespClusterReplicationCommands.cs b/libs/cluster/Session/RespClusterReplicationCommands.cs index fdb1aebf54..f9001b0ad8 100644 --- a/libs/cluster/Session/RespClusterReplicationCommands.cs +++ b/libs/cluster/Session/RespClusterReplicationCommands.cs @@ -404,7 +404,7 @@ private bool NetworkClusterAttachSync(out bool invalidParameters) else replicationOffset = clusterProvider.replicationManager.ReplicaRecoverDiskless(syncMetadata); - if (errorMessage != default) + if (!errorMessage.IsEmpty) { while (!RespWriteUtils.TryWriteError(errorMessage, ref dcurr, dend)) SendAndReset();