Skip to content

Commit

Permalink
Sproc test fixes around concurrency tokens
Browse files Browse the repository at this point in the history
Closes #29135
  • Loading branch information
roji committed Sep 19, 2022
1 parent 77887fe commit b4eb7d7
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 21 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -404,17 +404,26 @@ public virtual async Task Store_generated_concurrency_token_as_in_out_parameter(
await using (var context2 = CreateContext())
{
var entity2 = await context2.WithStoreGeneratedConcurrencyTokenAsInOutParameter.SingleAsync(w => w.Name == "Initial");
entity2.Name = "Preempted";
await SaveChanges(context2, async);
}
entity2.Name = "Updated";
ClearLog();
entity1.Name = "Preempted";
await SaveChanges(context1, async);
entity1.Name = "Updated";
ClearLog();
var exception = await Assert.ThrowsAsync<DbUpdateConcurrencyException>(async () => await SaveChanges(context1, async));
var entry = exception.Entries.Single();
Assert.Same(entity1, entry.Entity);
var exception = await Assert.ThrowsAsync<DbUpdateConcurrencyException>(async () => await SaveChanges(context2, async));
var entry = exception.Entries.Single();
Assert.Same(entity2, entry.Entity);
}
// Make sure we propagated the new concurrency token in the update above
using (Fixture.TestSqlLoggerFactory.SuspendRecordingEvents())
{
entity1.Name = "Another update";
await SaveChanges(context1, async);
Assert.Equal("Another update", (await context1.WithStoreGeneratedConcurrencyTokenAsInOutParameter.SingleAsync(w => w.Id == entity1.Id)).Name);
}
}

[ConditionalTheory]
Expand All @@ -430,17 +439,26 @@ public virtual async Task Store_generated_concurrency_token_as_two_parameters(bo
await using (var context2 = CreateContext())
{
var entity2 = await context2.WithStoreGeneratedConcurrencyTokenAsTwoParameters.SingleAsync(w => w.Name == "Initial");
entity2.Name = "Preempted";
await SaveChanges(context2, async);
}
entity2.Name = "Updated";

ClearLog();
entity1.Name = "Preempted";
await SaveChanges(context1, async);

entity1.Name = "Updated";
ClearLog();

var exception = await Assert.ThrowsAsync<DbUpdateConcurrencyException>(async () => await SaveChanges(context1, async));
var entry = exception.Entries.Single();
Assert.Same(entity1, entry.Entity);
var exception = await Assert.ThrowsAsync<DbUpdateConcurrencyException>(async () => await SaveChanges(context2, async));
var entry = exception.Entries.Single();
Assert.Same(entity2, entry.Entity);
}

// Make sure we propagated the new concurrency token in the update above
using (Fixture.TestSqlLoggerFactory.SuspendRecordingEvents())
{
entity1.Name = "Another update";
await SaveChanges(context1, async);

Assert.Equal("Another update", (await context1.WithStoreGeneratedConcurrencyTokenAsTwoParameters.SingleAsync(w => w.Id == entity1.Id)).Name);
}
}

[ConditionalTheory]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -260,13 +260,11 @@ public override async Task Store_generated_concurrency_token_as_two_parameters(b

// Can't assert SQL baseline as usual because the concurrency token changes
Assert.Equal(
@"@p2='Updated' (Size = 4000)
@p3=NULL (Size = 8) (Direction = Output) (DbType = Binary)
@p4='0' (Direction = Output)
@"@p4='0' (Direction = Output)
SET NOCOUNT ON;
EXEC [WithStoreGeneratedConcurrencyTokenAsTwoParameters_Update] @p0, @p1, @p2, @p3 OUTPUT, @p4 OUTPUT;",
Fixture.TestSqlLoggerFactory.Sql.Substring(Fixture.TestSqlLoggerFactory.Sql.IndexOf("@p2", StringComparison.Ordinal)),
Fixture.TestSqlLoggerFactory.Sql.Substring(Fixture.TestSqlLoggerFactory.Sql.IndexOf("@p4", StringComparison.Ordinal)),
ignoreLineEndingDifferences: true);
}

Expand Down Expand Up @@ -528,14 +526,16 @@ CREATE PROCEDURE WithStoreGeneratedConcurrencyTokenAsInOutParameter_Update(@Id i
AS BEGIN
UPDATE [WithStoreGeneratedConcurrencyTokenAsInOutParameter] SET [Name] = @Name WHERE [Id] = @Id AND [ConcurrencyToken] = @ConcurrencyToken;
SET @RowsAffected = @@ROWCOUNT;
SELECT @ConcurrencyToken = [ConcurrencyToken] FROM [WithStoreGeneratedConcurrencyTokenAsInOutParameter] WHERE [Id] = @Id;
END;
GO
CREATE PROCEDURE WithStoreGeneratedConcurrencyTokenAsTwoParameters_Update(@Id int, @ConcurrencyTokenIn rowversion, @Name varchar(max), @ConcurrencyTokenOut rowversion OUT, @RowsAffected int OUT)
AS BEGIN
UPDATE [WithStoreGeneratedConcurrencyTokenAsTwoParameters] SET [Name] = @Name, @ConcurrencyTokenOut = [ConcurrencyToken] WHERE [Id] = @Id AND [ConcurrencyToken] = @ConcurrencyTokenIn;
UPDATE [WithStoreGeneratedConcurrencyTokenAsTwoParameters] SET [Name] = @Name WHERE [Id] = @Id AND [ConcurrencyToken] = @ConcurrencyTokenIn;
SET @RowsAffected = @@ROWCOUNT;
SELECT @ConcurrencyTokenOut = [ConcurrencyToken] FROM [WithStoreGeneratedConcurrencyTokenAsTwoParameters] WHERE [Id] = @Id;
END;
GO
Expand Down

0 comments on commit b4eb7d7

Please sign in to comment.