// override if new properties in a derived class need to be considered in comparisons
 internal virtual bool IsEqual(TheStorageEngineTSM senderThingToAdd)
 {
     return
         (senderThingToAdd != null &&
          cdeMID == senderThingToAdd.cdeMID &&
          Disable == senderThingToAdd.Disable &&
          SourceEngineName == senderThingToAdd.SourceEngineName &&
          TargetEngineName == senderThingToAdd.TargetEngineName &&
          SerializeTSM == senderThingToAdd.SerializeTSM &&
          SendAsFile == senderThingToAdd.SendAsFile &&
          MQTTTopicTemplate == senderThingToAdd.MQTTTopicTemplate &&
          TXTPattern == senderThingToAdd.TXTPattern
         );
 }
        public void GetRecordsFromTheMirrorCache(
            [Values(0, 500, 5000)] int maxCount,
            [Values(50, 5000)] int totalCandidates
            )
        {
            #region ASSEMBLE
            bool entryNotFound             = false;
            var  random                    = new Random();
            var  data                      = Enumerable.Range(1, totalCandidates).OrderBy(i => random.Next(1, totalCandidates));
            ManualResetEventSlim gate      = new ManualResetEventSlim();
            CountdownEvent       countdown = new CountdownEvent(1);
            TheMirrorCache <TheStorageEngineTSM> mirror;
            List <TheStorageEngineTSM>           TSMs      = new List <TheStorageEngineTSM>();
            List <TheStorageEngineTSM>           myRecords = new List <TheStorageEngineTSM>();

            // Build the collection of TSMs
            var baseTime = DateTimeOffset.Now;
            int counter  = 0;
            foreach (var payload in data)
            {
                TSMs.Add(new TheStorageEngineTSM()
                {
                    cdeMID     = Guid.NewGuid(),
                    TXTPattern = payload.ToString(),
                    cdeCTIM    = baseTime.AddTicks(counter++),
                });
            }

            // Spin up your mirror
            mirror = new TheMirrorCache <TheStorageEngineTSM>(10)
            {
                CacheStoreInterval       = 1,
                IsStoreIntervalInSeconds = true,
                IsCachePersistent        = true,
                UseSafeSave      = true,
                AllowFireUpdates = true,
            };
            if (maxCount != 0)
            {
                mirror.SetMaxStoreSize(maxCount);
            }

            // Add your items...
            mirror.AddItems(TSMs, response =>
            {
                myRecords = response;
                countdown.Signal();
            });

            countdown.Wait();

            Assert.AreEqual(totalCandidates, myRecords.Count, "Not all test records were added successfully.");

            #endregion

            #region ACT

            var expectedCount = maxCount == 0 ? totalCandidates : Math.Min(maxCount, totalCandidates);
            Assert.AreEqual(expectedCount, mirror.Count, "Not all test records were not added successfully.");

            // Retrieve your items...
            counter = 0;
            foreach (var tsm in TSMs)
            {
                TheStorageEngineTSM match = mirror.GetEntryByID(tsm.cdeMID);
                if (counter >= TSMs.Count - expectedCount)
                {
                    if (match == null)
                    {
                        entryNotFound = true;
                        break;
                    }
                }
                else
                {
                    if (match != null)
                    {
                        Assert.IsNull(match, "Item found that was supposed to have been removed due to max count limit", counter);
                    }
                }
                counter++;
            }

            mirror?.Dispose();

            #endregion

            #region ASSERT

            Assert.IsFalse(entryNotFound, "TheMirrorCache was missing one or more test entries!");

            #endregion
        }
        public void RemoveAnItemByKeyFromTheMirrorCacheTest()
        {
            #region ASSEMBLE

            int totalCandidates            = 5000;
            int indexMiddle                = totalCandidates / 2;
            int indexCurrent               = 0;
            var random                     = new Random();
            var data                       = Enumerable.Range(1, totalCandidates).OrderBy(i => random.Next(1, totalCandidates));
            ManualResetEventSlim gate      = new ManualResetEventSlim();
            CountdownEvent       countdown = new CountdownEvent(1);
            TheMirrorCache <TheStorageEngineTSM> mirror;
            TheStorageEngineTSM        tsmCurrent = null;
            TheStorageEngineTSM        tsmMiddle  = null;
            TheStorageEngineTSM        tsmRemoved = null;
            TheStorageEngineTSM        tsmMatch   = null;
            List <TheStorageEngineTSM> TSMs       = new List <TheStorageEngineTSM>();
            List <TheStorageEngineTSM> myRecords  = new List <TheStorageEngineTSM>();

            // Build the collection of TSMs and cache the middle one
            foreach (var payload in data)
            {
                tsmCurrent = new TheStorageEngineTSM()
                {
                    cdeMID     = Guid.NewGuid(),
                    TXTPattern = payload.ToString()
                };
                TSMs.Add(tsmCurrent);
                if ((indexCurrent++ >= indexMiddle) && (tsmMiddle == null))
                {
                    tsmMiddle = tsmCurrent;
                }
            }
            if (tsmMiddle == null)
            {
                Assert.Fail("Unable to cache the middle TSM!");
            }

            // Spin up your mirror
            mirror = new TheMirrorCache <TheStorageEngineTSM>(10)
            {
                CacheStoreInterval       = 1,
                IsStoreIntervalInSeconds = true,
                IsCachePersistent        = true,
                UseSafeSave      = true,
                AllowFireUpdates = true,
            };

            // Add your items...
            mirror.AddItems(TSMs, response =>
            {
                myRecords = response;
                countdown.Signal();
            });

            countdown.Wait();
            if (TSMs.Count != myRecords.Count)
            {
                Assert.Fail("Not all test records were not added successfully.");
            }

            #endregion

            #region ACT

            // Attempt to remove your middle item
            Task.Factory.StartNew(() =>
            {
                mirror.RemoveAnItemByKey(tsmMiddle.cdeMID.ToString(), payload =>
                {
                    tsmRemoved = payload;
                    gate.Set();
                });
            });

            // Wait for response
            gate.Reset();
            gate.Wait(30000);
            if (tsmRemoved == null)
            {
                Assert.Fail("Unable to remove item by ID!");
            }

            // Attempt to retrieve your middle item
            tsmMatch = mirror.GetEntryByID(tsmMiddle.cdeMID);

            mirror?.Dispose();

            #endregion

            #region ASSERT

            Assert.IsTrue(tsmMatch == null);

            #endregion
        }
        public void RemoveAnItemByIDFromTheStorageMirrorTest()
        {
            #region ASSEMBLE

            TheStorageMirror <TheStorageEngineTSM> .StoreResponse response = null;
            int totalCandidates       = 5000;
            int indexMiddle           = totalCandidates / 2;
            int indexCurrent          = 0;
            var random                = new Random();
            var data                  = Enumerable.Range(1, totalCandidates).OrderBy(i => random.Next(1, totalCandidates));
            ManualResetEventSlim gate = new ManualResetEventSlim();
            TheStorageMirror <TheStorageEngineTSM> mirror;
            TheStorageEngineTSM        tsmCurrent = null;
            TheStorageEngineTSM        tsmMiddle  = null;
            TheStorageEngineTSM        tsmMatch   = null;
            List <TheStorageEngineTSM> TSMs       = new List <TheStorageEngineTSM>();
            List <TheStorageEngineTSM> myRecords  = new List <TheStorageEngineTSM>();

            // Build the collection of TSMs and cache the middle one
            foreach (var payload in data)
            {
                tsmCurrent = new TheStorageEngineTSM()
                {
                    cdeMID     = Guid.NewGuid(),
                    TXTPattern = payload.ToString()
                };
                TSMs.Add(tsmCurrent);
                if ((indexCurrent++ >= indexMiddle) && (tsmMiddle == null))
                {
                    tsmMiddle = tsmCurrent;
                }
            }
            if (tsmMiddle == null)
            {
                Assert.Fail("Unable to cache the middle TSM!");
            }

            // Spin up your mirror
            mirror = new TheStorageMirror <TheStorageEngineTSM>(TheCDEngines.MyIStorageService)
            {
                IsRAMStore               = true,
                CacheStoreInterval       = 1,
                IsStoreIntervalInSeconds = true,
                IsCachePersistent        = true,
                UseSafeSave              = true,
                AllowFireUpdates         = true,
            };
            mirror.RegisterEvent(eStoreEvents.StoreReady, e => { gate.Set(); });
            mirror.InitializeStore(true);

            // Wait for mirror to initialize...
            gate.Wait(30000);

            // Add your items
            Task.Factory.StartNew(() =>
            {
                mirror.AddItems(TSMs, payload =>
                {
                    response = payload;
                    gate.Set();
                });
            });

            //Wait for response
            gate.Reset();
            gate.Wait(30000);
            if ((response != null) && response.HasErrors)
            {
                Assert.Fail("Unable to add test collection items! Reason: {0}", response.ErrorMsg);
            }

            #endregion

            #region ACT

            // Attempt to remove your middle item
            Task.Factory.StartNew(() =>
            {
                mirror.RemoveAnItemByID(tsmMiddle.cdeMID, payload =>
                {
                    response = payload;
                    gate.Set();
                });
            });

            // Wait for response
            gate.Reset();
            gate.Wait(30000);
            if ((response != null) && response.HasErrors)
            {
                Assert.Fail("Unable to remove item by ID! Reason: {0}", response.ErrorMsg);
            }

            // Attempt to retrieve your middle item
            tsmMatch = mirror.GetEntryByID(tsmMiddle.cdeMID);

            mirror?.Dispose();

            #endregion

            #region ASSERT

            Assert.IsTrue(tsmMatch == null);

            #endregion
        }