JosephSilber / bouncer

Laravel Eloquent roles and abilities.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Memory exhausted when using Policies in phpunit

asivaneswaran opened this issue · comments

Fatal error: Allowed memory size of 536870912 bytes exhausted (tried to allocate 1163264 bytes) in /home/vagrant/code/kin-ball-v4/vendor/silber/bouncer/src/CachedClipboard.php on line 130

I keep getting this error when I try to test my permissions on phpunit.

I figured out it where it happens:

public function index(User $user)
    {
        return $user->can('index', Article::class);
    }

If I remove that, it works fine. As soon as I do $user->can() I get that error....

How many roles/abilities does that user have?

He is assigned one role that has 5/6 models that he owns.

Interesting. I (and many others) have tried it with way more roles and abilities.

Could you maybe recreate this in a small reproduction?

Closing this for now. Feel free to reopen with a reproduction 👍

Hi, sorry for the delay. Here is my seeder:

    {
        /**
         * Run the database seeds.
         *
         * @return void
         */
        public function run()
        {
            /*
            * Admin role and permissions
            */
            Bouncer::role()->firstOrCreate(
                [
                    'name'  => 'admin',
                    'title' => 'Administrateur',
                ]
            );
            Bouncer::allow('admin')->everything();

            /*
            * Responsible role and permissions
            */
            Bouncer::role()->firstOrCreate(
                [
                    'name'  => 'responsible',
                    'title' => 'Responsable d\'association',
                ]
            );
            Bouncer::allow('responsible')->to('index', Account::class);
            Bouncer::allow('responsible')->to('index', CcrEvent::class);
            Bouncer::allow('responsible')->to('index', CcrTeam::class);
            Bouncer::allow('responsible')->to('index', Member::class);
            Bouncer::allow('responsible')->to('index', Team::class);

            /*
            * Coach role and permissions
            */
            Bouncer::role()->firstOrCreate(
                [
                    'name'  => 'coach',
                    'title' => 'Entraîneur en chef',
                ]
            );
            Bouncer::allow('coach')->to('index', Member::class);
            Bouncer::allow('coach')->to('index', Team::class);

            /*
            * Referee role
            */
            Bouncer::role()->firstOrCreate(
                [
                    'name'  => 'referee',
                    'title' => 'Arbitre',
                ]
            );
            Bouncer::allow('referee')->to('referee', CcrEvent::class);

            /*
            * Extra abilities
            */
            Bouncer::ability()->firstOrCreate(
                [
                    'name'  => 'can-access-panel',
                    'title' => 'Can access panel',
                ]
            );

            $users = User::where('is_superuser', 1)->get();

            foreach ($users as $user) {
                $user->allow('can-access-panel');
            }
        }

In my policy, I have this:
return $user->can('index', Article::class);

Thanks,

$users = User::where('is_superuser', 1)->get();

    foreach ($users as $user) {
        $user->allow('can-access-panel');
    }

How many users are there?

There is around 100 users in the real database. But in testing environment, maybe 1 or 2 max.

Feel free to reopen with a reproduction

We need a real reproduction, not just a code dump.


I created a reproduction of your code here:

https://github.com/JosephSilber/bouncer-demo-issue-524

As you can see, the tests pass.


Please open a PR to that repository with a failing test.

Hey,
So I think I figured it out. I think I didn't give you all the infos.

I don't create the users before the test. I create it in the test:

        $user = $user ?: factory(Account::class)->create()->user;

        $user->assign('admin');
        $user->allow(config('permissions.can-access-cp'));

        $response = $this->actingAs($user)->get(route('admin.article.index'));

        $response->assertOk();
        $response->assertViewIs('admin.article.index');
        $response->assertViewHas('page_title');
        $response->assertViewHas('html');
        $response->assertViewHas('create_route');

Could this lead to the error? I am so confused, why I am getting this on my repo but not on the test repo.

Could this lead to the error?

I don't think so.

I am so confused, why I am getting this on my repo but not on the test repo.

Try cloning that repo and playing around with it (I left you instructions in the readme). Get it to break, and submit it as a PR there, so I can take a look.

Wait, is this (from your first message) a controller method, or a policy method?

public function index(User $user)
{
    return $user->can('index', Article::class);
}

@JosephSilber I ran into the same issue. here is how to replicate it on https://github.com/JosephSilber/bouncer-demo-issue-524 repository

Test without using seeders:

public function testBasicTest()
  {
      $user = factory('App\User')->create();
      Bouncer::allow($user)->to('viewAny', Article::class);

      $this->assertTrue(User::first()->can('viewAny', Article::class));
  }

ArticlePolicy viewAny function:

 public function viewAny(User $user)
    {
        return $user->can('viewAny', Article::class);
    }

and also running Bouncer after policies

Bouncer::runAfterPolicies(true);

I guess the issue is when the laravel policy function name viewAny and Bouncer permission name viewAny are the same is will start an infinte loop because each time it will go back to policy function without an end.

I figured that's what it was. That's why I was asking:

is this (from your first message) a controller method, or a policy method?

@KhawlahElshah that policy shouldn't exist. Laravel's gate checks directly with Bouncer.