Skip to content

Conversation

@RS146BIJAY
Copy link
Contributor

Description

This PR fixes following:

  • Enable all integ test for CAS.
  • Enable searchIdle for CAS.
  • Fix remote store test cases for CAS.
  • Fix regresion due to excessive flushes during syncing child writers with parent writers.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jan 21, 2026

Important

Review skipped

Auto incremental reviews are disabled on this repository.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

📝 Walkthrough

Walkthrough

This PR introduces a context-aware migration experimental feature by adding a CONTEXT_AWARE_MIGRATION_EXPERIMENTAL_FLAG flag, implementing a ContextAwareIndexPlugin for test frameworks with document grouping listener capabilities, modifying core indexing logic in CompositeIndexWriter, and updating integration tests to enable and utilize the new functionality.

Changes

Cohort / File(s) Summary
Feature Flag Infrastructure
server/src/main/java/org/opensearch/common/settings/FeatureFlagSettings.java
Added CONTEXT_AWARE_MIGRATION_EXPERIMENTAL_SETTING to the BUILT_IN_FEATURE_FLAGS set for framework-level flag registration.
Core Engine Logic
server/src/main/java/org/opensearch/index/engine/CompositeIndexWriter.java
Modified lock acquisition to unlock and return null when target lookup is closed; introduced collection-based batching for Directory objects during refresh path with accumulated pending document count updates.
IndexShard Behavior
server/src/main/java/org/opensearch/index/shard/IndexShard.java
Removed context awareness check from isSearchIdleSupported() guard, decoupling search-idle support from context-aware state.
Test Framework - Context-Aware Plugin
test/framework/src/main/java/org/opensearch/test/OpenSearchIntegTestCase.java
Introduced ContextAwareIndexPlugin and ContextAwareIndexOperationListener inner classes; listener sets document grouping criteria to "-1" during preIndex when enabled; updated additionalNodePlugins() to return plugin info.
Test Framework - Plugin Integration
test/framework/src/main/java/org/opensearch/test/OpenSearchSingleNodeTestCase.java, test/framework/src/main/java/org/opensearch/snapshots/AbstractSnapshotIntegTestCase.java, test/framework/src/main/java/org/opensearch/test/AbstractMultiClustersTestCase.java
Updated plugin configurations to include ContextAwareIndexPlugin in node setup for single-node and multi-cluster test cases.
Remote Store Test Framework
test/framework/src/main/java/org/opensearch/remotestore/RemoteStoreBaseIntegTestCase.java
Added FLUSHED_OPERATIONS constant and tracking; incremented flush counter after each flush operation and persisted count in result map.
Remote Store Core Tests
test/framework/src/main/java/org/opensearch/remotestore/RemoteStoreCoreTestCase.java
Introduced extraMetadataFilesDueToFlush computation based on context-aware setting and flush operation counts; adjusted expected file count assertions to account for extra metadata files when context-aware is enabled.
Integration Tests - Feature Flag Enablement
server/src/internalClusterTest/java/org/opensearch/action/admin/cluster/node/tasks/ConcurrentSearchTasksIT.java, server/src/internalClusterTest/java/org/opensearch/cluster/routing/allocation/decider/ShardsLimitAllocationDeciderIT.java, server/src/internalClusterTest/java/org/opensearch/cluster/shards/ClusterShardLimitIT.java, server/src/internalClusterTest/java/org/opensearch/indices/memory/breaker/CircuitBreakerNoopIT.java, server/src/internalClusterTest/java/org/opensearch/indices/replication/WarmIndexSegmentReplicationIT.java, server/src/internalClusterTest/java/org/opensearch/remotestore/WritableWarmIT.java, server/src/test/java/org/opensearch/action/admin/indices/tiering/TransportHotToWarmTieringActionTests.java
Enabled CONTEXT_AWARE_MIGRATION_EXPERIMENTAL_FLAG in feature flag settings across multiple test classes.
Integration Tests - Plugin Addition
modules/transport-grpc/src/internalClusterTest/java/org/opensearch/transport/grpc/LoadExtendingPluginServicesIT.java, server/src/internalClusterTest/java/org/opensearch/plugins/ClasspathPluginIT.java
Added ContextAwareIndexPlugin to additionalNodePlugins() list for GrpcPlugin and classpath plugin tests.
Integration Test - IndexShard Construction
server/src/internalClusterTest/java/org/opensearch/index/shard/IndexShardIT.java
Added ContextAwareIndexOperationListener() argument to newIndexShard() construction call.

Sequence Diagram

sequenceDiagram
    participant Client as Test Client
    participant Plugin as ContextAwareIndexPlugin
    participant Engine as Indexing Engine
    participant Listener as ContextAwareIndexOperationListener
    participant Index as Index

    Client->>Plugin: Initialize cluster with plugin
    Plugin->>Plugin: onIndexModule() invoked
    Plugin->>Engine: Register ContextAwareIndexOperationListener
    
    Client->>Engine: Submit index request
    Engine->>Listener: preIndex(IndexingOperationListener.Context)
    Listener->>Listener: Check if context-aware enabled
    alt Context-Aware Enabled
        Listener->>Index: Set document grouping criteria to "-1"
        Listener->>Engine: Return context with modified criteria
    else Context-Aware Disabled
        Listener->>Engine: Return unmodified context
    end
    Engine->>Index: Index document with criteria
    Engine->>Client: Return success
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

