Skip to content
This repository has been archived by the owner on Oct 1, 2024. It is now read-only.

[graphql-fixtures] Remove unused call to faker.seed() #2161

Merged
merged 2 commits into from
Feb 14, 2022

Conversation

notjosh
Copy link
Contributor

@notjosh notjosh commented Feb 7, 2022

Description

Hi! We're seeing lots of calls to faker.seed() when using this library, and it turns out (predictably) that's because we call it a lot in some situations! 😱

The problem here, is that init_genrand() is quite an expensive operation (source). It was showing to be using 2-4% of time spent in test suites!

As a starting point, this PR cuts the calls to init_genrand() to around 50%, without any noticeable negative side effect.

Discussion: For future, we could replace the Mersenne Twister implementation for less cryptographically secure but cheaper + good enough for our needs. For example, an implementation of an LCG with an essentially free seeding function. I have a patch for this that I used in profiling to swap out the implementation in Faker.js, but a) it's obviously fragile to patch a core function like that, and b) it will break existing tests relying on specific seeded output.

(This ventures deep into "should we even still use Faker?" territory though, but it's food for thought)

Type of change

  • graphql-fixtures Patch: Bug (non-breaking change which fixes an issue)

Checklist

  • I have added a changelog entry, prefixed by the type of change noted above (Documentation fix and Test update does not need a changelog as we do not publish new version)

@notjosh notjosh requested a review from a team as a code owner February 7, 2022 13:07
@notjosh notjosh requested a review from atesgoral February 7, 2022 13:07
@atesgoral
Copy link
Contributor

should we even still use Faker?

My first instinct is, no.

I don't see why we want unpredictable/nondeterministic test fixtures.

@atesgoral
Copy link
Contributor

We're seeing

Which repo was it?

I wonder what happens to Shopify/web tests with this patch.

@notjosh
Copy link
Contributor Author

notjosh commented Feb 7, 2022

Which repo was it?

Shopify/arrive-client. Tests remain green for that suite with the patch, but I'd also be curious if there are any side effects on other repos.

@notjosh
Copy link
Contributor Author

notjosh commented Feb 7, 2022

I don't see why we want unpredictable/nondeterministic test fixtures.

That's what the calls to faker.seed() prevent - the fixtures are deterministic based on the key/property (afaict). It gives repeatable & readable data, which is nice, so I can see the benefit. But it's not built for speed! (see also #2152)

@atesgoral
Copy link
Contributor

atesgoral commented Feb 7, 2022

What I implicitly (or in my own head) meant was: Even with seeding, tests might be prone to breaking the moment there's a slight tweak to how the PRNG or data synthesis works. I would hard-code the input and outputs in tests.

Like in this very particular case, where there's a performance win opportunity, but we can't be sure about the side effects 😓

We could try yalc'ing this in Shopify/web or do a beta release, maybe.

@notjosh
Copy link
Contributor Author

notjosh commented Feb 7, 2022

What I implicitly (or in my own head) meant was: Even with seeding, tests might be prone to breaking the moment there's a slight tweak to how the PRNG or data synthesis works. I would hard-code the input and outputs in tests.

Ohhh right, yes. If we change the PRNG, tests will (and do!) definitely break, so I haven't touched that. This change doesn't change any of the output used for fixtures at all, and gets re-seeded with a deterministic seed every time it's called.

I'd imagine the only way this could break tests would be extremely specific, i.e. tests that a) mock Math.random() for some reason (maybe to imitate seeding the value), and b) rely specifically on the instance of Faker set up with this module (which would be left with a different seed after execution).

And for completeness: other libs pulling in Faker wouldn't be impacted, as they get (re-)seeded separately in their own instance.

@BPScott
Copy link
Member

BPScott commented Feb 7, 2022

@ryanwilsonperkin you've been knee deep in faker seeding funkyness. Got any thoughts?

@ryanwilsonperkin
Copy link
Member

Copying a couple comments over from slack:

This might break the odd thing in web, but probably not too to much because we already came across and fixed a few of the places where we were asserting on specific values that we expected to come back from the seed.

We’d still need some determinism within a given test though, I’m not sure we can remove all the calls to seed. Simplest example to demonstrate would be if you had multiple useQuery calls within the same component and you expected them to each resolve (potentially nested) a Widget type. If you don’t provide an id value in your partial fill argument, then you’ll get a deterministic id value for the Widget in each of the query responses. If we remove the seeding, then this would result in each one getting a different id, which then breaks Apollo (it returns undefined)

@notjosh
Copy link
Contributor Author

notjosh commented Feb 8, 2022

^Totally agreed, but this is only removing one of the calls to seed which uses Math.random() as the seed (so not deterministic anyway), so the withRandom method will still be deterministic in the same way it was before

Copy link
Member

@ryanwilsonperkin ryanwilsonperkin left a comment

Choose a reason for hiding this comment

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

Ran a subset of web tests using this branch through yalc and seems to be working fine, couldn't run the full test suite locally but this gives us some confidence that this won't break any paths we were worried about. LGTM 👍🏻

Please update the changelog with a note on the changed functionality, and we can release a new patch version to do a full test on web.

@notjosh notjosh force-pushed the chore/no-extra-seed branch 2 times, most recently from 88bcc6a to a2b3e3b Compare February 10, 2022 10:26
@BPScott
Copy link
Member

BPScott commented Feb 12, 2022

CI failures due to shifting node versions fixed in #2171. Rebase and CI should be happy again

@notjosh notjosh force-pushed the chore/no-extra-seed branch from a2b3e3b to 948bf62 Compare February 14, 2022 09:56
@notjosh notjosh merged commit d90818d into main Feb 14, 2022
@notjosh notjosh deleted the chore/no-extra-seed branch February 14, 2022 10:10
@shopify-shipit shopify-shipit bot temporarily deployed to production February 14, 2022 16:32 Inactive
@shopify-shipit shopify-shipit bot temporarily deployed to fix-deprecated-exports-pattern February 22, 2022 19:45 Inactive
@shopify-shipit shopify-shipit bot temporarily deployed to a11y_tests_class_improvement February 24, 2022 21:31 Inactive
@shopify-shipit shopify-shipit bot temporarily deployed to mf-beta March 7, 2022 09:18 Inactive
@shopify-shipit shopify-shipit bot temporarily deployed to production-gem June 21, 2022 14:45 Inactive
@Flufd Flufd mentioned this pull request Dec 7, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants