public static void MyClassInitialize(TestContext testContext) { CloudTableClient tableClient = GenerateCloudTableClient(); currentTable = tableClient.GetTableReference(GenerateRandomTableName()); currentTable.CreateIfNotExists(); // Populate Entities (This will add 1500 entities to a new table, enough to test continuations TableServiceContext ctx = tableClient.GetTableServiceContext(); for (int l = 0; l < totalTestEntities / 100; l++) { for (int m = 0; m < 100; m++) { BaseEntity ent = new BaseEntity("partition" + l, m.ToString()); ent.Randomize(); ent.A = ent.RowKey; ctx.AddObject(currentTable.Name, ent); } ctx.SaveChangesWithRetries(SaveChangesOptions.Batch); } }
private void DoSingleEntityReplaceFail(TablePayloadFormat format) { CloudTableClient tableClient = GenerateCloudTableClient(); TableServiceContext ctx = tableClient.GetTableServiceContext(); TableServiceContext secondContext = tableClient.GetTableServiceContext(); SetPayloadFormatOnDataServiceContext(ctx, format, tableClient); SetPayloadFormatOnDataServiceContext(secondContext, format, tableClient); // Insert Entity BaseEntity baseEntity = new BaseEntity("insert test", "foo" + format.ToString()); baseEntity.Randomize(); ctx.AddObject(currentTable.Name, baseEntity); ctx.SaveChangesWithRetries(); string etag = ctx.Entities.First().ETag; baseEntity.A = "updated"; ctx.UpdateObject(baseEntity); ctx.SaveChangesWithRetries(); MergeEntity replaceEntity = new MergeEntity(baseEntity.PartitionKey, baseEntity.RowKey); replaceEntity.Randomize(); secondContext.AttachTo(currentTable.Name, replaceEntity, etag); secondContext.UpdateObject(replaceEntity); OperationContext opContext = new OperationContext(); try { secondContext.SaveChangesWithRetries(SaveChangesOptions.ReplaceOnUpdate, null, opContext); Assert.Fail(); } catch (StorageException) { TestHelper.ValidateResponse(opContext, 1, (int)HttpStatusCode.PreconditionFailed, new string[] { "UpdateConditionNotSatisfied", "ConditionNotMet" }, new string[] { "The update condition specified in the request was not satisfied.", "The condition specified using HTTP conditional header(s) is not met." }); } ctx.DeleteObject(baseEntity); ctx.SaveChangesWithRetries(); opContext = new OperationContext(); // try merging with deleted entity try { secondContext.SaveChangesWithRetries(SaveChangesOptions.None, null, opContext); Assert.Fail(); } catch (StorageException) { TestHelper.ValidateResponse(opContext, 1, (int)HttpStatusCode.NotFound, new string[] { "ResourceNotFound" }, "The specified resource does not exist."); } }
private void DoSingleEntityReplace(TablePayloadFormat format) { CloudTableClient tableClient = GenerateCloudTableClient(); TableServiceContext ctx = tableClient.GetTableServiceContext(); TableServiceContext queryContext = tableClient.GetTableServiceContext(); SetPayloadFormatOnDataServiceContext(ctx, format, tableClient); SetPayloadFormatOnDataServiceContext(queryContext, format, tableClient); // Insert Entity BaseEntity baseEntity = new BaseEntity("insert test", "foo" + format.ToString()); baseEntity.Randomize(); ctx.AddObject(currentTable.Name, baseEntity); ctx.SaveChangesWithRetries(); string etag = ctx.Entities.First().ETag; ctx.Detach(baseEntity); MergeEntity replaceEntity = new MergeEntity(baseEntity.PartitionKey, baseEntity.RowKey); replaceEntity.Randomize(); ctx.AttachTo(currentTable.Name, replaceEntity, etag); ctx.UpdateObject(replaceEntity); ctx.SaveChangesWithRetries(SaveChangesOptions.ReplaceOnUpdate); // Retrieve Entity UnionEnitity retrievedEntity = (from ent in queryContext.CreateQuery<UnionEnitity>(currentTable.Name) where ent.PartitionKey == baseEntity.PartitionKey && ent.RowKey == baseEntity.RowKey select ent).AsTableServiceQuery(queryContext).Execute().FirstOrDefault(); Assert.IsNotNull(retrievedEntity); Assert.AreEqual(null, retrievedEntity.A); Assert.AreEqual(null, retrievedEntity.B); Assert.AreEqual(null, retrievedEntity.C); Assert.AreEqual(replaceEntity.D, retrievedEntity.D); Assert.AreEqual(replaceEntity.E, retrievedEntity.E); Assert.AreEqual(replaceEntity.F, retrievedEntity.F); }
public void SingleEntityInsertOrReplaceTask() { CloudTableClient tableClient = GenerateCloudTableClient(); TableServiceContext ctx = tableClient.GetTableServiceContext(); TableServiceContext queryContext = tableClient.GetTableServiceContext(); queryContext.MergeOption = MergeOption.NoTracking; // Insert Entity BaseEntity baseEntity = new BaseEntity("insert test", "foo"); // Insert Or Merge with no pre-existing entity MergeEntity insertOrReplaceEntity = new MergeEntity(baseEntity.PartitionKey, baseEntity.RowKey); insertOrReplaceEntity.Randomize(); ctx.AttachTo(currentTable.Name, insertOrReplaceEntity, null); ctx.UpdateObject(insertOrReplaceEntity); ctx.SaveChangesWithRetriesAsync(SaveChangesOptions.ReplaceOnUpdate).Wait(); ctx.Detach(insertOrReplaceEntity); // Retrieve Entity & Verify Contents UnionEnitity retrievedEntity = (from ent in queryContext.CreateQuery<UnionEnitity>(currentTable.Name) where ent.PartitionKey == baseEntity.PartitionKey && ent.RowKey == baseEntity.RowKey select ent).AsTableServiceQuery(queryContext).Execute().FirstOrDefault(); Assert.IsNotNull(retrievedEntity); Assert.AreEqual(null, retrievedEntity.A); Assert.AreEqual(null, retrievedEntity.B); Assert.AreEqual(null, retrievedEntity.C); Assert.AreEqual(insertOrReplaceEntity.D, retrievedEntity.D); Assert.AreEqual(insertOrReplaceEntity.E, retrievedEntity.E); Assert.AreEqual(insertOrReplaceEntity.F, retrievedEntity.F); BaseEntity replacedEntity = new BaseEntity("insert test", "foo"); replacedEntity.Randomize(); ctx.AttachTo(currentTable.Name, replacedEntity, null); ctx.UpdateObject(replacedEntity); ctx.SaveChangesWithRetriesAsync(SaveChangesOptions.ReplaceOnUpdate).Wait(); // Retrieve Entity & Verify retrievedEntity = (from ent in queryContext.CreateQuery<UnionEnitity>(currentTable.Name) where ent.PartitionKey == baseEntity.PartitionKey && ent.RowKey == baseEntity.RowKey select ent).AsTableServiceQuery(queryContext).Execute().FirstOrDefault(); Assert.IsNotNull(retrievedEntity); Assert.AreEqual(replacedEntity.A, retrievedEntity.A); Assert.AreEqual(replacedEntity.B, retrievedEntity.B); Assert.AreEqual(replacedEntity.C, retrievedEntity.C); Assert.AreEqual(null, retrievedEntity.D); Assert.AreEqual(null, retrievedEntity.E); Assert.AreEqual(null, retrievedEntity.F); }
public void TableServiceContextSaveChangeWithRetriesAPM() { CloudTableClient tableClient = GenerateCloudTableClient(); // Get data context. TableServiceContext context = tableClient.GetTableServiceContext(); // Create the new entity. BaseEntity entity = new BaseEntity("Hello", "world."); using (AutoResetEvent waitHandle = new AutoResetEvent(false)) { // Add the entity. context.AttachTo(this.currentTable.Name, entity); context.UpdateObject(entity); // Save changes to the service. IAsyncResult result = context.BeginSaveChangesWithRetries(ar => waitHandle.Set(), null); waitHandle.WaitOne(); context.EndSaveChangesWithRetries(result); BaseEntity entity2 = new BaseEntity("Insert", "foo."); context.AttachTo(this.currentTable.Name, entity2); context.UpdateObject(entity2); // Test again with different parameters result = context.BeginSaveChangesWithRetries(SaveChangesOptions.None, ar => waitHandle.Set(), null); waitHandle.WaitOne(); context.EndSaveChangesWithRetries(result); // Retrieve Entities & Verify BaseEntity retrievedEntity = (from ent in context.CreateQuery<BaseEntity>(currentTable.Name) where ent.PartitionKey == entity2.PartitionKey && ent.RowKey == entity2.RowKey select ent).AsTableServiceQuery(context).Execute().FirstOrDefault(); Assert.IsNotNull(retrievedEntity); retrievedEntity = (from ent in context.CreateQuery<BaseEntity>(currentTable.Name) where ent.PartitionKey == entity.PartitionKey && ent.RowKey == entity.RowKey select ent).AsTableServiceQuery(context).Execute().FirstOrDefault(); Assert.IsNotNull(retrievedEntity); } // Test Dispose context.Dispose(); }
private void DoSingleEntityInsertOrMerge(TablePayloadFormat format) { CloudTableClient tableClient = GenerateCloudTableClient(); TableServiceContext ctx = tableClient.GetTableServiceContext(); TableServiceContext queryContext = tableClient.GetTableServiceContext(); SetPayloadFormatOnDataServiceContext(ctx, format, tableClient); SetPayloadFormatOnDataServiceContext(queryContext, format, tableClient); // Insert Entity BaseEntity baseEntity = new BaseEntity("insert test", "foo" + format.ToString()); // Insert Or Merge with no pre-existing entity MergeEntity insertOrMergeEntity = new MergeEntity(baseEntity.PartitionKey, baseEntity.RowKey); insertOrMergeEntity.Randomize(); ctx.AttachTo(currentTable.Name, insertOrMergeEntity, null); ctx.UpdateObject(insertOrMergeEntity); ctx.SaveChangesWithRetries(); ctx.Detach(insertOrMergeEntity); // Retrieve Entity & Verify Contents UnionEnitity retrievedEntity = (from ent in queryContext.CreateQuery<UnionEnitity>(currentTable.Name) where ent.PartitionKey == baseEntity.PartitionKey && ent.RowKey == baseEntity.RowKey select ent).AsTableServiceQuery(ctx).Execute().FirstOrDefault(); Assert.IsNotNull(retrievedEntity); Assert.AreEqual(insertOrMergeEntity.D, retrievedEntity.D); Assert.AreEqual(insertOrMergeEntity.E, retrievedEntity.E); Assert.AreEqual(insertOrMergeEntity.F, retrievedEntity.F); UnionEnitity mergedEntity = new UnionEnitity("insert test", "foo" + format.ToString()); mergedEntity.Randomize(); mergedEntity.D = insertOrMergeEntity.D; mergedEntity.E = insertOrMergeEntity.E; mergedEntity.F = insertOrMergeEntity.F; ctx.AttachTo(currentTable.Name, mergedEntity, null); ctx.UpdateObject(mergedEntity); ctx.SaveChangesWithRetries(); ctx.Detach(mergedEntity); // Retrieve Entity & Verify retrievedEntity = (from ent in queryContext.CreateQuery<UnionEnitity>(currentTable.Name) where ent.PartitionKey == baseEntity.PartitionKey && ent.RowKey == baseEntity.RowKey select ent).AsTableServiceQuery(queryContext).Execute().FirstOrDefault(); Assert.IsNotNull(retrievedEntity); Assert.AreEqual(mergedEntity.A, retrievedEntity.A); Assert.AreEqual(mergedEntity.B, retrievedEntity.B); Assert.AreEqual(mergedEntity.C, retrievedEntity.C); Assert.AreEqual(mergedEntity.D, retrievedEntity.D); Assert.AreEqual(mergedEntity.E, retrievedEntity.E); Assert.AreEqual(mergedEntity.F, retrievedEntity.F); }
public void TableServiceContextTimeoutDuringSaveChangesNonBatchAPM() { CloudTableClient tableClient = GenerateCloudTableClient(); TableServiceContext ctx = tableClient.GetTableServiceContext(); for (int m = 0; m < 100; m++) { BaseEntity ent = new BaseEntity("testpartition", m.ToString()); ent.Randomize(); ent.A = ent.RowKey; ctx.AddObject(currentTable.Name, ent); } OperationContext opContext = new OperationContext(); TableRequestOptions requestOptions = new TableRequestOptions() { MaximumExecutionTime = TimeSpan.FromSeconds(5) }; using (HttpMangler proxy = new HttpMangler(false, new[] { DelayBehaviors.DelayAllRequestsIf(2000, XStoreSelectors.TableTraffic().IfHostNameContains(tableClient.Credentials.AccountName).SkipNSessions(10)) })) { try { using (ManualResetEvent evt = new ManualResetEvent(false)) { IAsyncResult result = ctx.BeginSaveChangesWithRetries(SaveChangesOptions.None, requestOptions, opContext, (res) => { result = res; evt.Set(); }, null); evt.WaitOne(); ctx.EndSaveChangesWithRetries(result); } ctx.SaveChangesWithRetries(SaveChangesOptions.None, requestOptions, opContext); } catch (StorageException ex) { Assert.AreEqual(ex.RequestInformation.HttpStatusCode, (int)HttpStatusCode.RequestTimeout); Assert.AreEqual("The client could not finish the operation within specified timeout.", ex.Message); Assert.IsTrue(ex.InnerException is TimeoutException); } } }
public void TableServiceContextConcurrencyAllowsOnlySingleOperationAtOnce() { CloudTableClient tableClient = GenerateCloudTableClient(); TableServiceContext tableContext = tableClient.GetTableServiceContext(); // insert entities to query against for (int i = 0; i < 5; i++) { for (int m = 0; m < 100; m++) { BaseEntity ent = new BaseEntity("testpartition" + i, m.ToString()); ent.Randomize(); ent.A = ent.RowKey; tableContext.AddObject(currentTable.Name, ent); } tableContext.SaveChangesWithRetries(SaveChangesOptions.Batch); } List<OperationContext> opContexts = new List<OperationContext>(); object lockerObj = new object(); DateTime start = DateTime.Now; int threadsRunning = 0; Exception lastEx = null; // Start 10 simultaneous threads to query entities associated with same context. for (int j = 0; j < 10; j++) { opContexts.Add(new OperationContext()); Thread newThread = new Thread((arg) => { Interlocked.Increment(ref threadsRunning); try { lock (lockerObj) { Monitor.Wait(lockerObj); } TableServiceQuery<BaseEntity> query = (from ent in tableContext.CreateQuery<BaseEntity>(currentTable.Name) select ent).AsTableServiceQuery(tableContext); Debug.WriteLine(String.Format("Thread {0} start operation @ {1}", Thread.CurrentThread.ManagedThreadId, (DateTime.Now - start).TotalMilliseconds)); try { query.Execute(null, arg as OperationContext).ToList(); } catch (Exception) { // no op, expected to have some exceptions } Debug.WriteLine(String.Format("Thread {0} end operation @ {1}", Thread.CurrentThread.ManagedThreadId, (DateTime.Now - start).TotalMilliseconds)); } catch (Exception ex) { lastEx = ex; } finally { Interlocked.Decrement(ref threadsRunning); } }); newThread.Start(opContexts[j]); } // Wait for all threads to start while (Interlocked.CompareExchange(ref threadsRunning, 10, 10) < 10) { Thread.Sleep(200); } // pulse all threads lock (lockerObj) { Monitor.PulseAll(lockerObj); } // Wait for all threads to complete while (Interlocked.CompareExchange(ref threadsRunning, -1, 0) > -1) { Thread.Sleep(200); } if (lastEx != null) { throw lastEx; } foreach (OperationContext opContext in opContexts) { if (opContext.LastResult == null || opContext.LastResult.StartTime == null || opContext.LastResult.EndTime == null) continue; TestHelper.AssertNAttempts(opContext, 1); RequestResult currRes = opContext.LastResult; // Make sure this results start time does not occur in between any other results start & end time var overlappingResults = (from ctx in opContexts where ctx.LastResult != null && ctx.LastResult != currRes && ctx.LastResult.StartTime != null && ctx.LastResult.EndTime != null && ctx.LastResult.StartTime.Ticks < currRes.StartTime.Ticks && ctx.LastResult.EndTime.Ticks > currRes.StartTime.Ticks select ctx.LastResult); Assert.AreEqual(overlappingResults.Count(), 0, "Detected overlapping query"); } }
public void TableServiceContextOperationContextEventsAPM() { CloudTableClient tableClient = GenerateCloudTableClient(); TableServiceContext ctx = tableClient.GetTableServiceContext(); for (int m = 0; m < 10; m++) { BaseEntity ent = new BaseEntity("testpartition", m.ToString()); ent.Randomize(); ent.A = ent.RowKey; ctx.AddObject(currentTable.Name, ent); } List<string> sends = new List<string>(); List<string> receives = new List<string>(); OperationContext opContext = new OperationContext(); opContext.SendingRequest += (sender, args) => sends.Add(args.RequestInformation.StartTime.Ticks.ToString()); opContext.ResponseReceived += (sender, args) => receives.Add(args.RequestInformation.ServiceRequestID); using (ManualResetEvent evt = new ManualResetEvent(false)) { ctx.BeginSaveChangesWithRetries(SaveChangesOptions.None, null, opContext, (res) => { ctx.EndSaveChangesWithRetries(res); evt.Set(); }, null); evt.WaitOne(); } TestHelper.AssertNAttempts(opContext, 10); Assert.AreEqual(sends.Count(), 10); Assert.AreEqual(receives.Count(), 10); }
public void TableServiceContextRequestResultsAPM() { CloudTableClient tableClient = GenerateCloudTableClient(); TableServiceContext ctx = tableClient.GetTableServiceContext(); for (int m = 0; m < 10; m++) { BaseEntity ent = new BaseEntity("testpartition", m.ToString()); ent.Randomize(); ent.A = ent.RowKey; ctx.AddObject(currentTable.Name, ent); } OperationContext opContext = new OperationContext(); using (ManualResetEvent evt = new ManualResetEvent(false)) { ctx.BeginSaveChangesWithRetries(SaveChangesOptions.None, null, opContext, (res) => { ctx.EndSaveChangesWithRetries(res); evt.Set(); }, null); evt.WaitOne(); } TestHelper.AssertNAttempts(opContext, 10); }
public void TableServiceContextRequestResultsSync() { CloudTableClient tableClient = GenerateCloudTableClient(); TableServiceContext ctx = tableClient.GetTableServiceContext(); for (int m = 0; m < 10; m++) { BaseEntity ent = new BaseEntity("testpartition", m.ToString()); ent.Randomize(); ent.A = ent.RowKey; ctx.AddObject(currentTable.Name, ent); } OperationContext opContext = new OperationContext(); ctx.SaveChangesWithRetries(SaveChangesOptions.None, null, opContext); TestHelper.AssertNAttempts(opContext, 10); }
/// <summary> /// Test a table operation on entities inside and outside the given range. /// </summary> /// <param name="tableName">The name of the table to test.</param> /// <param name="startPk">The start partition key range.</param> /// <param name="startRk">The start row key range.</param> /// <param name="endPk">The end partition key range.</param> /// <param name="endRk">The end row key range.</param> /// <param name="runOperationDelegate">A delegate with the table operation to test.</param> /// <param name="opName">The name of the operation being tested.</param> /// <param name="expectSuccess">Whether the operation should succeed on entities within the range.</param> private void TestOperationWithRange( string tableName, string startPk, string startRk, string endPk, string endRk, Action<BaseEntity> runOperationDelegate, string opName, bool expectSuccess, HttpStatusCode expectedStatusCode, bool isRangeQuery) { CloudTableClient referenceClient = GenerateCloudTableClient(); TableServiceContext referenceContext = referenceClient.GetTableServiceContext(); string partitionKey = startPk ?? endPk ?? "M"; string rowKey = startRk ?? endRk ?? "S"; // if we expect a success for creation - avoid inserting duplicate entities BaseEntity tableEntity = new BaseEntity(partitionKey, rowKey); if (expectedStatusCode == HttpStatusCode.Created) { referenceContext.AttachTo(tableName, tableEntity, "*"); referenceContext.DeleteObject(tableEntity); try { referenceContext.SaveChangesWithRetries(); } catch (Exception) { } } else { // only for add we should not be adding the entity referenceContext.AttachTo(tableName, tableEntity); referenceContext.UpdateObject(tableEntity); referenceContext.SaveChangesWithRetries(SaveChangesOptions.ReplaceOnUpdate); } if (expectSuccess) { runOperationDelegate(tableEntity); } else { TestHelper.ExpectedException( () => runOperationDelegate(tableEntity), string.Format("{0} without appropriate permission.", opName), HttpStatusCode.NotFound); } if (startPk != null) { tableEntity.PartitionKey = "A"; if (startPk.CompareTo(tableEntity.PartitionKey) <= 0) { Assert.Inconclusive("Test error: partition key for this test must not be less than or equal to \"A\""); } TestHelper.ExpectedException( () => runOperationDelegate(tableEntity), string.Format("{0} before allowed partition key range", opName), HttpStatusCode.NotFound); tableEntity.PartitionKey = partitionKey; } if (endPk != null) { tableEntity.PartitionKey = "Z"; if (endPk.CompareTo(tableEntity.PartitionKey) >= 0) { Assert.Inconclusive("Test error: partition key for this test must not be greater than or equal to \"Z\""); } TestHelper.ExpectedException( () => runOperationDelegate(tableEntity), string.Format("{0} after allowed partition key range", opName), HttpStatusCode.NotFound); tableEntity.PartitionKey = partitionKey; } if (startRk != null) { if (isRangeQuery || startPk != null) { tableEntity.PartitionKey = startPk; tableEntity.RowKey = "A"; if (startRk.CompareTo(tableEntity.RowKey) <= 0) { Assert.Inconclusive("Test error: row key for this test must not be less than or equal to \"A\""); } TestHelper.ExpectedException( () => runOperationDelegate(tableEntity), string.Format("{0} before allowed row key range", opName), HttpStatusCode.NotFound); tableEntity.RowKey = rowKey; } } if (endRk != null) { if (isRangeQuery || endPk != null) { tableEntity.PartitionKey = endPk; tableEntity.RowKey = "Z"; if (endRk.CompareTo(tableEntity.RowKey) >= 0) { Assert.Inconclusive("Test error: row key for this test must not be greater than or equal to \"Z\""); } TestHelper.ExpectedException( () => runOperationDelegate(tableEntity), string.Format("{0} after allowed row key range", opName), HttpStatusCode.NotFound); tableEntity.RowKey = rowKey; } } }
public void TableServiceContextOperationContextStartEndTimeAPM() { CloudTableClient tableClient = GenerateCloudTableClient(); TableServiceContext ctx = tableClient.GetTableServiceContext(); DateTime start = DateTime.Now; for (int m = 0; m < 10; m++) { BaseEntity ent = new BaseEntity("testpartition", m.ToString()); ent.Randomize(); ent.A = ent.RowKey; ctx.AddObject(currentTable.Name, ent); } OperationContext opContext = new OperationContext(); using (ManualResetEvent evt = new ManualResetEvent(false)) { ctx.BeginSaveChangesWithRetries(SaveChangesOptions.None, null, opContext, (res) => { ctx.EndSaveChangesWithRetries(res); evt.Set(); }, null); evt.WaitOne(); } Assert.IsNotNull(opContext.StartTime, "StartTime not set"); Assert.IsTrue(opContext.StartTime >= start, "StartTime not set correctly"); Assert.IsNotNull(opContext.EndTime, "EndTime not set"); Assert.IsTrue(opContext.EndTime <= DateTime.Now, "EndTime not set correctly"); }
public void SingleEntityMerge() { CloudTableClient tableClient = GenerateCloudTableClient(); TableServiceContext ctx = tableClient.GetTableServiceContext(); TableServiceContext queryContext = tableClient.GetTableServiceContext(); // Insert Entity BaseEntity baseEntity = new BaseEntity("insert test", "foo"); baseEntity.Randomize(); ctx.AddObject(currentTable.Name, baseEntity); ctx.SaveChangesWithRetries(); string etag = ctx.Entities.First().ETag; ctx.Detach(baseEntity); MergeEntity mergeEntity = new MergeEntity(baseEntity.PartitionKey, baseEntity.RowKey); mergeEntity.Randomize(); ctx.AttachTo(currentTable.Name, mergeEntity, etag); ctx.UpdateObject(mergeEntity); ctx.SaveChangesWithRetries(); // Retrieve Entity UnionEnitity retrievedEntity = (from ent in queryContext.CreateQuery<UnionEnitity>(currentTable.Name) where ent.PartitionKey == baseEntity.PartitionKey && ent.RowKey == baseEntity.RowKey select ent).AsTableServiceQuery(queryContext).Execute().FirstOrDefault(); Assert.IsNotNull(retrievedEntity); Assert.AreEqual(baseEntity.A, retrievedEntity.A); Assert.AreEqual(baseEntity.B, retrievedEntity.B); Assert.AreEqual(baseEntity.C, retrievedEntity.C); Assert.AreEqual(mergeEntity.D, retrievedEntity.D); Assert.AreEqual(mergeEntity.E, retrievedEntity.E); Assert.AreEqual(mergeEntity.F, retrievedEntity.F); }