🚥 Pre-merge checks | ✅ 2 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 15.63% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately describes the main objective of the PR: enabling integration test cases for context-aware segments. It is concise, clear, and specific to the primary change.
Description check ✅ Passed The PR description provides specific implementation details (enabling integ tests for CAS, enabling searchIdle, fixing remote store tests, fixing regression with flushes) but uses the template structure and covers the main objectives effectively.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


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

Copy link
Contributor

@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: 3

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
server/src/main/java/org/opensearch/index/shard/IndexShard.java (1)

4992-5001: Update the comment to reflect current behavior and verify CAS sync correctness with search-idle enabled.

The inline comment at line 4995–4996 states that context-aware indices disable search-idle to ensure periodic sync between parent and child IndexWriter, but the implementation (line 5001) does not check for context-aware enablement. This mismatch is misleading. Since CAS indices use CompositeIndexWriter that relies on periodic refreshes to sync writers, confirm that skipping refreshes due to search-idle does not break that sync (e.g., via integration tests).

💡 Suggested comment update
-    // TODO: Should we disable this as data will never get in sync if we use search idle for context aware segments.
-    public final boolean isSearchIdleSupported() {
-        // If the index is remote store backed, then search idle is not supported. This is to ensure that async
-        // refresh. If the index is context aware enabled, search idle is not supported. This will ensure periodic sync
-        // between child and parent IndexWriter.
-        // task continues to upload to remote store periodically.
+    // Search-idle is disabled only for remote-store backed indices to ensure async refresh/upload keeps running.
+    public final boolean isSearchIdleSupported() {
+        // For remote-store backed indices, search idle is not supported to ensure async refresh/upload keeps running.
         if (isRemoteTranslogEnabled() || indexSettings.isAssignedOnRemoteNode()) {
             return false;
         }
         return indexSettings.isSegRepEnabledOrRemoteNode() == false || indexSettings.getNumberOfReplicas() == 0;
     }
🤖 Fix all issues with AI agents
In
`@modules/transport-grpc/src/internalClusterTest/java/org/opensearch/transport/grpc/LoadExtendingPluginServicesIT.java`:
- Around line 112-122: The PluginInfo instantiation references
ContextAwareIndexPlugin.class.getName() without an import and uses inconsistent
symbols/values; replace the bare reference with the nested class reference
OpenSearchIntegTestCase.ContextAwareIndexPlugin.class.getName() (or add the
appropriate import for ContextAwareIndexPlugin), change
org.opensearch.Version.CURRENT to the already-used Version.CURRENT for
consistency, and update the plugin version string "1.8" to match the other
plugins (e.g., "21") so PluginInfo, ContextAwareIndexPlugin, and Version.CURRENT
usages compile and are consistent.

In `@server/src/main/java/org/opensearch/index/engine/CompositeIndexWriter.java`:
- Around line 548-554: The loop in CompositeIndexWriter is closing each child
IndexWriter before calling getPendingNumDocs(), which can throw
AlreadyClosedException; change the loop to first obtain a local reference to the
child writer (e.g., IndexWriter iw = childDisposableWriter.getIndexWriter()),
then call iw.getPendingNumDocs() and add to pendingNumDocsByOldChildWriter, then
collect iw.getDirectory() and finally call iw.close(); update uses of
getIndexWriter() in the loop to that local variable (refer to
markForRefreshIndexWritersMap, DisposableIndexWriter, getIndexWriter(),
getPendingNumDocs(), getDirectory(), close()).

In
`@test/framework/src/main/java/org/opensearch/snapshots/AbstractSnapshotIntegTestCase.java`:
- Around line 157-159: Replace the unresolved ContextAwareIndexPlugin reference
in nodePlugins() by using the fully qualified nested class used elsewhere:
change ContextAwareIndexPlugin.class to
OpenSearchIntegTestCase.ContextAwareIndexPlugin.class (so nodePlugins() returns
List.of(MockRepository.Plugin.class,
OpenSearchIntegTestCase.ContextAwareIndexPlugin.class)); this avoids adding an
import and matches other usages.
🧹 Nitpick comments (2)
server/src/main/java/org/opensearch/index/engine/CompositeIndexWriter.java (1)

348-357: Align timeout-based tryAcquire with closed-map handling.
tryAcquire() now unlocks and returns null when the lookup is closed, but tryAcquire(TimeValue) can still return a closed lookup. Consider mirroring the closed check there to keep semantics consistent and avoid operations on closed maps in timeout code paths.

modules/transport-grpc/src/internalClusterTest/java/org/opensearch/transport/grpc/LoadExtendingPluginServicesIT.java (1)

116-117: Inconsistent version and redundant qualification.

Two minor observations:

  1. The plugin version "1.8" differs from other plugins in this file which use "21". Verify if this is intentional.
  2. org.opensearch.Version.CURRENT at line 116 is fully qualified, but Version is already imported at line 11, so you can use Version.CURRENT for consistency with line 94.
Suggested fix
            new PluginInfo(
                ContextAwareIndexPlugin.class.getName(),
                "classpath plugin",
                "NA",
-               org.opensearch.Version.CURRENT,
-               "1.8",
+               Version.CURRENT,
+               "21",
                ContextAwareIndexPlugin.class.getName(),
                null,
                Collections.emptyList(),
                false
            )
📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 68c2d14 and 290d970.

📒 Files selected for processing (19)
  • modules/transport-grpc/src/internalClusterTest/java/org/opensearch/transport/grpc/LoadExtendingPluginServicesIT.java
  • server/src/internalClusterTest/java/org/opensearch/action/admin/cluster/node/tasks/ConcurrentSearchTasksIT.java
  • server/src/internalClusterTest/java/org/opensearch/cluster/routing/allocation/decider/ShardsLimitAllocationDeciderIT.java
  • server/src/internalClusterTest/java/org/opensearch/cluster/shards/ClusterShardLimitIT.java
  • server/src/internalClusterTest/java/org/opensearch/index/shard/IndexShardIT.java
  • server/src/internalClusterTest/java/org/opensearch/indices/memory/breaker/CircuitBreakerNoopIT.java
  • server/src/internalClusterTest/java/org/opensearch/indices/replication/WarmIndexSegmentReplicationIT.java
  • server/src/internalClusterTest/java/org/opensearch/plugins/ClasspathPluginIT.java
  • server/src/internalClusterTest/java/org/opensearch/remotestore/WritableWarmIT.java
  • server/src/main/java/org/opensearch/common/settings/FeatureFlagSettings.java
  • server/src/main/java/org/opensearch/index/engine/CompositeIndexWriter.java
  • server/src/main/java/org/opensearch/index/shard/IndexShard.java
  • server/src/test/java/org/opensearch/action/admin/indices/tiering/TransportHotToWarmTieringActionTests.java
  • test/framework/src/main/java/org/opensearch/remotestore/RemoteStoreBaseIntegTestCase.java
  • test/framework/src/main/java/org/opensearch/remotestore/RemoteStoreCoreTestCase.java
  • test/framework/src/main/java/org/opensearch/snapshots/AbstractSnapshotIntegTestCase.java
  • test/framework/src/main/java/org/opensearch/test/AbstractMultiClustersTestCase.java
  • test/framework/src/main/java/org/opensearch/test/OpenSearchIntegTestCase.java
  • test/framework/src/main/java/org/opensearch/test/OpenSearchSingleNodeTestCase.java
🧰 Additional context used
🧠 Learnings (4)
📚 Learning: 2026-01-13T17:40:27.167Z
Learnt from: reta
Repo: opensearch-project/OpenSearch PR: 20411
File: server/src/main/java/org/opensearch/index/codec/CodecService.java:112-133
Timestamp: 2026-01-13T17:40:27.167Z
Learning: Avoid capturing or evaluating a supplier (e.g., this::defaultCodec) upfront when passing it to a registry during object construction. If registries may replace defaults during iteration (as in EnginePlugin.getAdditionalCodecs), pass the supplier itself and only resolve it at use time. This ensures dynamic behavior is preserved during initialization and prevents premature binding of defaults in codecs/registry setup. This pattern should apply to similar initialization paths in Java server code where registries may mutate defaults during construction.

Applied to files:

  • server/src/main/java/org/opensearch/common/settings/FeatureFlagSettings.java
  • server/src/main/java/org/opensearch/index/shard/IndexShard.java
  • server/src/main/java/org/opensearch/index/engine/CompositeIndexWriter.java
📚 Learning: 2025-12-02T22:44:14.799Z
Learnt from: prudhvigodithi
Repo: opensearch-project/OpenSearch PR: 20112
File: server/src/internalClusterTest/java/org/opensearch/search/slice/SearchSliceIT.java:73-81
Timestamp: 2025-12-02T22:44:14.799Z
Learning: In OpenSearch integration tests extending OpenSearchIntegTestCase, using `LuceneTestCase.SuppressCodecs("*")` triggers special handling that selects a random production codec from the CODECS array, while `SuppressCodecs("Asserting")` or other specific codec suppressions still allow Lucene's default codec randomization which may include the asserting codec. Use `SuppressCodecs("*")` when you need to completely avoid asserting codecs (e.g., for cross-thread StoredFieldsReader usage) while maintaining production codec test coverage.

Applied to files:

  • server/src/internalClusterTest/java/org/opensearch/index/shard/IndexShardIT.java
📚 Learning: 2026-01-02T19:23:16.689Z
Learnt from: karenyrx
Repo: opensearch-project/OpenSearch PR: 20335
File: modules/transport-grpc/src/main/java/org/opensearch/transport/grpc/proto/request/search/SearchSourceBuilderProtoUtils.java:155-172
Timestamp: 2026-01-02T19:23:16.689Z
Learning: In OpenSearch's gRPC transport module, treat removals of previously-unsupported fields (those throwing UnsupportedOperationException) from experimental proto schemas as non-breaking changes. When reviewing changes to proto-related Java code in this module, document that such removals do not count as breaking API changes, and ensure tests reflect compatibility expectations accordingly.

Applied to files:

  • modules/transport-grpc/src/internalClusterTest/java/org/opensearch/transport/grpc/LoadExtendingPluginServicesIT.java
📚 Learning: 2025-12-12T13:31:51.234Z
Learnt from: andriyredko
Repo: opensearch-project/OpenSearch PR: 20017
File: plugins/transport-reactor-netty4/src/test/java/org/opensearch/http/reactor/netty4/ssl/SecureReactorNetty4HttpServerTransportTests.java:642-646
Timestamp: 2025-12-12T13:31:51.234Z
Learning: In the OpenSearch ReactorNetty4 secure HTTP transport tests (plugins/transport-reactor-netty4/src/test/java/org/opensearch/http/reactor/netty4/ssl/SecureReactorNetty4HttpServerTransportTests.java), the createBuilderWithPort() helper intentionally uses randomBoolean() for the HTTP/3 enabled setting to ensure all tests validate correct behavior with both HTTP/3 enabled and disabled configurations.

Applied to files:

  • test/framework/src/main/java/org/opensearch/test/OpenSearchIntegTestCase.java
🧬 Code graph analysis (9)
server/src/internalClusterTest/java/org/opensearch/cluster/routing/allocation/decider/ShardsLimitAllocationDeciderIT.java (1)
server/src/main/java/org/opensearch/common/util/FeatureFlags.java (1)
  • FeatureFlags (29-341)
server/src/test/java/org/opensearch/action/admin/indices/tiering/TransportHotToWarmTieringActionTests.java (1)
server/src/main/java/org/opensearch/common/util/FeatureFlags.java (1)
  • FeatureFlags (29-341)
server/src/main/java/org/opensearch/common/settings/FeatureFlagSettings.java (1)
server/src/main/java/org/opensearch/common/util/FeatureFlags.java (1)
  • FeatureFlags (29-341)
server/src/internalClusterTest/java/org/opensearch/remotestore/WritableWarmIT.java (1)
server/src/main/java/org/opensearch/common/util/FeatureFlags.java (1)
  • FeatureFlags (29-341)
server/src/internalClusterTest/java/org/opensearch/indices/memory/breaker/CircuitBreakerNoopIT.java (1)
server/src/main/java/org/opensearch/common/util/FeatureFlags.java (1)
  • FeatureFlags (29-341)
server/src/internalClusterTest/java/org/opensearch/action/admin/cluster/node/tasks/ConcurrentSearchTasksIT.java (1)
server/src/main/java/org/opensearch/common/util/FeatureFlags.java (1)
  • FeatureFlags (29-341)
server/src/internalClusterTest/java/org/opensearch/index/shard/IndexShardIT.java (2)
server/src/internalClusterTest/java/org/opensearch/indices/memory/breaker/CircuitBreakerNoopIT.java (1)
  • OpenSearchIntegTestCase (52-100)
server/src/internalClusterTest/java/org/opensearch/plugins/ClasspathPluginIT.java (1)
  • OpenSearchIntegTestCase (21-86)
server/src/internalClusterTest/java/org/opensearch/indices/replication/WarmIndexSegmentReplicationIT.java (1)
server/src/main/java/org/opensearch/common/util/FeatureFlags.java (1)
  • FeatureFlags (29-341)
server/src/internalClusterTest/java/org/opensearch/cluster/shards/ClusterShardLimitIT.java (1)
server/src/main/java/org/opensearch/common/util/FeatureFlags.java (1)
  • FeatureFlags (29-341)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (20)
  • GitHub Check: gradle-check
  • GitHub Check: detect-breaking-change
  • GitHub Check: Analyze (java)
  • GitHub Check: precommit (21, macos-15)
  • GitHub Check: precommit (25, ubuntu-24.04-arm)
  • GitHub Check: precommit (25, windows-latest)
  • GitHub Check: precommit (25, macos-15-intel)
  • GitHub Check: precommit (21, macos-15-intel)
  • GitHub Check: precommit (21, windows-latest)
  • GitHub Check: precommit (25, macos-15)
  • GitHub Check: precommit (21, windows-2025, true)
  • GitHub Check: precommit (21, ubuntu-latest)
  • GitHub Check: precommit (25, ubuntu-latest)
  • GitHub Check: precommit (21, ubuntu-24.04-arm)
  • GitHub Check: assemble (21, windows-latest)
  • GitHub Check: assemble (25, ubuntu-24.04-arm)
  • GitHub Check: assemble (25, windows-latest)
  • GitHub Check: assemble (25, ubuntu-latest)
  • GitHub Check: assemble (21, ubuntu-latest)
  • GitHub Check: assemble (21, ubuntu-24.04-arm)
🔇 Additional comments (23)
server/src/main/java/org/opensearch/index/engine/CompositeIndexWriter.java (1)

42-48: No issues found.

server/src/internalClusterTest/java/org/opensearch/remotestore/WritableWarmIT.java (1)

77-82: LGTM!

The addition of CONTEXT_AWARE_MIGRATION_EXPERIMENTAL_FLAG follows the existing pattern for enabling experimental feature flags in this test class. The import for FeatureFlags is already present.

server/src/main/java/org/opensearch/common/settings/FeatureFlagSettings.java (1)

41-42: LGTM!

The addition of CONTEXT_AWARE_MIGRATION_EXPERIMENTAL_SETTING to BUILT_IN_FEATURE_FLAGS is required to register the new experimental feature flag with the settings framework. This correctly aligns with the flag definition in FeatureFlags.java.

server/src/test/java/org/opensearch/action/admin/indices/tiering/TransportHotToWarmTieringActionTests.java (1)

47-52: LGTM!

The addition of CONTEXT_AWARE_MIGRATION_EXPERIMENTAL_FLAG follows the existing pattern. Note that this test class is currently disabled via @LuceneTestCase.AwaitsFix(bugUrl = "") annotation at line 39.

server/src/internalClusterTest/java/org/opensearch/cluster/shards/ClusterShardLimitIT.java (1)

140-145: LGTM!

The addition of CONTEXT_AWARE_MIGRATION_EXPERIMENTAL_FLAG correctly follows the existing pattern for enabling experimental feature flags in this parameterized test class.

server/src/internalClusterTest/java/org/opensearch/cluster/routing/allocation/decider/ShardsLimitAllocationDeciderIT.java (1)

105-110: LGTM!

The addition of CONTEXT_AWARE_MIGRATION_EXPERIMENTAL_FLAG correctly follows the existing pattern for enabling experimental feature flags in this parameterized test class.

server/src/internalClusterTest/java/org/opensearch/index/shard/IndexShardIT.java (2)

98-98: LGTM!

The import is correctly added to access the ContextAwareIndexOperationListener inner class from OpenSearchIntegTestCase.


668-669: LGTM!

The ContextAwareIndexOperationListener is correctly added as a second listener to the newIndexShard call. The method signature at line 696 accepts varargs (IndexingOperationListener... listeners), so this correctly passes both the local listener and the new context-aware listener to enable the experimental feature during shard recovery tests.

server/src/internalClusterTest/java/org/opensearch/indices/memory/breaker/CircuitBreakerNoopIT.java (2)

37-37: LGTM!

Import correctly added for FeatureFlags to access the context-aware migration flag constant.


63-63: LGTM!

The CONTEXT_AWARE_MIGRATION_EXPERIMENTAL_FLAG is correctly enabled in nodeSettings(). This aligns with the PR objective to enable context-aware segments for integration tests.

server/src/internalClusterTest/java/org/opensearch/indices/replication/WarmIndexSegmentReplicationIT.java (1)

160-160: LGTM!

The CONTEXT_AWARE_MIGRATION_EXPERIMENTAL_FLAG is correctly added to featureFlagSettings() alongside the existing WRITABLE_WARM_INDEX_EXPERIMENTAL_FLAG. This enables both experimental features for warm index segment replication tests as intended.

server/src/internalClusterTest/java/org/opensearch/action/admin/cluster/node/tasks/ConcurrentSearchTasksIT.java (2)

18-18: LGTM!

Import correctly added for FeatureFlags.


71-72: LGTM!

The CONTEXT_AWARE_MIGRATION_EXPERIMENTAL_FLAG is correctly enabled after the built-in feature flags loop. This ensures the flag is explicitly set to true for concurrent search task tests, regardless of its default value.

test/framework/src/main/java/org/opensearch/test/OpenSearchIntegTestCase.java (4)

137-146: Import-only change — no review needed.

Also applies to: 230-230


696-698: Randomized CAS index setting looks good.

This keeps coverage for both CAS-enabled and disabled indices via existing randomized settings.


717-717: Base feature flag enablement is clear.

Enabling the CAS experimental flag here aligns with the test-wide intent.


2019-2031: ContextAwareIndexPlugin wiring is clean.

Listener registration is correctly gated on the index setting, keeping behavior scoped.

Also applies to: 3012-3034

test/framework/src/main/java/org/opensearch/test/OpenSearchSingleNodeTestCase.java (1)

277-279: CAS plugin added to single-node harness looks good.

Ensures the listener is available for single-node tests.

server/src/internalClusterTest/java/org/opensearch/plugins/ClasspathPluginIT.java (1)

68-79: Classpath plugin list update looks fine.

ContextAwareIndexPlugin aligns with other test harness updates.

test/framework/src/main/java/org/opensearch/test/AbstractMultiClustersTestCase.java (1)

80-82: CAS plugin inclusion for multi-cluster nodes looks good.

test/framework/src/main/java/org/opensearch/remotestore/RemoteStoreBaseIntegTestCase.java (1)

78-79: Flush count tracking integrates cleanly with existing stats.

The new FLUSHED_OPERATIONS metric will help downstream tests adjust expectations.

Also applies to: 105-111, 137-140

test/framework/src/main/java/org/opensearch/remotestore/RemoteStoreCoreTestCase.java (2)

18-18: Import-only change — no review needed.


221-258: CAS-aware metadata file accounting is a good test hardening.

Using FLUSHED_OPERATIONS to adjust expectations should reduce CAS-related flakiness.

Also applies to: 276-298, 338-359

✏️ Tip: You can disable this entire section by setting review_details to false in your review settings.

Comment on lines +112 to 122
new PluginInfo(
ContextAwareIndexPlugin.class.getName(),
"classpath plugin",
"NA",
org.opensearch.Version.CURRENT,
"1.8",
ContextAwareIndexPlugin.class.getName(),
null,
Collections.emptyList(),
false
)
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🏁 Script executed:

# Find ContextAwareIndexPlugin and check its package
fd -t f 'ContextAwareIndexPlugin.java' --exec head -30 {}

Repository: opensearch-project/OpenSearch

Length of output: 55


🏁 Script executed:

# Check the imports and full context of the test file
cat -n modules/transport-grpc/src/internalClusterTest/java/org/opensearch/transport/grpc/LoadExtendingPluginServicesIT.java | head -130

Repository: opensearch-project/OpenSearch

Length of output: 5465


🏁 Script executed:

# Search for all PluginInfo entries to compare versions
rg -A 10 "new PluginInfo" modules/transport-grpc/src/internalClusterTest/java/org/opensearch/transport/grpc/LoadExtendingPluginServicesIT.java

Repository: opensearch-project/OpenSearch

Length of output: 1130


🏁 Script executed:

# Search for ContextAwareIndexPlugin class definition anywhere in codebase
rg "class ContextAwareIndexPlugin" -A 3

Repository: opensearch-project/OpenSearch

Length of output: 529


🏁 Script executed:

# Also search for any reference to ContextAwareIndexPlugin to understand context
rg "ContextAwareIndexPlugin" --type java

Repository: opensearch-project/OpenSearch

Length of output: 1624


🏁 Script executed:

# Check how ContextAwareIndexPlugin is imported/used in ClasspathPluginIT.java
cat -n server/src/internalClusterTest/java/org/opensearch/plugins/ClasspathPluginIT.java | head -150

Repository: opensearch-project/OpenSearch

Length of output: 3295


🏁 Script executed:

# Check the OpenSearchIntegTestCase file to understand the class structure
cat -n test/framework/src/main/java/org/opensearch/test/OpenSearchIntegTestCase.java | grep -A 30 "public static class ContextAwareIndexPlugin"

Repository: opensearch-project/OpenSearch

Length of output: 1159


🏁 Script executed:

# Check what LoadExtendingPluginServicesIT extends and if it has access to ContextAwareIndexPlugin
rg -A 5 "class LoadExtendingPluginServicesIT" modules/transport-grpc/src/internalClusterTest/java/org/opensearch/transport/grpc/LoadExtendingPluginServicesIT.java

Repository: opensearch-project/OpenSearch

Length of output: 445


🏁 Script executed:

# Check what GrpcTransportBaseIT is and what it extends
fd -t f 'GrpcTransportBaseIT.java' --exec head -50 {}

Repository: opensearch-project/OpenSearch

Length of output: 2007


🏁 Script executed:

# Check if LoadExtendingPluginServicesIT imports ContextAwareIndexPlugin or OpenSearchIntegTestCase
cat -n modules/transport-grpc/src/internalClusterTest/java/org/opensearch/transport/grpc/LoadExtendingPluginServicesIT.java | grep -E "import|ContextAware|OpenSearchIntegTestCase"

Repository: opensearch-project/OpenSearch

Length of output: 1086


🏁 Script executed:

# Check how nested class access works - verify if similar patterns exist in the codebase
rg "OpenSearchIntegTestCase\.ContextAwareIndexPlugin" --type java

Repository: opensearch-project/OpenSearch

Length of output: 412


Add missing import for ContextAwareIndexPlugin or use fully qualified name.

The code references ContextAwareIndexPlugin.class.getName() (lines 113, 118) but does not import it. Although ContextAwareIndexPlugin is a static nested class of OpenSearchIntegTestCase (which GrpcTransportBaseIT extends), the bare reference will not compile without an import. Either import OpenSearchIntegTestCase or use OpenSearchIntegTestCase.ContextAwareIndexPlugin.class.getName().

Additionally, line 116 inconsistently uses org.opensearch.Version.CURRENT instead of the imported Version.CURRENT (used at lines 94 and 105). And the version "1.8" for ContextAwareIndexPlugin differs from "21" used for the other plugins in this same method.

🤖 Prompt for AI Agents
In
`@modules/transport-grpc/src/internalClusterTest/java/org/opensearch/transport/grpc/LoadExtendingPluginServicesIT.java`
around lines 112 - 122, The PluginInfo instantiation references
ContextAwareIndexPlugin.class.getName() without an import and uses inconsistent
symbols/values; replace the bare reference with the nested class reference
OpenSearchIntegTestCase.ContextAwareIndexPlugin.class.getName() (or add the
appropriate import for ContextAwareIndexPlugin), change
org.opensearch.Version.CURRENT to the already-used Version.CURRENT for
consistency, and update the plugin version string "1.8" to match the other
plugins (e.g., "21") so PluginInfo, ContextAwareIndexPlugin, and Version.CURRENT
usages compile and are consistent.

Comment on lines +548 to +554
final List<Directory> directoryToCombine = new ArrayList<>();
final AtomicLong pendingNumDocsByOldChildWriter = new AtomicLong();
for (CompositeIndexWriter.DisposableIndexWriter childDisposableWriter : markForRefreshIndexWritersMap.values()) {
directoryToCombine = childDisposableWriter.getIndexWriter().getDirectory();
directoryToCombine.add(childDisposableWriter.getIndexWriter().getDirectory());
childDisposableWriter.getIndexWriter().close();
long pendingNumDocsByOldChildWriter = childDisposableWriter.getIndexWriter().getPendingNumDocs();
accumulatingIndexWriter.addIndexes(directoryToCombine);
pendingNumDocsByOldChildWriter.addAndGet(childDisposableWriter.getIndexWriter().getPendingNumDocs());
}
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Read pending docs before closing child writers.
Line 552 closes the IndexWriter before Line 553 calls getPendingNumDocs(). That can throw AlreadyClosedException or return an invalid value, leading to incorrect pending-doc accounting. Fetch pending count before closing.

✅ Proposed fix
-        for (CompositeIndexWriter.DisposableIndexWriter childDisposableWriter : markForRefreshIndexWritersMap.values()) {
-            directoryToCombine.add(childDisposableWriter.getIndexWriter().getDirectory());
-            childDisposableWriter.getIndexWriter().close();
-            pendingNumDocsByOldChildWriter.addAndGet(childDisposableWriter.getIndexWriter().getPendingNumDocs());
-        }
+        for (CompositeIndexWriter.DisposableIndexWriter childDisposableWriter : markForRefreshIndexWritersMap.values()) {
+            IndexWriter childWriter = childDisposableWriter.getIndexWriter();
+            directoryToCombine.add(childWriter.getDirectory());
+            pendingNumDocsByOldChildWriter.addAndGet(childWriter.getPendingNumDocs());
+            childWriter.close();
+        }
📝 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
final List<Directory> directoryToCombine = new ArrayList<>();
final AtomicLong pendingNumDocsByOldChildWriter = new AtomicLong();
for (CompositeIndexWriter.DisposableIndexWriter childDisposableWriter : markForRefreshIndexWritersMap.values()) {
directoryToCombine = childDisposableWriter.getIndexWriter().getDirectory();
directoryToCombine.add(childDisposableWriter.getIndexWriter().getDirectory());
childDisposableWriter.getIndexWriter().close();
long pendingNumDocsByOldChildWriter = childDisposableWriter.getIndexWriter().getPendingNumDocs();
accumulatingIndexWriter.addIndexes(directoryToCombine);
pendingNumDocsByOldChildWriter.addAndGet(childDisposableWriter.getIndexWriter().getPendingNumDocs());
}
final List<Directory> directoryToCombine = new ArrayList<>();
final AtomicLong pendingNumDocsByOldChildWriter = new AtomicLong();
for (CompositeIndexWriter.DisposableIndexWriter childDisposableWriter : markForRefreshIndexWritersMap.values()) {
IndexWriter childWriter = childDisposableWriter.getIndexWriter();
directoryToCombine.add(childWriter.getDirectory());
pendingNumDocsByOldChildWriter.addAndGet(childWriter.getPendingNumDocs());
childWriter.close();
}
🤖 Prompt for AI Agents
In `@server/src/main/java/org/opensearch/index/engine/CompositeIndexWriter.java`
around lines 548 - 554, The loop in CompositeIndexWriter is closing each child
IndexWriter before calling getPendingNumDocs(), which can throw
AlreadyClosedException; change the loop to first obtain a local reference to the
child writer (e.g., IndexWriter iw = childDisposableWriter.getIndexWriter()),
then call iw.getPendingNumDocs() and add to pendingNumDocsByOldChildWriter, then
collect iw.getDirectory() and finally call iw.close(); update uses of
getIndexWriter() in the loop to that local variable (refer to
markForRefreshIndexWritersMap, DisposableIndexWriter, getIndexWriter(),
getPendingNumDocs(), getDirectory(), close()).

Comment on lines 157 to 158
protected Collection<Class<? extends Plugin>> nodePlugins() {
return Arrays.asList(MockRepository.Plugin.class);
return List.of(MockRepository.Plugin.class, ContextAwareIndexPlugin.class);
}
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Check imports in AbstractSnapshotIntegTestCase.java
head -100 test/framework/src/main/java/org/opensearch/snapshots/AbstractSnapshotIntegTestCase.java | grep -n "import"

Repository: opensearch-project/OpenSearch

Length of output: 3599


🏁 Script executed:

#!/bin/bash
# Search for ContextAwareIndexPlugin references
rg -n "ContextAwareIndexPlugin" test/framework/src/main/java/org/opensearch/snapshots/AbstractSnapshotIntegTestCase.java

Repository: opensearch-project/OpenSearch

Length of output: 160


🏁 Script executed:

#!/bin/bash
# Find where ContextAwareIndexPlugin is defined
rg -n "class ContextAwareIndexPlugin" --type java

Repository: opensearch-project/OpenSearch

Length of output: 220


🏁 Script executed:

#!/bin/bash
# Check the class declaration and what AbstractSnapshotIntegTestCase extends
rg -n "^public.*class AbstractSnapshotIntegTestCase" -A 2 test/framework/src/main/java/org/opensearch/snapshots/AbstractSnapshotIntegTestCase.java

Repository: opensearch-project/OpenSearch

Length of output: 272


🏁 Script executed:

#!/bin/bash
# Check if ContextAwareIndexPlugin needs to be imported or if it's statically available
# Look for any static import or reference pattern
grep -n "static.*import\|OpenSearchIntegTestCase" test/framework/src/main/java/org/opensearch/snapshots/AbstractSnapshotIntegTestCase.java | head -20

Repository: opensearch-project/OpenSearch

Length of output: 271


🏁 Script executed:

#!/bin/bash
# Check what ParameterizedStaticSettingsOpenSearchIntegTestCase extends
rg -n "^public.*class ParameterizedStaticSettingsOpenSearchIntegTestCase" -A 1 test/framework/src/main/java/org/opensearch/test/ParameterizedStaticSettingsOpenSearchIntegTestCase.java

Repository: opensearch-project/OpenSearch

Length of output: 199


🏁 Script executed:

#!/bin/bash
# Also check OpenSearchIntegTestCase hierarchy
rg -n "^public.*class OpenSearchIntegTestCase" -A 1 test/framework/src/main/java/org/opensearch/test/OpenSearchIntegTestCase.java | head -5

Repository: opensearch-project/OpenSearch

Length of output: 156


🏁 Script executed:

#!/bin/bash
# Check ParameterizedOpenSearchIntegTestCase extends clause
rg -n "^public.*class ParameterizedOpenSearchIntegTestCase" -A 1 test/framework/src/main/java/org/opensearch/test/ParameterizedOpenSearchIntegTestCase.java

Repository: opensearch-project/OpenSearch

Length of output: 55


🏁 Script executed:

#!/bin/bash
# Check if ContextAwareIndexPlugin can be accessed without import by testing Java's nested class accessibility rules
# Let's verify if the code would compile by checking if there's a pattern of using OpenSearchIntegTestCase.ContextAwareIndexPlugin elsewhere
rg -n "OpenSearchIntegTestCase\.ContextAwareIndexPlugin" --type java

Repository: opensearch-project/OpenSearch

Length of output: 419


Fix the compilation error: ContextAwareIndexPlugin cannot be resolved.

Line 158 uses ContextAwareIndexPlugin.class without importing it. Since ContextAwareIndexPlugin is a public static inner class of OpenSearchIntegTestCase (not inherited by AbstractSnapshotIntegTestCase), it must be either imported explicitly or referenced with its full qualifier. Other usages in the codebase (e.g., OpenSearchSingleNodeTestCase.java, AbstractMultiClustersTestCase.java) use the fully qualified form: OpenSearchIntegTestCase.ContextAwareIndexPlugin.class. Apply the same pattern here.

🤖 Prompt for AI Agents
In
`@test/framework/src/main/java/org/opensearch/snapshots/AbstractSnapshotIntegTestCase.java`
around lines 157 - 159, Replace the unresolved ContextAwareIndexPlugin reference
in nodePlugins() by using the fully qualified nested class used elsewhere:
change ContextAwareIndexPlugin.class to
OpenSearchIntegTestCase.ContextAwareIndexPlugin.class (so nodePlugins() returns
List.of(MockRepository.Plugin.class,
OpenSearchIntegTestCase.ContextAwareIndexPlugin.class)); this avoids adding an
import and matches other usages.

@github-actions
Copy link
Contributor

❌ Gradle check result for 290d970: FAILURE

Please examine the workflow log, locate, and copy-paste the failure(s) below, then iterate to green. Is the failure a flaky test unrelated to your change?

.getSetting(INDEX_NAME, IndexSettings.INDEX_CONTEXT_AWARE_ENABLED_SETTING.getKey());
if (isCASEnabled != null && isCASEnabled.equals("true")) {
// For CAS enabled domains, there will be an extra refresh for each OpenSearch flush call.
extraMetadataFilesDueToFlush += indexingStats.get(FLUSHED_OPERATIONS);

Check failure

Code scanning / CodeQL

Implicit narrowing conversion in compound assignment

Implicit cast of source type Long to narrower destination type [int](1).
.getSetting(INDEX_NAME, IndexSettings.INDEX_CONTEXT_AWARE_ENABLED_SETTING.getKey());
if (isCASEnabled != null && isCASEnabled.equals("true")) {
// For CAS enabled domains, there will be an extra refresh for each OpenSearch flush call.
extraMetadataFilesDueToFlush += indexingStats.get(FLUSHED_OPERATIONS);

Check failure

Code scanning / CodeQL

Implicit narrowing conversion in compound assignment

Implicit cast of source type Long to narrower destination type [int](1).
.getSetting(INDEX_NAME, IndexSettings.INDEX_CONTEXT_AWARE_ENABLED_SETTING.getKey());
if (isCASEnabled != null && isCASEnabled.equals("true")) {
// For CAS enabled domains, there will be an extra refresh for each OpenSearch flush call.
extraMetadataFilesDueToFlush += indexingStats.get(FLUSHED_OPERATIONS);

Check failure

Code scanning / CodeQL

Implicit narrowing conversion in compound assignment

Implicit cast of source type Long to narrower destination type [int](1).
@RS146BIJAY RS146BIJAY force-pushed the enable-test-case-final branch from 290d970 to 2077eea Compare January 24, 2026 10:42
@github-actions
Copy link
Contributor

❌ Gradle check result for 2077eea: FAILURE

Please examine the workflow log, locate, and copy-paste the failure(s) below, then iterate to green. Is the failure a flaky test unrelated to your change?

Signed-off-by: RS146BIJAY <rishavsagar4b1@gmail.com>
@RS146BIJAY RS146BIJAY force-pushed the enable-test-case-final branch from 2077eea to 8ec0419 Compare January 24, 2026 11:12
@github-actions
Copy link
Contributor

❌ Gradle check result for 8ec0419: FAILURE

Please examine the workflow log, locate, and copy-paste the failure(s) below, then iterate to green. Is the failure a flaky test unrelated to your change?

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.

1 participant