Skip to content
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

Limit browser implementation to hold a single browserContext #929

Merged
merged 6 commits into from
Jun 14, 2023

Conversation

ankur22
Copy link
Collaborator

@ankur22 ankur22 commented Jun 12, 2023

Description of changes

This PR is one of a few that will be used to help enforce a single browserContext per browser per iteration. The reason for this change can be found in this directly linked issue and this overarching issue. The summary is that we want to be able to predict the resource requirements of how many browsers a test run may need, and the first step towards this goal is to be able to predict the number of browserContexts a test run will need.

At the moment (in this PR) we enforce a single browserContext per iteration, which also means we allow the user to close() the existing browserContext and create a new one with NewContext. Any objects still associated to the previous browserContext will be closed and the user will not be able to work with those objects. In a later PR we will change this behaviour so once a browserContext is setup, no other browserContext can be created, even if the existing one is closed.

export default async function() {
  const context = browser.newContext();
  const page = context.newPage();

  // const context2 = context.newContext(); // If uncommented, it would cause an error.

  context.close(); // page cannot be used after this call

  // await page.goto("https://test.k6.io"); // If uncommented, it would cause an error.

  const context2 = context.newContext();

  // await page.goto("https://test.k6.io"); // If uncommented, it would cause an error.

  const page2 = context2.newPage();
  await page2.goto("https://test.k6.io");
  ...

Checklist

Tasks

To enable us to predicate and have a better idea of how much resource
a test run will require, we want to restrict the number of browser-
Contexts per vu to be one. This will ensure that a single test
scenario which requires 1 vu and 50 iterations could work with a single
browser and a new browserContext per iteration.

Users will need to close the existing browserContext before creating
a new one. We feel that this restriction along with scenarios should
still work for majority of our users.
This check when NewContext is called on browser will ensure that we
only ever have one browserContext at any one point. If a user wishes to
create a new browserContext, they will need to close the existing one
first.
@ankur22 ankur22 requested review from inancgumus and ka3de June 12, 2023 15:29
@ankur22 ankur22 changed the title Enforce 1 browser context Limit browser implementation to hold a single browserContext Jun 12, 2023
browserCtx := b.context
b.contextMu.RUnlock()
if browserCtx != nil {
return nil, errors.New("close the existing browser context before creating a new one")
Copy link
Collaborator Author

@ankur22 ankur22 Jun 12, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let me know how you feel about this. I could change this in this PR (was going to do it in a later PR) so that we don't allow more than one browserContext to be setup as we originally wanted.

@@ -50,8 +50,7 @@ type Browser struct {
// A *Connection is saved to this field, see: connect().
conn connection

contextsMu sync.RWMutex
Copy link
Collaborator Author

@ankur22 ankur22 Jun 12, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've done a stress test on this mutex removal change, and it all seems to work still.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

😱🤞🙃

Since all interactions with the browserContext in the browser are
synchronous and no async actions occur on browserContext that could
cause it to change between two or more goroutines - browser.context is
set when browser.NewContext is called, and unset when browser.close is
called.
@ankur22 ankur22 force-pushed the refactor/925-enfore-1-browserContext branch from b743c16 to 177cf7e Compare June 12, 2023 15:56
@ankur22
Copy link
Collaborator Author

ankur22 commented Jun 12, 2023

I haven't added a docs issue to this PR, as there are still two more PRs to create (as directed by the original issue). Once the final PR is done I will work on the docs.

@ankur22 ankur22 marked this pull request as draft June 12, 2023 16:06
Copy link
Collaborator

@ka3de ka3de left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall LGTM 👍 Just a couple of small comments.

common/browser.go Outdated Show resolved Hide resolved
common/browser.go Outdated Show resolved Hide resolved
Copy link
Member

@inancgumus inancgumus left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good! Minor skippable suggestions suggestions.

common/browser.go Outdated Show resolved Hide resolved
common/browser.go Outdated Show resolved Hide resolved
tests/keyboard_test.go Show resolved Hide resolved
ankur22 and others added 3 commits June 13, 2023 15:32
When multiple k6 instances connect to a single chrome instance, the
page that is created by each k6 instance is also recreated in all
k6 instances that are connected to the same browser. We don't do the
same for browserContexts. When a page is recreated in one k6 instance
for another k6 instance, the browserContext will not be there, so
instead for now we should still work with the defaultContext.
Co-authored-by: ka3de <daniel.jimenez@grafana.com>
Co-authored-by: İnanç Gümüş <inanc.gumus@grafana.com>
Copy link
Collaborator

@ka3de ka3de left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM.

@ankur22 ankur22 requested a review from inancgumus June 13, 2023 15:26
Copy link
Member

@inancgumus inancgumus left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM 👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants