Skip to content

Conversation

@Enjection
Copy link
Owner

Changelog entry

...

Changelog category

  • New feature
  • Experimental feature
  • Improvement
  • Performance improvement
  • User Interface
  • Bugfix
  • Backward incompatible change
  • Documentation (changelog entry is not required)
  • Not for changelog (changelog entry is not required)

Description for reviewers

...

@coderabbitai
Copy link

coderabbitai bot commented Nov 12, 2025

📝 Walkthrough

Summary by CodeRabbit

Release Notes

  • New Features

    • Enhanced testing framework for parallel schema operations with support for reproducible operation ordering and exhaustive scenario testing.
  • Bug Fixes

    • Improved index entity version synchronization for CDC streams to prevent version downgrades and ensure proper state consistency.
  • Documentation

    • Added comprehensive guides for testing parallel operations and working with order-based test scenarios.

Walkthrough

Introduces a comprehensive operation-order testing framework and documentation for SchemeShard, adds runtime and controller utilities for batching and reordering test operations, new parameterized tests and test macros, and refines index impl table version synchronization logic used during continuous backups/CDC.

Changes

Cohort / File(s) Summary
Testing Plan / Guide
PARALLEL_OPERATIONS_TESTING_PLAN.md, ydb/core/tx/schemeshard/ut_helpers/OPERATION_ORDER_CONTROLLER_USAGE.md
New planning and usage documents describing the phased testing roadmap, operation-order concepts (TOperationOrderController modes, batching, macros, runtimes), sampling strategies, debugging and integration guidance.
Operation Order Controller (core)
ydb/core/tx/schemeshard/ut_helpers/operation_order_controller.h
New controller to generate/replay operation orders (Default, Random, Exhaustive, Deterministic), seed control, permutation iteration, Factorial helper, and TestAllPermutations helper to drive permutation-based test runs.
Runtime Integration & RAII
ydb/core/tx/schemeshard/ut_helpers/operation_order_runtime.h
Adds TOperationOrderRuntimeController to intercept and batch TEvForward events, support Begin/Flush/Cancel batches, optional reordering via attached controller; provides ergonomic TOperationOrderRuntime wrapper and RAII TOperationOrderBatchScope.
Test Macros & Helpers
ydb/core/tx/schemeshard/ut_helpers/operation_order_test_macros.h, ydb/core/tx/schemeshard/ut_helpers/ya.make
New macros and small helpers to read test params and register tests that run with shuffled, exhaustive, or specific orders; build file exposes new headers and testing dependency.
Order Examples & Tests
ydb/core/tx/schemeshard/ut_helpers/operation_order_example_test.cpp, ydb/core/tx/schemeshard/ut_param_test/ut_param_test.cpp
New unit test files demonstrating controller usage, runtime integration, RAII batch scopes, mixed-operation ordering and a parameterized test suite (SimpleParameterReading, PermutationSamplingDemo, ActualSchemeShardTest).
Test Documentation & README
ydb/core/tx/schemeshard/ut_param_test/README.md
README for parameterized tests: usage, sampling strategies, examples, and notes about manual runs and environment mapping.
Build / Make changes
ydb/core/tx/schemeshard/ut_helpers/ya.make, ydb/core/tx/schemeshard/ut_param_test/ya.make, CMakeLists.txt
Registers new test sources and headers, adds peer/test dependencies, marks parameterized suite as manual.
CDC / Version Sync Fixes
ydb/core/tx/schemeshard/schemeshard__operation_common_cdc_stream.cpp
Adjusted SyncImplTableVersion to compute targetVersion = max(parent, indexEntity) and conditionally increment or set implant version; SyncIndexEntityVersion avoids downgrades and only persists/publishes when target > current; UpdateTableVersion delegates to sync logic for index impl + continuous backup paths and logs detailed version actions.

Sequence Diagram(s)

sequenceDiagram
    autonumber
    participant Test as Test / Caller
    participant Controller as TOperationOrderController
    participant RuntimeCtrl as TOperationOrderRuntimeController
    participant SchemeShard as SchemeShard (enqueue path)
    participant PipeCache as TEvPipeCache::TEvForward
    Note over Test,Controller: Test creates controller (mode/seed/orders)
    Test->>RuntimeCtrl: SetOperationOrderController(Controller)
    Test->>RuntimeCtrl: BeginOperationBatch(expectedSize)
    Test->>SchemeShard: Submit operations (enqueued events)
    SchemeShard->>PipeCache: Emit TEvForward events
    PipeCache->>RuntimeCtrl: OnEventObserved(TEvForward) (captured & batched)
    Note over RuntimeCtrl,Controller: When flushing, runtime queries order
    RuntimeCtrl->>Controller: GetNextOrder(batchedTxIds)
    Controller-->>RuntimeCtrl: Ordered indices/sequence
    RuntimeCtrl->>PipeCache: Forward batched events in chosen order
    PipeCache->>SchemeShard: Deliver events (in controlled order)
    RuntimeCtrl->>RuntimeCtrl: Clear batch / reset state
    Test->>RuntimeCtrl: FlushOperationBatch() / End scope
    Note right of Test: Verification waits for completions and asserts results
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

  • Areas requiring close review:
    • ydb/core/tx/schemeshard/schemeshard__operation_common_cdc_stream.cpp — version calculation, persistence, cache invalidation, and logging accuracy.
    • ydb/core/tx/schemeshard/ut_helpers/operation_order_runtime.h — event interception, threading/actor runtime interactions, correctness of batching/flush semantics and edge cases (empty batches, cancellation).
    • ydb/core/tx/schemeshard/ut_helpers/operation_order_controller.h & TestAllPermutations — correctness/performance for exhaustive permutations and sampling strategies.
    • New tests and macros — ensure parameter parsing, seed determinism, and integration with existing test infra (ya.make flags, manual runs).

Poem

🐇 I shuffle orders in the night,

Batches lined up just right.
Seeds and permutations play,
So SchemeShard behaves each way.
A hop, a test — reproducible delight!

Pre-merge checks and finishing touches

❌ Failed checks (1 warning, 2 inconclusive)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 40.91% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
Title check ❓ Inconclusive The title 'WIP' is a generic placeholder that does not convey any meaningful information about the changeset. Replace the generic 'WIP' title with a descriptive summary of the main changes, such as 'Add operation order controller framework for SchemeShard parameterized testing'.
Description check ❓ Inconclusive The PR description contains only a changelog template with placeholder text and no actual description of the changes or their purpose. Provide a meaningful description explaining the purpose of the operation order controller framework, its use cases, and how it integrates with SchemeShard testing.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch bugfix/incr-restore/ss-permutation-testing

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between a56d656 and 8db836c.

📒 Files selected for processing (5)
  • PARALLEL_OPERATIONS_TESTING_PLAN.md (1 hunks)
  • ydb/core/tx/schemeshard/schemeshard__operation_common_cdc_stream.cpp (3 hunks)
  • ydb/core/tx/schemeshard/ut_param_test/README.md (1 hunks)
  • ydb/core/tx/schemeshard/ut_param_test/ut_param_test.cpp (1 hunks)
  • ydb/core/tx/schemeshard/ut_param_test/ya.make (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
ydb/core/tx/schemeshard/ut_param_test/ut_param_test.cpp (1)
ydb/core/tx/schemeshard/ut_helpers/helpers.h (1)
  • NSchemeShardUT_Private (73-737)
🪛 LanguageTool
PARALLEL_OPERATIONS_TESTING_PLAN.md

[style] ~307-~307: The word “ya” is non-standard. Did you mean “you”, “your” or “yes”?
Context: ...rmutation tests, mark them as manual in ya.make: ```ya.make UNITTEST() SRCS( ...

(YA)


[style] ~372-~372: The word “ya” is non-standard. Did you mean “you”, “your” or “yes”?
Context: ...ode:** Manual testing only (marked with ya:manual tag) Complexity Analysis: ...

(YA)


[style] ~380-~380: As an alternative to the over-used intensifier ‘very’, consider replacing this phrase.
Context: ... 7 operations: 7! = 5,040 permutations (very expensive) Example - Full Exhaustive: ```cpp...

(EN_WEAK_ADJECTIVE)


[style] ~390-~390: The word “ya” is non-standard. Did you mean “you”, “your” or “yes”?
Context: ...le orderings when run manually } **ya.make configuration:**ya.make UNITTE...

(YA)


[style] ~488-~488: The word “ya” is non-standard. Did you mean “you”, “your” or “yes”?
Context: ...ration - [ ] Mark exhaustive tests with ya:manual tag in ya.make - [ ] Update `...

(YA)


[style] ~510-~510: The word “ya” is non-standard. Did you mean “you”, “your” or “yes”?
Context: ... strategies work correctly - [ ] Verify ya:manual tag filtering works as expected...

(YA)


[style] ~621-~621: The word “Ya” is non-standard. Did you mean “you”, “your” or “yes”?
Context: ...ransaction ordering tests ## Appendix: Ya Make Testing Reference ### Running Tes...

(YA)


[style] ~624-~624: The word “Ya” is non-standard. Did you mean “you”, “your” or “yes”?
Context: ...Running Tests with Tags and Parameters Ya make supports flexible test execution w...

(YA)


[style] ~704-~704: The word “ya” is non-standard. Did you mean “you”, “your” or “yes”?
Context: ...; } #### 4. Manual Tests Using the ya:manual Tag **In ya.make:**ya.make ...

(YA)


[style] ~706-~706: The word “ya” is non-standard. Did you mean “you”, “your” or “yes”?
Context: ...ual Tests Using the ya:manual Tag In ya.make: ```ya.make UNITTEST() SRCS( ...

(YA)

ydb/core/tx/schemeshard/ut_param_test/README.md

[style] ~3-~3: The word “ya” is non-standard. Did you mean “you”, “your” or “yes”?
Context: ...ng parameter reading functionality with ya make. ## Purpose This test suite dem...

(YA)


[style] ~118-~118: The word “ya” is non-standard. Did you mean “you”, “your” or “yes”?
Context: ... ## Notes - All tests are marked with ya:manual tag and won't run in regular CI...

(YA)

🪛 markdownlint-cli2 (0.18.1)
PARALLEL_OPERATIONS_TESTING_PLAN.md

686-686: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


754-754: Emphasis used instead of a heading

(MD036, no-emphasis-as-heading)


761-761: Emphasis used instead of a heading

(MD036, no-emphasis-as-heading)


768-768: Emphasis used instead of a heading

(MD036, no-emphasis-as-heading)


775-775: Emphasis used instead of a heading

(MD036, no-emphasis-as-heading)

ydb/core/tx/schemeshard/ut_param_test/README.md

108-108: Fenced code blocks should have a language specified

(MD040, fenced-code-language)

Comment on lines +1 to +6
#include <ydb/core/tx/schemeshard/ut_helpers/helpers.h>
#include <library/cpp/testing/unittest/registar.h>
#include <library/cpp/testing/common/env.h>

#include <util/string/cast.h>

Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Add the required headers to keep this file buildable.

std::shuffle, std::sort, std::next_permutation, and std::mt19937 plus THashSet, TStringBuilder, and StringSplitter come from headers that aren’t currently included here. The build depends on transitive includes, which breaks easily with toolchain changes. Please add the direct headers.

 #include <ydb/core/tx/schemeshard/ut_helpers/helpers.h>
 #include <library/cpp/testing/unittest/registar.h>
 #include <library/cpp/testing/common/env.h>

+#include <algorithm>
+#include <random>
+#include <util/generic/hash_set.h>
+#include <util/string/builder.h>
+#include <util/string/split.h>
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
#include <ydb/core/tx/schemeshard/ut_helpers/helpers.h>
#include <library/cpp/testing/unittest/registar.h>
#include <library/cpp/testing/common/env.h>
#include <util/string/cast.h>
#include <ydb/core/tx/schemeshard/ut_helpers/helpers.h>
#include <library/cpp/testing/unittest/registar.h>
#include <library/cpp/testing/common/env.h>
#include <algorithm>
#include <random>
#include <util/generic/hash_set.h>
#include <util/string/builder.h>
#include <util/string/split.h>
#include <util/string/cast.h>
🤖 Prompt for AI Agents
In ydb/core/tx/schemeshard/ut_param_test/ut_param_test.cpp around lines 1 to 6,
the file relies on transitive includes for std::shuffle, std::sort,
std::next_permutation, std::mt19937 and for THashSet, TStringBuilder,
StringSplitter; add direct includes to make the file buildable and robust:
include <algorithm> for sort/shuffle/next_permutation, <random> for mt19937, and
the project utility headers such as <util/generic/hash_set.h> for THashSet,
<util/string/builder.h> for TStringBuilder, and <util/string/split.h> (or the
correct util split header used in the codebase) for StringSplitter.

This commit implements a comprehensive framework for testing parallel operation
orderings in SchemeShard to catch order-dependent bugs and race conditions.

Key Components:
- TOperationOrderController: Core controller supporting Default, Random,
  Exhaustive, and Deterministic ordering modes
- Test Macros: Y_UNIT_TEST_WITH_ORDER_SHUFFLE, Y_UNIT_TEST_ALL_ORDERS,
  Y_UNIT_TEST_WITH_SPECIFIC_ORDER
- Sampling Strategies: all, random, distributed, first - for handling
  large permutation spaces

Features:
- Zero production code overhead (manual integration pattern)
- Seed-based reproducibility for random testing
- Support for test parameters via ya make --test-param
- Template-based design works with any operation type
- Comprehensive documentation and examples

Files Added:
- ydb/core/tx/schemeshard/ut_helpers/operation_order_controller.h
  Core controller class with ordering strategies
- ydb/core/tx/schemeshard/ut_helpers/operation_order_test_macros.h
  Test helper macros for easy test creation
- ydb/core/tx/schemeshard/ut_helpers/OPERATION_ORDER_CONTROLLER_USAGE.md
  Comprehensive usage guide with examples
- ydb/core/tx/schemeshard/ut_helpers/operation_order_example_test.cpp
  Example tests demonstrating all patterns

Files Modified:
- PARALLEL_OPERATIONS_TESTING_PLAN.md
  Updated with implementation progress (Phases 1, 3, 5 complete)
- ydb/core/tx/schemeshard/ut_helpers/ya.make
  Added new headers and library/cpp/testing/common dependency

Implementation Status:
- Phase 1: Infrastructure ✅ COMPLETED
- Phase 2: SchemeShard Integration ⚠️ DEFERRED (manual pattern chosen)
- Phase 3: Test Helpers ✅ COMPLETED
- Phase 4: Test Migration ⏳ READY TO START
- Phase 5: Documentation ✅ COMPLETED
- Phase 6: Validation ⏳ PENDING

Next Steps:
1. Migrate existing parallel tests to use the framework
2. Validate sampling strategies with real tests
3. Measure performance impact

Related to incremental restore and parallel operation testing.
This commit completes Phase 2 of the operation order testing framework by
adding runtime integration that automatically intercepts and reorders
operations without requiring test code modifications.

Key Features:
- TOperationOrderRuntimeController: Uses event observers to intercept
  TEvPipeCache::TEvForward events going to SchemeShard
- TOperationOrderRuntime: Clean wrapper API for tests
- TOperationOrderBatchScope: RAII helper for automatic batch management
- Zero overhead when not used (observer only active during batching)
- Works with existing test helpers (TestCreateSequence, etc.)

Usage Example:
    TOperationOrderRuntime orderedRuntime(runtime);
    TOperationOrderController controller;
    controller.SetMode(TOperationOrderController::Random, 42);
    orderedRuntime.SetOperationOrderController(&controller);

    {
        TOperationOrderBatchScope batch(orderedRuntime, 4);
        TestCreateSequence(runtime, ++txId, "/MyRoot", R"(Name: "seq1")");
        // ... more operations
    } // Auto-flush and reorder

Files Added:
- ydb/core/tx/schemeshard/ut_helpers/operation_order_runtime.h
  Runtime integration with event observation

Files Modified:
- ydb/core/tx/schemeshard/ut_helpers/operation_order_example_test.cpp
  Added Examples 6-8 demonstrating runtime integration
- ydb/core/tx/schemeshard/ut_helpers/OPERATION_ORDER_CONTROLLER_USAGE.md
  Added comprehensive runtime integration documentation
- ydb/core/tx/schemeshard/ut_helpers/ya.make
  Added operation_order_runtime.h

Implementation Status:
- Phase 2: SchemeShard Integration ✅ COMPLETED
  * Automatic event interception via observers
  * No production code changes
  * Clean RAII API

Benefits Over Manual Approach:
1. Zero test code changes - use existing helpers
2. Automatic event interception
3. RAII scopes for clean management
4. Flexible - change orderings between batches
5. Debuggable - built-in operation logging

Next Steps:
- Begin test migration (Phase 4)
- Validate framework with real tests
Mark Phase 2 as completed with full runtime integration implementation.
Framework now provides three usage patterns: test macros, runtime
integration, and manual controller usage.

All foundation phases (1, 2, 3, 5) are now complete. Ready for Phase 4
(test migration) and Phase 6 (validation).
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 4

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 8db836c and 044fff2.

📒 Files selected for processing (7)
  • PARALLEL_OPERATIONS_TESTING_PLAN.md (1 hunks)
  • ydb/core/tx/schemeshard/ut_helpers/OPERATION_ORDER_CONTROLLER_USAGE.md (1 hunks)
  • ydb/core/tx/schemeshard/ut_helpers/operation_order_controller.h (1 hunks)
  • ydb/core/tx/schemeshard/ut_helpers/operation_order_example_test.cpp (1 hunks)
  • ydb/core/tx/schemeshard/ut_helpers/operation_order_runtime.h (1 hunks)
  • ydb/core/tx/schemeshard/ut_helpers/operation_order_test_macros.h (1 hunks)
  • ydb/core/tx/schemeshard/ut_helpers/ya.make (2 hunks)
🧰 Additional context used
🧬 Code graph analysis (4)
ydb/core/tx/schemeshard/ut_helpers/operation_order_controller.h (1)
ydb/core/tx/schemeshard/ut_helpers/operation_order_test_macros.h (2)
  • NSchemeShardUT_Private (10-17)
  • TVector (90-92)
ydb/core/tx/schemeshard/ut_helpers/operation_order_example_test.cpp (2)
ydb/core/tx/schemeshard/ut_helpers/operation_order_runtime.h (1)
  • NSchemeShardUT_Private (12-319)
ydb/core/tx/schemeshard/ut_helpers/operation_order_test_macros.h (1)
  • NSchemeShardUT_Private (10-17)
ydb/core/tx/schemeshard/ut_helpers/operation_order_test_macros.h (1)
ydb/core/tx/schemeshard/ut_helpers/operation_order_example_test.cpp (1)
  • Y_UNIT_TEST_WITH_ORDER_SHUFFLE (26-61)
ydb/core/tx/schemeshard/ut_helpers/operation_order_runtime.h (2)
ydb/library/actors/testlib/test_runtime.h (1)
  • IEventHandle (230-238)
ydb/core/tx/schemeshard/ut_helpers/operation_order_controller.h (1)
  • TOperationOrderController (27-60)
🪛 LanguageTool
PARALLEL_OPERATIONS_TESTING_PLAN.md

[style] ~307-~307: The word “ya” is non-standard. Did you mean “you”, “your” or “yes”?
Context: ...rmutation tests, mark them as manual in ya.make: ```ya.make UNITTEST() SRCS( ...

(YA)


[style] ~372-~372: The word “ya” is non-standard. Did you mean “you”, “your” or “yes”?
Context: ...ode:** Manual testing only (marked with ya:manual tag) Complexity Analysis: ...

(YA)


[style] ~380-~380: As an alternative to the over-used intensifier ‘very’, consider replacing this phrase.
Context: ... 7 operations: 7! = 5,040 permutations (very expensive) Example - Full Exhaustive: ```cpp...

(EN_WEAK_ADJECTIVE)


[style] ~390-~390: The word “ya” is non-standard. Did you mean “you”, “your” or “yes”?
Context: ...le orderings when run manually } **ya.make configuration:**ya.make UNITTE...

