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

Assignees

Labels

bugSomething isn't working

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions