From ff468b93c28d91b0f3f70bed122038656623540b Mon Sep 17 00:00:00 2001 From: Gabe Stocco <98900+gfs@users.noreply.github.com> Date: Wed, 14 Dec 2022 10:57:30 -0800 Subject: [PATCH] Remove LiteDB References and benchmarks (#679) --- Benchmarks/Benchmarks.csproj | 1 - Benchmarks/LiteDbInsertTests.cs | 99 ------ Benchmarks/LiteDbManager.cs | 558 -------------------------------- Benchmarks/LiteDbQueryTests.cs | 176 ---------- 4 files changed, 834 deletions(-) delete mode 100644 Benchmarks/LiteDbInsertTests.cs delete mode 100644 Benchmarks/LiteDbManager.cs delete mode 100644 Benchmarks/LiteDbQueryTests.cs diff --git a/Benchmarks/Benchmarks.csproj b/Benchmarks/Benchmarks.csproj index afa3018b0..1bf67192a 100644 --- a/Benchmarks/Benchmarks.csproj +++ b/Benchmarks/Benchmarks.csproj @@ -10,7 +10,6 @@ - diff --git a/Benchmarks/LiteDbInsertTests.cs b/Benchmarks/LiteDbInsertTests.cs deleted file mode 100644 index 21c489bc7..000000000 --- a/Benchmarks/LiteDbInsertTests.cs +++ /dev/null @@ -1,99 +0,0 @@ -using Microsoft.CST.AttackSurfaceAnalyzer.Utils; -using BenchmarkDotNet.Attributes; -using System.Threading; -using System.Threading.Tasks; - -namespace Microsoft.CST.AttackSurfaceAnalyzer.Benchmarks -{ - [MarkdownExporterAttribute.GitHub] - [JsonExporterAttribute.Full] - public class LiteDbInsertTests : AsaDatabaseBenchmark - { - // Bag of reusable objects to write to the database. - public LiteDbInsertTests() - { - Logger.Setup(true, true); - Strings.Setup(); - } - - // The number of records to insert for the benchmark - //[Params(25000,50000,100000)] - [Params(10000)] - public int N { get; set; } - - // The amount of padding to add to the object in bytes Default size is approx 530 bytes serialized - // Does not include SQL overhead - [Params(0)] - public int ObjectPadding { get; set; } - - // The number of Shards/Threads to use for Database operations - //[Params(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12)] - [Params(1)] - public int Shards { get; set; } - - // The number of records to populate the database with before the benchmark - //[Params(0,100000,200000,400000,800000,1600000,3200000)] - [Params(0)] - public int StartingSize { get; set; } - - public static void Insert_X_Objects(int X, int ObjectPadding = 0, string runName = "Insert_X_Objects") - { - Parallel.For(0, X, i => - { - var obj = GetRandomObject(ObjectPadding); - LiteDbManager.Write(obj, runName); - BagOfObjects.Add(obj); - }); - - while (LiteDbManager.HasElements()) - { - Thread.Sleep(1); - } - } - - [GlobalCleanup] - public void GlobalCleanup() - { - Setup(); - LiteDbManager.Destroy(); - } - - [GlobalSetup] - public void GlobalSetup() - { - PopulateDatabases(); - } - - [Benchmark] - public void Insert_N_Objects() => Insert_X_Objects(N, ObjectPadding, "Insert_N_Objects"); - - [IterationCleanup] - public void IterationCleanup() - { - LiteDbManager.CloseDatabase(); - } - - [IterationSetup] - public void IterationSetup() - { - Setup(); - LiteDbManager.BeginTransaction(); - } - - public void PopulateDatabases() - { - Setup(); - LiteDbManager.BeginTransaction(); - - Insert_X_Objects(StartingSize, ObjectPadding, "PopulateDatabase"); - - LiteDbManager.Commit(); - LiteDbManager.CloseDatabase(); - } - - private void Setup() - { - LiteDbManager.Setup(filename: $"AsaBenchmark_{Shards}.litedb"); - } - } -} \ No newline at end of file diff --git a/Benchmarks/LiteDbManager.cs b/Benchmarks/LiteDbManager.cs deleted file mode 100644 index 51762acc2..000000000 --- a/Benchmarks/LiteDbManager.cs +++ /dev/null @@ -1,558 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT License. -using Microsoft.CST.AttackSurfaceAnalyzer.Objects; -using Microsoft.CST.AttackSurfaceAnalyzer.Types; -using LiteDB; -using Newtonsoft.Json; -using Serilog; -using System; -using System.Collections.Concurrent; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Threading; -using System.Threading.Tasks; - -namespace Microsoft.CST.AttackSurfaceAnalyzer.Utils -{ - public static class LiteDbManager - { - public static LiteDatabase? db { get; private set; } - public static string Filename { get; private set; } = "asa.litedb"; - public static bool FirstRun { get; private set; } = true; - public static ConcurrentQueue WriteQueue { get; private set; } = new ConcurrentQueue(); - - public static void BeginTransaction() - { - db?.BeginTrans(); - } - - public static void CloseDatabase() - { - db?.Rollback(); - db?.Dispose(); - db = null; - } - - public static void Commit() - { - db?.Commit(); - } - - public static void DeleteRun(string runId) - { - var Runs = db?.GetCollection("Runs"); - - Runs?.DeleteMany(x => x.RunId == runId); - - var Results = db?.GetCollection("WriteObjects"); - - Results?.DeleteMany(x => x.RunId == runId); - } - - public static void Destroy() - { - try - { - File.Delete(Filename); - } - catch (Exception e) - { - Log.Information(e, $"Failed to clean up database located at {Filename}"); - } - } - - public static IEnumerable? GetCommonResultTypes(string baseId, string compareId) - { - var runs = db?.GetCollection("Runs"); - - var firstRun = runs?.FindOne(x => x.RunId.Equals(baseId)); - var secondRun = runs?.FindOne(x => x.RunId.Equals(compareId)); - - return firstRun?.ResultTypes.Intersect(secondRun?.ResultTypes ?? new List()) ?? secondRun?.ResultTypes ?? new List(); - } - - public static bool? GetComparisonCompleted(string firstRunId, string secondRunId) - { - var cr = db?.GetCollection("CompareRuns"); - - return cr?.Exists(x => x.FirstRunId != null && x.SecondRunId != null && x.FirstRunId.Equals(firstRunId) && x.SecondRunId.Equals(secondRunId)); - } - - public static IEnumerable? GetComparisonResults(string firstRunId, string secondRunId, RESULT_TYPE resultType, int offset = 0, int numResults = 2147483647) - { - var crs = db?.GetCollection("CompareResult"); - return crs?.Find(x => x.BaseRunId != null && x.CompareRunId != null && x.BaseRunId.Equals(firstRunId) && x.CompareRunId.Equals(secondRunId) && x.ResultType.Equals(resultType), offset, numResults); - } - - public static int? GetComparisonResultsCount(string firstRunId, string secondRunId, int resultType) - { - var crs = db?.GetCollection("CompareResult"); - - return crs?.Count(x => x.BaseRunId != null && x.CompareRunId != null && x.BaseRunId.Equals(firstRunId) && x.CompareRunId.Equals(secondRunId) && x.ResultType.Equals(resultType)); - } - - public static List GetLatestRunIds(int numberOfIds, RUN_TYPE type) - { - var runs = db?.GetCollection("Runs"); - var selectedRuns = runs?.Find(Query.All(Query.Descending)).Where(x => x.Type == type).Select(x => x.RunId).Take(numberOfIds).ToList() ?? new List(); - return selectedRuns; - } - - public static IEnumerable GetMissingFromFirst(string firstRunId, string secondRunId) - { - var col = db?.GetCollection("WriteObjects"); - - var list = new ConcurrentBag(); - - var wos = col?.Find(x => x.RunId == secondRunId) ?? Array.Empty(); - - //wos.AsParallel().ForAll(wo => - foreach (var wo in wos) - { - Log.Information($"{firstRunId},{JsonConvert.SerializeObject(wo)}"); - if (col?.Exists(x => x.Identity == firstRunId && x.RunId == wo.Identity) == true) - { - list.Add(wo); - } - } - //}); - - return wos ?? new List(); - } - - public static IEnumerable<(WriteObject, WriteObject)> GetModified(string firstRunId, string secondRunId) - { - var col = db?.GetCollection("WriteObjects"); - - var list = new ConcurrentBag<(WriteObject, WriteObject)>(); - - //GetWriteObjects(firstRunId).AsParallel().ForAll(WO => - foreach (var WO in GetWriteObjects(firstRunId)) - { - Log.Information(JsonConvert.SerializeObject(WO)); - var secondItem = col?.FindOne(Query.And(Query.EQ("RunId", secondRunId), Query.EQ("IdentityHash", WO.Identity), Query.Not("InstanceHash", WO.RowKey))); - if (secondItem is WriteObject WO2) - { - list.Add((WO, WO2)); - } - } - //}); - - return list; - } - - public static List GetMonitorResults(string runId, int offset, int numResults) - { - //var fme = db.GetCollection("FileMonitorEvents"); - //return fme.Find(x => x.RunId.Equals(runId), skip: offset, limit: numResults).ToList(); - return new List(); - } - - public static List GetMonitorRuns() - { - return GetRuns("monitor"); - } - - public static int GetNumMonitorResults(string runId) - { - //var fme = db.GetCollection("FileMonitorEvent"); - //return fme.Count(x => x.RunId.Equals(runId)); - return 0; - } - - public static int GetNumResults(RESULT_TYPE ResultType, string runId) - { - var wo = db?.GetCollection("WriteObjects"); - - return wo?.Count(Query.And(Query.EQ("RunId", runId), Query.EQ("ColObj.ResultType", (int)ResultType))) ?? 0; - } - - public static bool GetOptOut() - { - //var settings = db.GetCollection("Settings"); - //var optout = settings.FindOne(x => x.Name == "TelemetryOptOut"); - //return bool.Parse(optout.Value); - return false; - } - - public static List GetResultModels(RUN_STATUS status) - { - var output = new List(); - var comparisons = db?.GetCollection("Comparisons"); - - var results = comparisons?.Find(x => x.Status.Equals(status)); - - if (results != null) - { - foreach (var result in results) - { - output.Add(new DataRunModel(KeyIn: result.FirstRunId + " vs. " + result.SecondRunId, TextIn: result.FirstRunId + " vs. " + result.SecondRunId)); - } - } - - return output; - } - - public static List GetResultsByRunid(string runid) - { - var output = new List(); - - var wo = db?.GetCollection("WriteObjects"); - - return wo?.Find(x => x.RunId.Equals(runid)).ToList() ?? new List(); - } - - public static List GetResultTypes(string runId) - { - var runs = db?.GetCollection("Runs"); - - var run = runs?.FindOne(x => x.RunId.Equals(runId)); - - return run?.ResultTypes ?? new List(); - } - - public static Dictionary GetResultTypesAndCounts(string runId) - { - var outDict = new Dictionary() { }; - - var wo = db?.GetCollection("WriteObjects"); - - foreach (RESULT_TYPE? resultType in Enum.GetValues(typeof(RESULT_TYPE))) - { - if (resultType is RESULT_TYPE _TYPE) - { - var count = wo?.Count(x => x.ColObj.ResultType.Equals(_TYPE)) ?? 0; - - if (count > 0) - { - outDict.Add(_TYPE, count); - } - } - } - - return outDict; - } - - public static AsaRun? GetRun(string RunId) - { - var runs = db?.GetCollection("Runs"); - - return runs?.FindOne(Query.EQ("RunId", RunId)); - } - - // fme.Insert(new FileMonitorEvent() - // { - // RunId = runId, - // FMO = obj - // }); - //} - public static List GetRuns(string type) - { - var runs = db?.GetCollection("Runs"); - - return runs?.Find(x => x.Type.Equals(type)).Select(x => x.RunId)?.ToList() ?? new List(); - } - - //public static void WriteFileMonitor(FileMonitorObject obj, string runId) - //{ - // var fme = db.GetCollection(); - public static List GetRuns() - { - return GetRuns("collect"); - } - - public static IEnumerable GetSerializedMonitorResults(string runId) - { - //List records = new List(); - - //var fme = db.GetCollection("FileMonitorEvents"); - - //return fme.Find(x => x.RunId.Equals(runId)); - return new List(); - } - - public static WriteObject? GetWriteObject(string RunId, string IdentityHash) - { - if (!WriteObjectCollections.TryTake(out ILiteCollection? col)) - { - col = db?.GetCollection(); - } - - var output = col?.FindOne(x => x.Identity == IdentityHash && x.RunId == RunId); - - if (col is ILiteCollection) - WriteObjectCollections.Add(col); - - return output; - } - - // return list; - //} - public static IEnumerable GetWriteObjects(string runId) - { - var col = db?.GetCollection("WriteObjects"); - - return col?.Find(Query.EQ("RunId", runId)) ?? new List(); - } - - public static bool HasElements() - { - return !WriteQueue.IsEmpty; - } - - public static void InsertAnalyzed(CompareResult objIn) - { - if (objIn != null) - { - var cr = db?.GetCollection("CompareResults"); - - cr?.Insert(objIn); - } - } - - public static void InsertCompareRun(string firstRunId, string secondRunId, RUN_STATUS runStatus) - { - var crs = db?.GetCollection("CompareRun"); - - var cr = new CompareRun(FirstRunIdIn: firstRunId, SecondRunIdIn: secondRunId, RunStatusIn: runStatus); - - crs?.Insert(cr); - } - - public static void InsertRun(string runId, List typeList, RUN_TYPE type) - { - var runs = db?.GetCollection("Runs"); - - runs?.Insert(new AsaRun( - RunId: runId, - ResultTypes: typeList, - Platform: AsaHelpers.GetPlatform(), - Timestamp: DateTime.Now, - Type: type, - Version: AsaHelpers.GetVersionString() - )); - } - - public static void KeepSleepAndFlushQueue() - { - while (true) - { - SleepAndFlushQueue(); - } - } - - public static bool RunContains(string runId, string IdentityHash) - { - if (!WriteObjectCollections.TryTake(out ILiteCollection? col)) - { - col = db?.GetCollection(); - } - - var output = col?.Exists(y => y.RunId == runId && y.Identity == IdentityHash); - - if (col is ILiteCollection) - WriteObjectCollections.Add(col); - - return output ?? false; - } - - public static PLATFORM RunIdToPlatform(string runid) - { - var col = db?.GetCollection("Runs"); - - var results = col?.Find(x => x.RunId.Equals(runid)); - if (results?.Any() ?? false) - { - return results.First().Platform; - } - else - { - return PLATFORM.UNKNOWN; - } - } - - public static void SetOptOut(bool OptOut) - { - //var settings = db.GetCollection("Settings"); - - //settings.Upsert(new Setting() { Name = "TelemetryOptOut", Value = OptOut.ToString() }); - } - - public static bool Setup(string filename = "") - { - if (!string.IsNullOrEmpty(filename)) - { - Filename = filename; - } - - if (db != null) - { - CloseDatabase(); - } - - try - { - db = new LiteDatabase(Filename); - - db.BeginTrans(); - - var col = db.GetCollection("WriteObjects"); - - col.EnsureIndex(x => x.ColObj.Identity); - col.EnsureIndex(x => x.RowKey); - col.EnsureIndex(x => x.ColObj.ResultType); - col.EnsureIndex(x => x.RunId); - - var cr = db.GetCollection("CompareResults"); - - cr.EnsureIndex(x => x.BaseRunId); - cr.EnsureIndex(x => x.CompareRunId); - cr.EnsureIndex(x => x.ResultType); - - db.Commit(); - } - catch (Exception e) - { - Log.Debug(e, "Initializing database."); - } - - if (!WriterStarted) - { - ((Action)(async () => - { - await Task.Run(() => KeepSleepAndFlushQueue()).ConfigureAwait(false); - }))(); - WriterStarted = true; - } - - return true; - } - - public static void SleepAndFlushQueue() - { - while (!WriteQueue.IsEmpty) - { - WriteNext(); - } - Thread.Sleep(100); - } - - public static void TrimToLatest() - { - List Runs = new List(); - - var runs = db?.GetCollection("Runs"); - - var all = runs?.FindAll(); - - if (all != null) - { - var allButLatest = all.Except(new List() { all.Last() }); - - foreach (var run in allButLatest) - { - DeleteRun(run.RunId); - } - } - } - - // Stopwatch.Stop(); var t = TimeSpan.FromMilliseconds(Stopwatch.ElapsedMilliseconds); var answer = - // string.Format(CultureInfo.InvariantCulture, "{0:D2}h:{1:D2}m:{2:D2}s:{3:D3}ms", t.Hours, t.Minutes, - // t.Seconds, t.Milliseconds); Log.Debug("Completed getting WriteObjects for {0} in {1}", secondRunId, answer); - public static void UpdateCompareRun(string firstRunId, string secondRunId, RUN_STATUS runStatus) - { - var crs = db?.GetCollection("CompareRun"); - - var cr = crs?.FindOne(x => x.FirstRunId.Equals(firstRunId) && x.SecondRunId.Equals(secondRunId)); - if (cr != null) - { - cr.Status = runStatus; - crs?.Update(cr); - } - } - - public static void VerifySchemaVersion() - { - //var settings = db.GetCollection("Settings"); - - //if (!(settings.Exists(Query.And(Query.EQ("Name", "SchemaVersion"), Query.EQ("Value", SCHEMA_VERSION))))) - //{ - // Log.Fatal("Schema version of database is {0} but {1} is required. Use config --reset-database to delete the incompatible database.", settings.FindOne(x => x.Name.Equals("SchemaVersion")).Value, SCHEMA_VERSION); - // Environment.Exit(-1); - //} - } - - public static void Write(CollectObject objIn, string runId) - { - if (objIn != null && runId != null) - { - WriteQueue.Enqueue(new WriteObject(objIn, runId)); - } - } - - public static void WriteNext() - { - var list = new List(); - - for (int i = 0; i < Math.Min(1000, WriteQueue.Count); i++) - { - if (WriteQueue.TryDequeue(out WriteObject? ColObj) && ColObj is WriteObject WO) - { - list.Add(WO); - } - } - - var col = db?.GetCollection("WriteObjects"); - col?.Insert(list); - } - - private const int SCHEMA_VERSION = 1; - - private static readonly ConcurrentBag> WriteObjectCollections = new ConcurrentBag>(); - private static bool WriterStarted = false; - private static Settings settings { get; set; } = new Settings() { SchemaVersion = SCHEMA_VERSION, ShardingFactor = 1 }; - //public static IEnumerable GetMissingFromFirst2(string firstRunId, string secondRunId) - //{ - // var col = db.GetCollection("WriteObjects"); - - // var list = new ConcurrentBag(); - - // var Stopwatch = System.Diagnostics.Stopwatch.StartNew(); - - // var identityHashes = db.Execute($"SELECT IdentityHash FROM WriteObjects WHERE RunId = @0", new - // BsonDocument { ["0"] = secondRunId }); - - // Parallel.ForEach(identityHashes.ToEnumerable(), IdentityHash => { if (WriteObjectExists(firstRunId, - // IdentityHash["IdentityHash"].AsString)) { list.Add(GetWriteObject(secondRunId, - // IdentityHash.AsString)); } }); - } - - public class CompareRun - { - public CompareRun(string FirstRunIdIn, string SecondRunIdIn, RUN_STATUS RunStatusIn) - { - FirstRunId = FirstRunIdIn; - SecondRunId = SecondRunIdIn; - Status = RunStatusIn; - } - - public string FirstRunId { get; } - public string SecondRunId { get; } - public RUN_STATUS Status { get; set; } - } - - public class Comparison - { - public Comparison(string firstRunId, string secondRunId, RUN_STATUS status) - { - FirstRunId = firstRunId; - SecondRunId = secondRunId; - Status = status; - } - - public string FirstRunId { get; set; } - public int Id { get; set; } - public string SecondRunId { get; set; } - public RUN_STATUS Status { get; set; } - } -} \ No newline at end of file diff --git a/Benchmarks/LiteDbQueryTests.cs b/Benchmarks/LiteDbQueryTests.cs deleted file mode 100644 index d85f6c596..000000000 --- a/Benchmarks/LiteDbQueryTests.cs +++ /dev/null @@ -1,176 +0,0 @@ -using Microsoft.CST.AttackSurfaceAnalyzer.Utils; -using BenchmarkDotNet.Attributes; -using System.Collections.Concurrent; -using System.Linq; -using System.Threading; -using System.Threading.Tasks; - -namespace Microsoft.CST.AttackSurfaceAnalyzer.Benchmarks -{ - [MarkdownExporterAttribute.GitHub] - [JsonExporterAttribute.Full] - public class LiteDbQueryTests : AsaDatabaseBenchmark - { -#nullable disable - - public LiteDbQueryTests() -#nullable restore - { - Logger.Setup(true, true); - Strings.Setup(); - } - - // Percent of identities which should match between the two runs (% of the smaller run) - [Params(0, .25, .5, .75, 1)] - public double IdentityMatches { get; set; } - - //[Params("OFF","DELETE","WAL","MEMORY")] - [Params("WAL")] - public string JournalMode { get; set; } - - // Options are NORMAL, EXCLUSIVE - [Params("NORMAL")] - public string LockingMode { get; set; } - - // The amount of padding to add to the object in bytes Default size is approx 530 bytes serialized - // Does not include SQL overhead - [Params(0)] - public int ObjectPadding { get; set; } - - // Options are powers of 2 between 512 and 65536 - [Params(4096)] - public int PageSize { get; set; } - - // Percent of those identities which match which should match in rowkey - [Params(0, .25, .5, .75, 1)] - public double RowKeyMatches { get; set; } - - // The number of records in run one - [Params(10000)] - public int RunOneSize { get; set; } - - // The number of records in run two - [Params(10000)] - public int RunTwoSize { get; set; } - - // The number of Shards/Threads to use for Database operations - [Params(1)] - public int Shards { get; set; } - - // The number random records to populate the database with before the two compare runs are added - [Params(0)] - public int StartingSize { get; set; } - - // Options are OFF, NORMAL, FULL, EXTRA - [Params("OFF")] - public string Synchronous { get; set; } - - [Benchmark] - public void GetMissingFromFirstTest() - { - LiteDbManager.GetMissingFromFirst(RunOneName, RunTwoName).Count(); - } - - [Benchmark] - public void GetModifiedTest() - { - LiteDbManager.GetModified(RunOneName, RunTwoName); - } - - [GlobalCleanup] - public void GlobalCleanup() - { - Setup(); - LiteDbManager.Destroy(); - } - - [GlobalSetup] - public void GlobalSetup() - { - PopulateDatabases(); - } - - public void InsertFirstRun() - { - Parallel.For(0, RunOneSize, i => - { - var obj = GetRandomObject(ObjectPadding); - LiteDbManager.Write(obj, RunOneName); - - if (obj.FileType != null) - { - BagOfObjects.Add(obj); - } - }); - - while (LiteDbManager.HasElements()) - { - Thread.Sleep(1); - } - } - - public void InsertSecondRun() - { - Parallel.For(0, RunTwoSize, i => - { - var obj = GetRandomObject(ObjectPadding); - - if (BagOfIdentities.TryTake(out (string, string) Id)) - { - if (CryptoHelpers.GetRandomPositiveDouble(1) > IdentityMatches) - { - obj.Path = Id.Item1; - if (CryptoHelpers.GetRandomPositiveDouble(1) > RowKeyMatches) - { - obj.FileType = Id.Item2; - } - } - } - - LiteDbManager.Write(obj, RunTwoName); - BagOfObjects.Add(obj); - }); - } - - [IterationCleanup] - public void IterationCleanup() - { - LiteDbManager.CloseDatabase(); - } - - [IterationSetup] - public void IterationSetup() - { - Setup(); - } - - public void PopulateDatabases() - { - Setup(); - LiteDbManager.BeginTransaction(); - - InsertFirstRun(); - InsertSecondRun(); - - while (LiteDbManager.HasElements()) - { - Thread.Sleep(1); - } - - LiteDbManager.Commit(); - LiteDbManager.CloseDatabase(); - } - - // Bag of reusable identities - private static readonly ConcurrentBag<(string, string)> BagOfIdentities = new ConcurrentBag<(string, string)>(); - - private readonly string RunOneName = "RunOne"; - - private readonly string RunTwoName = "RunTwo"; - - private void Setup() - { - LiteDbManager.Setup(filename: $"AsaBenchmark_{Shards}.sqlite"); - } - } -} \ No newline at end of file