(YA)


[style] ~525-~525: The word “ya” is non-standard. Did you mean “you”, “your” or “yes”?
Context: ...stParamUi32() helpers - Uses standard ya make test parameter passing ### Phase ...

(YA)


[style] ~528-~528: The word “ya” is non-standard. Did you mean “you”, “your” or “yes”?
Context: ...TARTED - [ ] Mark exhaustive tests with ya:manual tag in ya.make - **Next Ste...

(YA)


[style] ~580-~580: The word “ya” is non-standard. Did you mean “you”, “your” or “yes”?
Context: ...validation with real tests - [ ] Verify ya:manual tag filtering works as expected...

(YA)


[style] ~581-~581: The word “ya” is non-standard. Did you mean “you”, “your” or “yes”?
Context: ...d - Status: Needs validation with ya make ## Implementation Progress Summar...

(YA)


[style] ~725-~725: The word “Ya” is non-standard. Did you mean “you”, “your” or “yes”?
Context: ...ransaction ordering tests ## Appendix: Ya Make Testing Reference ### Running Tes...

(YA)


[style] ~728-~728: The word “Ya” is non-standard. Did you mean “you”, “your” or “yes”?
Context: ...Running Tests with Tags and Parameters Ya make supports flexible test execution w...

(YA)


[style] ~808-~808: The word “ya” is non-standard. Did you mean “you”, “your” or “yes”?
Context: ...; } #### 4. Manual Tests Using the ya:manual Tag **In ya.make:**ya.make ...

