cypress icon indicating copy to clipboard operation
cypress copied to clipboard

'Out of Memory' error when there are heavy assertion logs printed in Cypress Test Runner

Open navdeepdevrepublic opened this issue 3 years ago • 7 comments

Current behavior

Cypress Test runner crashes with error 'Out of Memory'. OutOfMemoryError

Desired behavior

In this situation, Cypress should contract itself with 'Read more' or 'Read less' links in the assertion logs or if the cypress log is heavy it should dump the logs into local storage.

Test code to reproduce

The below line of code prints the complete JSON response from the API in the logs while asserting and hence the out of memory error occurs. expect(JSON.stringify(resp1.body)).to.include('DynamicColumns')

Below is the complete code to reproduce:

File example.cy.js

cy.request('https://devxxx.office.nl/Grid/ApplyFilter').as('req1').then((resp1)=>{

                        //expect(JSON.stringify(resp1.body)).to.include('DynamicColumns')
                
                        cy.get('@req1').should('have.property', 'status', 200)
                    })

Cypress Version

10.3.1

Other

No response

navdeepdevrepublic avatar Aug 05 '22 05:08 navdeepdevrepublic

Hi @navdeepdevrepublic. Thank you for opening an issue. This usually means that the browser has run out of memory. Have you tried giving the chrome process more memory? Also, is it possible you could provide a reproduction repo? I cannot seem to access that url you have provided.

AtofStryker avatar Aug 05 '22 19:08 AtofStryker

Hi @AtofStryker I was looking more about the same issue and I found out this issue close to my problem https://github.com/cypress-io/cypress/issues/1906, At the end of this ticket #1906 , you can see, there are a few more people who are still facing this problem in cypress version 10.3.1, in my case, there are heavy cypress logs generated and I can see the memory taken by this test is close to 4 GB which is itself a huge, moreover talking about the URL which you are not able to access in my above sample code is because of that URL is VPN restricted.

Memory taken image

In my above code if I am commenting this line //expect(JSON.stringify(resp1.body)).to.include('DynamicColumns') then my tests are running fine.

navdeepdevrepublic avatar Aug 07 '22 13:08 navdeepdevrepublic

4GB is definitely quite a bit of memory. For diagnostics, have you tried increasing the memory of the process or is your machine maxed out on memory usage? Since the URL is VPN restricted, are you able to provide a reproduction that we can run to illustrate the problem?

My guess is that the request is quite large that you are asserting on, as are some of the others. Have you tried decreasing the numTestsKeptInMemory to lower than the default (which is 50)? This should free up some memory in the browser, but will reduce the amount of snapshots in memory.

AtofStryker avatar Aug 08 '22 17:08 AtofStryker

Same problem since cypress v8.3 I think this requires urgent look because its getting worse when we have to use numTestsKeptInMemory:0 every time

My machine is having high configuration (16 GB RAM, SSD and i7 10th generation processor).

I am looking of the solution other than numTestskeptInMemory.

Prashant-Kan avatar Aug 08 '22 19:08 Prashant-Kan

@AtofStryker I am facing crash only when the JSON response gets printed (multiple times in the loop) in the test runner logs (while putting assertion), indeed the JSON response is heavy on which I am asserting.

Please guide me, how I can increase the memory of the process? (as you have written above)

I am unable to provide you with the URL to reproduce this issue.

The workaround numTestsKeptInMemory:0 is not working for me because I have only one test which has a loop for printing the multiple JSON responses.

@AtofStryker Do you know any way of asserting on JSON response without printing in the console or the JSON response could show in a compressed form in the logs?

navdeepdevrepublic avatar Aug 09 '22 06:08 navdeepdevrepublic

I am also having the same issue. My test runs for about 8 minutes and then crashes with Aw, Snap! Error code: Out of Memory. I use numTestsKeptInMemory:0 and the memory footprint does not exceed 2,600,000K but it still crashes every time. The strange thing is that one week ago my test was running fine for 23 mins and this week it cannot run for more than 8 mins

Georgi0304 avatar Aug 09 '22 10:08 Georgi0304

possibly related to #23193

AtofStryker avatar Aug 09 '22 18:08 AtofStryker

@navdeepdevrepublic sorry for the late reply. It has been a very busy few days. I don't think there is a direct way to provide the process with more memory, but out of curiosity, does the issue also happen when you are in run mode and how does it work with other browsers (for instance, electron)?

AtofStryker avatar Aug 15 '22 19:08 AtofStryker

@AtofStryker Yes, I have tried in run mode also and with Chrome and Electron browser as well.

navdeepdevrepublic avatar Aug 15 '22 20:08 navdeepdevrepublic

Users are still facing their issues in this ticket #1906

navdeepdevrepublic avatar Aug 22 '22 06:08 navdeepdevrepublic

Hi @navdeepdevrepublic, can you provide a simple reproduction we can use to dig into this further? This will help us isolate where the issue is happening and help you faster 🙏 . You can use cypress-test-tiny to set it up

I tried to set up a repo with the test code provided but the URL does not work as expected. Manually navigating to the website and going to the network tab shows that it fails to load the response data: Screen Shot 2022-08-21 at 11 59 40 PM

rachelruderman avatar Aug 22 '22 06:08 rachelruderman

@rachelruderman The above URL cannot be accessed at your end because it is VPN restricted URL. I am providing you an improvised version of code below. The below code picks up one DOM element and iterate its child elements in a loop and clicks on each element (which is itself a menu item) and on each click, the API is returning one JSON (quite long) which gets printed in the cy.log and then the error occurs.

This sample code to reproduce

  it('User should be able to verify the Global Master Data', () => {
    
    cy.visit(Cypress.env('fms_base_url')+'Home/Index')
    cy.wait(5000)

    //Check the length of the children of 'Global Master Data'
    new homePage().getMenuItem_GlobalMasterData().contains('Global Master Data').should('have.text','Global Master 
    Data').click().parent().find('ul').children().then((elements)=>{
      cy.log('length of elements -->  '+elements.length)
    })

    cy.wait(5000)

    // Click on each children of Global Master Data and verify if the data is being retrieved or not
    new homePage().getMenuItem_GlobalMasterData().contains('Global Master Data').should('have.text','Global Master 
    Data').parent().find('ul').children().each(($el, index, $list)=>{
      
        cy.wait(4000)
        
        let text11 = ''
        cy.wrap($el).invoke('text').then((txt)=>{
          text11 = txt
        }) 

        cy.wrap($el).click().wait(5000).invoke('attr','data-groupitem').then((valOfDataGroupItem)=>{

          cy.request(Cypress.env('fms_base_url')+'Grid/BindGridByID?ItemID='+valOfDataGroupItem+'&name='+text11.replace(' 
          ','%20')+'&catalog=Global%20Master%20Data&IsHLP=false&IsTabStrip=false').as('req').then((resp)=>{
          
          expect(JSON.stringify(resp.body)).to.include('DynamicColumns')
            
          cy.get('@req').should('have.property', 'status', 200)
          })
          
        })
      
    })

  })

@rachelruderman Hope the above code helps you to reproduce the issue, you just have to print the complete response returned by any API for multiple times in a loop in a spec file to reproduce this issue.

navdeepdevrepublic avatar Aug 22 '22 07:08 navdeepdevrepublic

Hi @navdeepdevrepublic, sorry I missed that part about the VPN! I know this whole process can be frustrating and I thank for your patience. I'll put together a sample reproduction today. Would just like to clarify one part:

you just have to print the complete response returned by any API for multiple times in a loop

How many times is the loop running? The exact number would be helpful so I can ensure my reproduction does the same

rachelruderman avatar Aug 22 '22 15:08 rachelruderman

@rachelruderman Thank you for your response. The loop has to print around 40+ different API responses in the test runner logs and the loop runs only once in one spec file.

navdeepdevrepublic avatar Aug 22 '22 16:08 navdeepdevrepublic

Simple reproduction case has been created here

@navdeepdevrepublic I was able to reproduce the issue you described above. I'm certain there are memory optimizations that could be made in the Cypress app to at least delay the failure, but there's also the potential that simple refactors in your test could also avoid the issue. I would like to have a better understanding on why you're doing the JSON.stringify method you've described - anytime we execute a string matcher the entirety of the string is (intentionally) output to the log which, if the string is very large, will have an impact on memory consumption. Is there potentially a more efficient set of assertions you could do that wouldn't involve matching on the entire stringified response?

I imagine you have some idea where in your JSON response the value you're looking for should exist - could you not pluck out the object keys, or a subset of the response and just match against that? This would not only improve your memory situation but would probably also speed up your tests (stringify and large string matches aren't cheap operations).

For example, if you're just validating that a given key exists in the response you could do something like this:

const responseKeys = Object.keys(response.body)
expect(responseKeys).to.include('DynamicColumns')

This would result in only outputting the keys (or some other subset) of the JSON response rather than the entire thing which would avoid the runaway memory consumption

mike-plummer avatar Aug 24 '22 20:08 mike-plummer

@mike-plummer Thank you for the response, I have modified my tests and it is working fine as per the proposed solution, however this 'Out of Memory' issue has been reported by many other users as well, there could be the other user scenarios, in my case, it is manageable however in other cases, it might not be.

navdeepdevrepublic avatar Aug 25 '22 06:08 navdeepdevrepublic

@navdeepdevrepublic at this point I am going to close this specific issue as I think we have come to a place with a solution that improves the test that was causing this issue. If you have other out of memory issues please do open a new ticket and we can investigate. Or feel free to search our backlog and add your voice to any of those open issues.

nagash77 avatar Aug 25 '22 18:08 nagash77