RANGER-5647: Fix date-bound tag policy engine test fixtures#1018
Merged
Conversation
RESTRICTED-FINAL deny-exception uses isAccessedBefore(activation_date). Fixture dates were 2026/06/15, so TestPolicyEngine_hiveForTag_filebased failed on/after that day. Use 2099/12/31 in tag test JSON so CI stays stable without changing policy semantics under test. Co-authored-by: Cursor <cursoragent@cursor.com>
3 tasks
mneethiraj
approved these changes
Jun 15, 2026
RecursiveWildcardResourceMatcher reused a shared wildcardPathElements
field when expanding {USER} tokens, causing intermittent deny results
under concurrent policy evaluation (e.g. hdfs_resourcespec in CI).
Co-authored-by: Cursor <cursoragent@cursor.com>
ramackri
pushed a commit
to ramackri/ranger
that referenced
this pull request
Jun 16, 2026
PR apache#1018 updated slash-format tag fixture dates to 2099/12/31 but left 2026-06-15 ISO expiry_date values in test_policyengine_tag_hive.json. After 2026-06-15, TestPolicyEngine.testPolicyEngine_hiveForTag fails CI with isAllowed expected true but was false for EXPIRES_ON SELF match. Co-authored-by: Cursor <cursoragent@cursor.com>
This was referenced Jun 16, 2026
ramackri
added a commit
that referenced
this pull request
Jun 16, 2026
…1021) PR #1018 updated slash-format tag fixture dates to 2099/12/31 but left 2026-06-15 ISO expiry_date values in test_policyengine_tag_hive.json. After 2026-06-15, TestPolicyEngine.testPolicyEngine_hiveForTag fails CI with isAllowed expected true but was false for EXPIRES_ON SELF match. Co-authored-by: ramk <ramk@cloudera.com> Co-authored-by: Cursor <cursoragent@cursor.com>
This file contains hidden or 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
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes RANGER-5647.
This PR contains two CI fixes for
agents-common:testPolicyEngine_hiveForTag_filebasedfails on/after 2026-06-15testPolicyEngine_hdfs_resourcespecfailure under concurrent policy evaluation1. Tag fixture dates
Tag policy tests use
RESTRICTED-FINALwith a deny exception conditioned onctx.isAccessedBefore('activation_date'). Fixture dates were2026/06/15; once the system clock passes that day, CI fails.Fix: change
2026/06/15→2099/12/31in:agents-common/src/test/resources/policyengine/resourceTags.jsonagents-common/src/test/resources/policyengine/ACLResourceTags.jsonagents-common/src/test/resources/policyengine/plugin/resourceTags.jsonagents-common/src/test/resources/policyengine/descendant_tags.jsonagents-common/src/test/resources/policyengine/test_policyengine_tag_hive.json2. Concurrent
{USER}path matching (hdfs_resourcespec)Symptom
TestPolicyEngine.runTestCaseTests()usesparallelStream()on a sharedRangerPolicyEngine. That is intentional — production plugins evaluate concurrently on one engine. The fix belongs in product code, not in serializing tests.Code path (end-to-end)
Policy under test (
test_policyengine_hdfs_resourcespec.json, policy id 2):Step 1 — Matcher built once at policy-engine init
RangerPathResourceMatcher.buildResourceMatchers()turns/home/{USER}/into/home/{USER}/*(recursive + trailing/), then creates oneRecursiveWildcardResourceMatcherper policy value. Because{USER}is present,setDelimiters()setstokenReplacer, sogetNeedsDynamicEval()returns true — the path cannot be pre-expanded at init.This matcher object is stored inside the policy evaluator and reused for every request that may hit policy id 2.
Step 2 — Each request gets its own token context
RangerDefaultRequestProcessor.preProcess()sets per-request context:Each
RangerAccessRequesthas its own contextMap— that part is thread-safe.Step 3 — Evaluation reaches the shared matcher
RangerDefaultPolicyEvaluator.evaluate()calls:which eventually calls
RecursiveWildcardResourceMatcher.isMatch(resourceValue, evalContext)where:resourceValue="/home/user1/tmp/sales.db"(same for both parallel sub-tests)evalContext= that request's context (differenttoken:USERper thread)Step 4 — Token expansion (per-request, always correct)
ResourceMatcher.getExpandedValue(evalContext)replaces{USER}from context:Step 5 — Segment-by-segment matching
isMatch()passes the expanded path and split segments intoRangerPathResourceMatcher.isRecursiveWildCardMatch(), which walks path components:The bug was not in token expansion or in per-request context — it was in where the split policy segments were stored between steps 4 and 5.
Before fix — race on shared instance field
RecursiveWildcardResourceMatcherdeclared split segments as an instance field:Two threads evaluating policy id 2 concurrently both enter
isMatch()on the sameRecursiveWildcardResourceMatcherinstance:Why
expandedValuebeing local wasn't enough:expandedValueis a localStringand stays correct per thread, butisRecursiveWildCardMatch()uses both the fullwildcardPathstring and thewildcardPathElementsarray for the optimized segment walk. When the array is corrupted by another thread, the segment comparison fails even though the string/home/user1/*on the stack is right.Why it is intermittent: This is a data race — it only fails when Thread B writes
wildcardPathElementsbetween Thread A's write and Thread A'sfunction.apply(). Single-threaded runs and low-contention local tests usually pass; CI full-suite load (agents-common, 502 tests, ForkJoin pool) hits it more often.After fix — local
pathElementsperisMatch()callStatic paths (no
{USER}): unchanged —wildcardPathElementsis still computed once in the constructor and reused read-only.Dynamic paths (
{USER}): split result lives on the thread stack for the duration of oneisMatch()call; the instance field is never written during evaluation.No shared mutable state between threads during the match.
Static vs dynamic paths — which failed?
The CI failure was on a dynamic path only. Static paths in the same test file were never affected.
Failed sub-test (dynamic path — policy id 2):
{USER}is a runtime token →getNeedsDynamicEval()returns truecontext["token:USER"]:/home/user1/*/home/user2/*wildcardPathElementson everyisMatch()call → race under parallel evaluationALLOW 'read /home/user1/tmp/sales.db' for user=user1Passing sub-test in same file (static path — policy id 1):
{USER}or other tokens →getNeedsDynamicEval()returns falsewildcardPathElementsread-onlyisMatch()→ no race, unaffected by this bug{USER})hdfs_resourcespec/finance/rest*ricted/(policy id 1)/home/{USER}/(policy id 2)getNeedsDynamicEval()falsetrueisMatch()callparallelStream)pathElementsper callBehaviour impact
{USER}evaluationNo intentional semantic change — only removes incorrect cross-thread corruption of split path segments on dynamic paths.
File:
agents-common/src/main/java/org/apache/ranger/plugin/resourcematcher/RangerPathResourceMatcher.javaTest plan
mvn test -pl agents-common -Dtest=TestPolicyEngine#testPolicyEngine_hiveForTag_filebasedmvn test -pl agents-common -Dtest=TestPolicyEngine#testPolicyEngine_hdfs_resourcespec(30 consecutive runs)mvn test -pl agents-common -Dtest=RangerPathResourceMatcherTestbuild-17green onagents-commonRelated