Skip to content

Shared Global Enforcer state breaks Async tests #31

@sushilbansal

Description

@sushilbansal

Problem

When using EnforcerServer with a named enforcer (e.g., "reach_enforcer"), all tests share the same global state, making async: true tests fail with race conditions.

What Happened

# This fails with async: true
defmodule Reach.Casbin.AclTest do
  use Reach.CasbinCase, async: true  # ❌ Tests interfere with each other
  
  test "admin has permissions" do
    create_test_policies(test_org_id)  # Adds policies
    # Another test's cleanup deletes these policies mid-test!
    assert Acl.allow?(...) # Returns false unexpectedly
  end
end

Symptoms

  • Policies.list() returns [] even after adding policies
  • add_policy returns {:error, :already_existed} but policies aren't in memory
  • Tests pass individually but fail when run together

Root Cause

# All tests use the same enforcer instance
@enforcer_name "reach_enforcer"
EnforcerServer.add_policy(@enforcer_name, ...)

One test's on_exit cleanup deletes policies while another test is running.

Workaround

# Must disable async
defmodule Reach.Casbin.AclTest do
  use Reach.CasbinCase  # Removed: async: true
end

Proposed Solutions

  1. Support dynamic enforcer names per test
  2. Provide enforcer isolation/sandboxing for tests
  3. Document the async limitation

Metadata

Metadata

Labels

bugSomething isn't working

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions