-
Notifications
You must be signed in to change notification settings - Fork 27
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Stored json gets corrupted on SqlServer after an update with a smalle…
…r sized payload (#1331) * Fix issue where sql parameter optimalisation was applied for INSERT/UPDATE. Now only applied for `ExecuteReaderAsync` and `ExecuteReaderAsync`. * Fix failing CI tests due to new test using incorrect table for testing * Updated the test name to better express its intent
- Loading branch information
1 parent
23a7a0c
commit 3f48828
Showing
4 changed files
with
120 additions
and
12 deletions.
There are no files selected for viewing
93 changes: 93 additions & 0 deletions
93
src/SqlPersistence.PersistenceTests/When_updating_saga_with_smaller_state.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
namespace NServiceBus.PersistenceTesting.Sagas | ||
{ | ||
using System; | ||
using System.Linq; | ||
using System.Threading.Tasks; | ||
using NUnit.Framework; | ||
|
||
public class When_updating_saga_with_smaller_state : SagaPersisterTests | ||
{ | ||
[Test] | ||
public async Task It_should_truncate_the_stored_state() | ||
{ | ||
// When updating an existing saga where the serialized state is smaller in length than the previous the column value should not have any left over data from the previous value. | ||
// The deserializer ignores any trailing | ||
|
||
var sqlVariant = (SqlTestVariant)param.Values[0]; | ||
|
||
if (sqlVariant.Dialect is not SqlDialect.MsSqlServer) | ||
{ | ||
Assert.Ignore("Only relevant for SQL Server"); | ||
return; // Satisfy compiler | ||
} | ||
|
||
var sagaData = new SagaWithCorrelationPropertyData | ||
{ | ||
CorrelatedProperty = Guid.NewGuid().ToString(), | ||
Payload = "very long state" | ||
}; | ||
|
||
await SaveSaga(sagaData); | ||
|
||
SagaWithCorrelationPropertyData retrieved; | ||
var context = configuration.GetContextBagForSagaStorage(); | ||
var persister = configuration.SagaStorage; | ||
|
||
using (var completeSession = configuration.CreateStorageSession()) | ||
{ | ||
await completeSession.Open(context); | ||
|
||
retrieved = await persister.Get<SagaWithCorrelationPropertyData>(nameof(sagaData.CorrelatedProperty), sagaData.CorrelatedProperty, completeSession, context); | ||
|
||
retrieved.Payload = "short"; | ||
|
||
await persister.Update(retrieved, completeSession, context); | ||
await completeSession.CompleteAsync(); | ||
} | ||
|
||
var retrieved2 = await GetById<SagaWithCorrelationPropertyData>(sagaData.Id); | ||
|
||
Assert.LessOrEqual(retrieved.Payload, sagaData.Payload); // No real need, but here to prevent accidental updates | ||
Assert.AreEqual(retrieved.Payload, retrieved2.Payload); | ||
|
||
await using var con = sqlVariant.Open(); | ||
await con.OpenAsync(); | ||
var cmd = con.CreateCommand(); | ||
cmd.CommandText = $"SELECT Data FROM [PersistenceTests_SWCP] WHERE Id = '{retrieved.Id}'"; | ||
var data = (string)await cmd.ExecuteScalarAsync(); | ||
|
||
// Payload should only have a single closing bracket, if there are more that means there is trailing data | ||
var countClosingBrackets = data.ToCharArray().Count(x => x == '}'); | ||
|
||
Assert.AreEqual(1, countClosingBrackets); | ||
} | ||
|
||
public class SagaWithCorrelationProperty : Saga<SagaWithCorrelationPropertyData>, IAmStartedByMessages<StartMessage> | ||
{ | ||
public Task Handle(StartMessage message, IMessageHandlerContext context) | ||
{ | ||
throw new NotImplementedException(); | ||
} | ||
|
||
protected override void ConfigureHowToFindSaga(SagaPropertyMapper<SagaWithCorrelationPropertyData> mapper) | ||
{ | ||
mapper.ConfigureMapping<StartMessage>(msg => msg.SomeId).ToSaga(saga => saga.CorrelatedProperty); | ||
} | ||
} | ||
|
||
public class SagaWithCorrelationPropertyData : ContainSagaData | ||
{ | ||
public string CorrelatedProperty { get; set; } | ||
public string Payload { get; set; } | ||
} | ||
|
||
public class StartMessage | ||
{ | ||
public string SomeId { get; set; } | ||
} | ||
|
||
public When_updating_saga_with_smaller_state(TestVariant param) : base(param) | ||
{ | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters