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.