(YA)


[style] ~810-~810: The word “ya” is non-standard. Did you mean “you”, “your” or “yes”?
Context: ...ual Tests Using the ya:manual Tag In ya.make: ```ya.make UNITTEST() SRCS( ...

(YA)

ydb/core/tx/schemeshard/ut_helpers/OPERATION_ORDER_CONTROLLER_USAGE.md

[style] ~132-~132: The word “ya” is non-standard. Did you mean “you”, “your” or “yes”?
Context: ...ameters For exhaustive tests marked as ya:manual, control behavior via command-l...

(YA)


[style] ~351-~351: The word “ya” is non-standard. Did you mean “you”, “your” or “yes”?
Context: ...ugging - [ ] Mark exhaustive tests with ya:manual tag - [ ] Document expected beh...

(YA)

🪛 markdownlint-cli2 (0.18.1)
PARALLEL_OPERATIONS_TESTING_PLAN.md

790-790: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


858-858: Emphasis used instead of a heading

(MD036, no-emphasis-as-heading)


865-865: Emphasis used instead of a heading

(MD036, no-emphasis-as-heading)


872-872: Emphasis used instead of a heading

(MD036, no-emphasis-as-heading)


879-879: Emphasis used instead of a heading

(MD036, no-emphasis-as-heading)

Comment on lines +69 to +72
for (int i = 0; i < 4; ++i) {
txIds.push_back(++txId);
}

Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Declare txId before it’s incremented in the manual example

Line 71 increments txId, but the snippet never declares or initializes it. Copying this example as-is will not compile. Please add the declaration right after the runtime/env setup before the loop.

 Y_UNIT_TEST(ManualOrderTest) {
     TTestBasicRuntime runtime;
     TTestEnv env(runtime);
 
+    ui64 txId = 100;
     // Create controller
     TOperationOrderController controller;

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In ydb/core/tx/schemeshard/ut_helpers/OPERATION_ORDER_CONTROLLER_USAGE.md around
lines 69 to 72, the example increments txId inside the loop but never declares
or initializes it; declare and initialize txId (for example to 0 or the
appropriate starting transaction id for the example) immediately after the
runtime/env setup and before the for loop so the snippet compiles when copied.

Comment on lines +10 to +11
#include <random>
#include <algorithm>
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Prevent factorial overflow breaking sampling.

Factorial silently wraps at numOperations >= 21, so totalPermutations becomes zero. In random sampling we then bail out immediately (testedCount < totalPermutations is false) and skip every test. That’s a major functional gap once the operation count grows.

Please make the factorial helper saturate instead of wrapping and add the needed header:

@@
-#include <algorithm>
+#include <algorithm>
+#include <limits>
@@
 inline ui64 Factorial(ui64 n) {
     ui64 result = 1;
     for (ui64 i = 2; i <= n; ++i) {
-        result *= i;
+        if (result > std::numeric_limits<ui64>::max() / i) {
+            return std::numeric_limits<ui64>::max();
+        }
+        result *= i;
     }
     return result;
 }

With this change, totalPermutations never collapses to zero, so random sampling keeps exercising permutations even for large test sets.

Also applies to: 159-165, 186-208

🤖 Prompt for AI Agents
In ydb/core/tx/schemeshard/ut_helpers/operation_order_controller.h (around lines
10-11 and also update the helper usages at 159-165 and 186-208), replace the
current factorial helper that overflows with one that uses a fixed unsigned
integer type (e.g., uint64_t), include the required headers (<cstdint> and
<limits>), and implement saturation on overflow by returning
std::numeric_limits<uint64_t>::max() once multiplication would exceed that
limit; update code that computes totalPermutations to use the uint64_t saturated
result so it never becomes zero, and apply the same saturated-factorial change
to the other two ranges mentioned.

Comment on lines +37 to +60
EOrderMode Mode = Default;
TVector<ui64> PredefinedOrder;
std::mt19937 RandomGen;
ui32 CurrentPermutation = 0;
ui32 Seed = 0;
bool HasMorePermutationsValue = false;

public:
TOperationOrderController()
: RandomGen(0)
{}

/**
* Set the ordering mode
* @param mode - The ordering strategy to use
* @param seed - Random seed for reproducibility (used in Random mode)
*/
void SetMode(EOrderMode mode, ui32 seed = 0) {
Mode = mode;
Seed = seed;
RandomGen.seed(seed);
CurrentPermutation = 0;
HasMorePermutationsValue = (mode == Exhaustive);
}
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

Fix exhaustive permutation state tracking.

GetNextOrder rebuilds the permutation source from the original operations vector on every call. As soon as you advance past the first permutation, every subsequent request starts from the original order again, so we keep returning the same few permutations and never reach the rest. Exhaustive mode is therefore broken and tests that rely on it get false confidence.

Please persist the permutation indices across calls and only advance them when more permutations are available. One way to do this is to stash an index vector in the controller, initialise it once, advance it with std::next_permutation, and rebuild HasMorePermutationsValue from that state:

@@
-    TVector<ui64> PredefinedOrder;
+    TVector<ui64> PredefinedOrder;
+    TVector<ui64> ExhaustiveOrder;
+    bool ExhaustiveInitialized = false;
@@
-        CurrentPermutation = 0;
-        HasMorePermutationsValue = (mode == Exhaustive);
+        CurrentPermutation = 0;
+        HasMorePermutationsValue = false;
+        ExhaustiveOrder.clear();
+        ExhaustiveInitialized = false;
@@
-            case Exhaustive: {
-                TVector<T> result = operations;
-                if (CurrentPermutation > 0) {
-                    // Generate next permutation
-                    HasMorePermutationsValue = std::next_permutation(result.begin(), result.end());
-                } else {
-                    // First permutation - ensure sorted order
-                    std::sort(result.begin(), result.end());
-                    HasMorePermutationsValue = true;
-                }
-                CurrentPermutation++;
-                return result;
-            }
+            case Exhaustive: {
+                if (!ExhaustiveInitialized) {
+                    ExhaustiveOrder.resize(operations.size());
+                    std::iota(ExhaustiveOrder.begin(), ExhaustiveOrder.end(), ui64{0});
+                    ExhaustiveInitialized = true;
+                } else {
+                    Y_ENSURE(ExhaustiveOrder.size() == operations.size(),
+                             "Operation set size changed between permutations");
+                    Y_ENSURE(HasMorePermutationsValue,
+                             "No more permutations available");
+                    Y_ENSURE(std::next_permutation(ExhaustiveOrder.begin(),
+                                                   ExhaustiveOrder.end()),
+                             "Failed to advance permutation");
+                }
+
+                TVector<T> result;
+                result.reserve(operations.size());
+                for (ui64 idx : ExhaustiveOrder) {
+                    result.push_back(operations[idx]);
+                }
+
+                TVector<ui64> peek = ExhaustiveOrder;
+                HasMorePermutationsValue = std::next_permutation(peek.begin(), peek.end());
+                CurrentPermutation++;
+                return result;
+            }
@@
     void Reset() {
         CurrentPermutation = 0;
         RandomGen.seed(Seed);
-        HasMorePermutationsValue = (Mode == Exhaustive);
+        HasMorePermutationsValue = false;
+        ExhaustiveOrder.clear();
+        ExhaustiveInitialized = false;
     }

Also applies to: 88-113, 128-132

🤖 Prompt for AI Agents
In ydb/core/tx/schemeshard/ut_helpers/operation_order_controller.h around lines
37 to 60, exhaustive permutation mode currently rebuilds the permutation source
from the original operations on every GetNextOrder call which resets progress;
fix by adding and persisting a permutation index vector (e.g., TVector<ui64>
PermutationIndices) initialized once when SetMode(Exhaustive, ...) is called
from the initial range [0..n-1], use std::next_permutation on that index vector
to advance between calls instead of recreating it, rebuild
HasMorePermutationsValue from whether next_permutation returned true (or when
permutation cycles back), and ensure CurrentPermutation/Seed logic updates
accordingly so subsequent GetNextOrder calls use the persisted indices to
produce new permutations until exhausted.

Comment on lines +11 to +38
#include "operation_order_test_macros.h"
#include "operation_order_controller.h"
#include "operation_order_runtime.h"
#include "helpers.h"

#include <library/cpp/testing/unittest/registar.h>

using namespace NSchemeShardUT_Private;

Y_UNIT_TEST_SUITE(TOperationOrderExamples) {

/**
* Example 1: Simple test with random shuffling
* This test runs with both default order and 10 random orders
*/
Y_UNIT_TEST_WITH_ORDER_SHUFFLE(SimpleRandomShuffleExample) {
TTestBasicRuntime runtime;
TTestEnv env(runtime);
ui64 txId = 100;

runtime.SetLogPriority(NKikimrServices::FLAT_TX_SCHEMESHARD, NActors::NLog::PRI_TRACE);

// Note: 'mode' template parameter is automatically provided by the macro
TOperationOrderController controller;
controller.SetMode(mode, 42); // seed = 42 for reproducibility

// Collect operations to be reordered
TVector<ui64> txIds;
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

Include <functional> for std::function

operations is declared as TVector<std::function<ui64()>>, but <functional> is not included. This prevents the example from compiling once the file is built. Please add the standard header to the include block.

 #include "operation_order_runtime.h"
 #include "helpers.h"
 
+#include <functional>
🤖 Prompt for AI Agents
In ydb/core/tx/schemeshard/ut_helpers/operation_order_example_test.cpp around
lines 11 to 38, the code declares TVector<std::function<ui64()>> but the
<functional> header is not included; add #include <functional> to the include
block at the top of the file so std::function is defined and the file compiles.

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.

3 participants