Skip to content

[Session][Test] MockFileSessionStorage is not persistent #22616

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
mtricht opened this issue May 2, 2017 · 10 comments
Closed

[Session][Test] MockFileSessionStorage is not persistent #22616

mtricht opened this issue May 2, 2017 · 10 comments

Comments

@mtricht
Copy link
Contributor

mtricht commented May 2, 2017

Q A
Bug report? yes
Feature request? no
BC Break report? no
RFC? no
Symfony version 2.1+

The following controller:

class DefaultController extends Controller
{
    /**
     * @Route("/", name="homepage")
     */
    public function indexAction()
    {
        $this->get('session')->set('test', 'test');
        $this->get('session')->save();
        return new Response('All good');
    }

    /**
     * @Route("/test", name="test")
     */
    public function testAction()
    {
        if ($this->get('session')->get('test') !== 'test') {
            return new Response('Missing test');
        }
        return new Response('All good');
    }
}

Used in a test:

class DefaultControllerTest extends WebTestCase
{
    public function testIndex()
    {
        $client = static::createClient();
        $client->request('GET', '/');
        $client->request('GET', '/test');
        $this->assertEquals('All good', $client->getResponse()->getContent());
    }
}

Expected: Test succeeds. Session is persisted as documented here.
Actual: Test fails. The session is not persisted through the two requests.

The following line causes this:

Removing this line fixes the problem.

Another 'solution' is adding the following line to the first action:

@@ -16,6 +16,7 @@ class DefaultController extends Controller
     {
         $this->get('session')->set('test', 'test');
         $this->get('session')->save();
+        $this->get('session')->get('test');
         return new Response('All good');
     }

Adding this get after the save sets the started variable back to true meaning the session is persisted, which is rather odd and made debugging this issue very frustrating.

@dmaicher
Copy link
Contributor

dmaicher commented May 3, 2017

I cannot reproduce this problem on Symfony 2.8 😋 Can you fork the symfony standard edition and apply the minimal changes to reproduce this issue?

@mtricht
Copy link
Contributor Author

mtricht commented May 3, 2017

@dmaicher
Copy link
Contributor

dmaicher commented May 3, 2017

ok thanks 👍 I think the difference to my tests was that I tested it behind a firewall 😋

Seems weird indeed the behaviour.

This works:

    /**
     * @Route("/", name="homepage")
     */
    public function indexAction()
    {
        $this->get('session')->set('test', 'test');
        return new Response('All good');
    }

And this also:

    /**
     * @Route("/", name="homepage")
     */
    public function indexAction()
    {
        $this->get('session')->set('test', 'test');
        $this->get('session')->save();
        $this->get('session')->start();
        return new Response('All good');
    }

@mtricht
Copy link
Contributor Author

mtricht commented May 3, 2017

@dmaicher weird that the first one works, isn't save always called at the end? I guess I could just remove the save call for now

@HeahDude
Copy link
Contributor

@jakzal
Copy link
Contributor

jakzal commented Oct 25, 2017

You shouldn't be calling save() yourself as the framework already takes care of it. If save() is called twice, the second time it will throw an exception (which is the reason why you're getting different output in your test).

@jakzal jakzal closed this as completed Oct 25, 2017
@Tobion
Copy link
Contributor

Tobion commented Oct 27, 2017

This looks like a bug. The NativeSessionStorage does not throw an exception when saving twice. A session_write_close on an inactive session is just ignored and does nothing. The mocked session must have the same behavior otherwise the two implementations are inconsistent.

@Tobion Tobion reopened this Oct 27, 2017
@jakzal
Copy link
Contributor

jakzal commented Oct 27, 2017

Well, the logic was deliberately introduced in #6362

@dmaicher
Copy link
Contributor

dmaicher commented Apr 6, 2019

Investigating this again as part of the EUFOSSA hackathon.

I cannot reproduce this anymore on Symfony 3.4+.

Also with recent changes in Session we will not call save on the storage if the session is not started (anymore):

https://github.com/symfony/symfony/blob/4.2/src/Symfony/Component/HttpFoundation/Session/Session.php#L196

So I think we can close this @jakzal @Tobion ?

@Tobion
Copy link
Contributor

Tobion commented Apr 6, 2019

I still think it should not throw an exception in

throw new \RuntimeException('Trying to save a session that was not started yet or was already closed');
but just return;. But since the original issue is not reproducible and save is not called anymore when the session has not been started, there is no point in changing the mock storage and potentially add a bc break.

@Tobion Tobion closed this as completed Apr 6, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

8 participants