Skip to content

[Internal] DTS: Refactors casing in DTS response and adds tests#5686

Merged
kirankumarkolli merged 15 commits into
masterfrom
users/Meghana-Palaparthi/distributed-transaction-test-suite
Apr 3, 2026
Merged

[Internal] DTS: Refactors casing in DTS response and adds tests#5686
kirankumarkolli merged 15 commits into
masterfrom
users/Meghana-Palaparthi/distributed-transaction-test-suite

Conversation

@Meghana-Palaparthi
Copy link
Copy Markdown
Contributor

Description

This pull request introduces several important changes to the distributed transactions implementation in Cosmos DB. The main focus is on improving the serialization and deserialization of distributed transaction operation results, updating property names to follow consistent casing, and modernizing how resource bodies are handled in responses. Additionally, it removes the end-to-end tests for distributed transactions and adds other test files.

Key changes include:

Serialization and Deserialization Improvements

  • Replaced the base64-encoded string property resourcebody with a new resourceBody property of type JsonElement in DistributedTransactionOperationResult, allowing direct handling of JSON objects instead of base64 strings. The setter now serializes the JSON element to bytes and populates the ResourceStream.
  • Updated the deserialization logic in FromJson to use json.GetRawText() for more accurate deserialization.

Property Naming and API Consistency

  • Changed JSON property names to use camelCase (e.g., statuscodestatusCode, substatuscodesubStatusCode) for consistency with common JSON conventions.
  • Added subStatusCodeValue as a public property for serialization, mapping to the internal SubStatusCode enum.

Header and Operation Type Handling

  • Updated header value serialization for OperationType and ResourceType to use explicit conversion methods (ToOperationTypeString(), ToResourceTypeString()) instead of .ToString(), ensuring correct string representations in headers.

Test Code Cleanup

  • Removed the entire DistributedTransactionE2ETests.cs file, which contained end-to-end tests for distributed transactions.
  • Added below test files -
Microsoft.Azure.Cosmos.EmulatorTests\DistributedTransaction
----> DistributedTransactionTests.cs

Microsoft.Azure.Cosmos.Tests\DistributedTransaction
----> DistributedTransactionResponseTests.cs
----> DistributedTransactionSerializerTests.cs
----> DistributedWriteTransactionTests.cs

Minor Cleanups

  • Removed SessionToken from response header and deserialization logic

Type of change

Please delete options that are not relevant.

  • [] Bug fix (non-breaking change which fixes an issue)
  • [] New feature (non-breaking change which adds functionality)
  • [] Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • [] This change requires a documentation update

Closing issues

To automatically close an issue: closes #IssueNumber

Copy link
Copy Markdown

@github-actions github-actions Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All good!

@Meghana-Palaparthi Meghana-Palaparthi changed the title [Internal] DTS: Reafctors casing in DTS response and adds tests [Internal] DTS: Refactors casing in DTS response and adds tests Mar 9, 2026
@Meghana-Palaparthi Meghana-Palaparthi marked this pull request as ready for review March 9, 2026 18:32
Meghana-Palaparthi and others added 2 commits March 24, 2026 15:28
…ing and adds DoNotParallelize

Two bugs in DistributedTransactionTests.cs:

1. Mock JSON used all-lowercase property names ('statuscode', 'substatuscode',
   'resourcebody') that do not match the model's JsonPropertyName attributes
   ('statusCode', 'subStatusCode') or the manual TryGetProperty lookup
   ('resourceBody'). System.Text.Json deserialization is case-sensitive, so
   StatusCode was always 0 causing all status-code assertions to fail.

2. Missing [DoNotParallelize] attribute. The TestInitialize calls TestInit()
   which runs DeleteAllDatabasesAsync; without [DoNotParallelize] concurrent
   test execution causes emulator resource contention (same fix as #5711 for
   the predecessor class DistributedTransactionE2ETests).

Also removes stray 'git' text from an inline comment.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@NaluTripician
Copy link
Copy Markdown
Contributor

AI Code Review Summary

PR Intent: Refactors Distributed Transaction response model -- switches from base64-encoded resource bodies to direct JSON objects, standardizes JSON property casing to camelCase, removes SessionToken from response population, and replaces old E2E tests with comprehensive unit + emulator tests.

Overall Assessment: The direction is sound. The new serialization approach and test decomposition are improvements. However, there are test quality issues (mock responses using wrong property casing) and missing test coverage for newly-exposed properties.

Findings Overview

Severity Count Summary
🟡 Recommendation 8 Test casing bugs, missing error handling, wire compatibility, perf regression, missing test coverage, API surface
🟢 Suggestion 3 Stale SessionToken artifacts, mixed deserialization pattern, resourceBody type restriction
💬 Observation 2 Good fixes (.ToString() conversion, test architecture)

Existing comments cross-referenced: 3 found from @kirankumarkolli and @Praveen-Msft. Finding #3 reinforces @Praveen-Msft's unresolved error handling comment. @kirankumarkolli's JsonElement concern was acknowledged by author and addressed by moving to inline handling in FromJson.

See inline comments for details.


⚠️ AI-generated review -- may be incorrect. Agree? ➡️ resolve the conversation. Disagree? ➡️ reply with your reasoning.

/// </summary>
[JsonConstructor]
protected DistributedTransactionOperationResult()
public DistributedTransactionOperationResult()
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Recommendation · API Surface: Constructor Visibility

[JsonConstructor] changed from protected to public

While the class is normally internal (via #if INTERNAL), when compiled as public, this lets consumers construct result objects with default (zero) values, bypassing SDK construction logic. Result types are typically not meant to be user-constructed.

If [JsonConstructor] requires accessibility for deserialization, consider whether internal would suffice (it does for System.Text.Json when the type itself is internal).


⚠️ AI-generated review — may be incorrect. Agree? → resolve the conversation. Disagree? → reply with your reasoning.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The project resolves System.Text.Json 6.0.10. In STJ 6.x, [JsonConstructor] is only honored on public constructors. internal would silently break deserialization.

return JsonSerializer.Deserialize<DistributedTransactionOperationResult>(json);
DistributedTransactionOperationResult result = JsonSerializer.Deserialize<DistributedTransactionOperationResult>(json.GetRawText());

if (json.TryGetProperty("resourceBody", out JsonElement resourceBody)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟢 Suggestion · Maintainability: Mixed Deserialization Pattern

FromJson mixes automatic and manual deserialization

This method uses JsonSerializer.Deserialize for most properties, then manually processes resourceBody via TryGetProperty. This dual pattern is fragile — any future property needing special handling requires updates in both the class attributes AND the manual code in FromJson, with no compile-time safety net.

Consider a custom JsonConverter<DistributedTransactionOperationResult> to centralize all deserialization logic in one place.


⚠️ AI-generated review — may be incorrect. Agree? → resolve the conversation. Disagree? → reply with your reasoning.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

resourcebody is the only property that requires custom handling. Changing deserialization of other properties to reflect the deserialization of resourcebody could introduce a lot of unnecessary manual handling

- Make [JsonConstructor] ctor internal (was public) -- result types should not be externally constructable; System.Text.Json honors [JsonConstructor] on non-public ctors via reflection on .NET 6+
- Use JsonSerializer.Deserialize<T>(JsonElement) overload directly in FromJson instead of json.GetRawText() to avoid unnecessary string allocation
- Wrap JsonSerializer.Deserialize in try-catch(JsonException) in FromJson so a malformed individual operation result returns InternalServerError instead of crashing the entire response parse
- Fix statuscode -> statusCode casing in BuildSuccessResponse/BuildErrorResponse helpers in DistributedWriteTransactionTests and DistributedTransactionSerializerTests
- Add SubStatusCode and RequestCharge deserialization tests to
  DistributedTransactionResponseTests

Co-Authored-By: Copilot <223556219+Copilot@users.noreply.github.com>
Copy link
Copy Markdown
Member

@kirankumarkolli kirankumarkolli left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also make deserialzier case-insensitive?

kirankumarkolli
kirankumarkolli previously approved these changes Apr 1, 2026
- Moves unique coverage from DistributedTransactionE2ETests.cs into
  the appropriate unit test files instead of the emulator test suite:
  - Argument validation (null stream): DistributedWriteTransactionTests
  - Stream serialization + IfMatchEtag: DistributedTransactionSerializerTests
  - PreconditionFailed response: DistributedTransactionResponseTests
- Removes DistributedTransactionE2ETests.cs (superseded).
- Merges origin/master.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@kirankumarkolli kirankumarkolli merged commit c7498ca into master Apr 3, 2026
32 checks passed
@kirankumarkolli kirankumarkolli deleted the users/Meghana-Palaparthi/distributed-transaction-test-suite branch April 3, 2026 16:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants