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

cache fixture results per sequence, clearing the cache at the end #14

Merged
merged 1 commit into from
Sep 20, 2019

Conversation

acoover
Copy link
Contributor

@acoover acoover commented Sep 16, 2019

No description provided.

@acoover acoover force-pushed the cache-fixtures-per-request-sequence branch from 781594c to d36b002 Compare September 16, 2019 23:34
@acoover
Copy link
Contributor Author

acoover commented Sep 16, 2019

fixes #13

@acoover
Copy link
Contributor Author

acoover commented Sep 16, 2019

This change removes the ability to override dependency injection for fixtures by providing explicit values for parameters. @domanchi can you provide some clarity on the motivation behind that functionality?

@domanchi
Copy link
Contributor

@acoover: when I envisioned this tool, I imagined fixtures being flexible enough to exist with other helper functions. This means that it supports manual fixture invocations (e.g. if you wanted to specify a precise value, or use it just as another factory to create data).

I don't think our internal use of this tool requires this manual invocation though.

Copy link
Contributor

@domanchi domanchi left a comment

Choose a reason for hiding this comment

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

This looks functionality sane to me; I'm just wondering more of the design aspects of these decisions.

fuzz_lightyear/datastore.py Show resolved Hide resolved
@@ -12,6 +13,7 @@ def run_sequence(
for request in sequence:
response = request.send()
responses.add_response(response)
clear_cache()
Copy link
Contributor

Choose a reason for hiding this comment

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

Hmm.

I wonder whether this should be a sequence level cache, rather than a request level cache. My thinking around this is that fixtures exist to complement the "traditional" CRUD application. What is now created in a fixture would have been created with a separate request, if we were testing a full CRUD application. This means that technically, it would have gone in the sequence level cache that was enabled here: #10

Granted, since these fixtures are executed on "request setup" time, rather than caching the responses, this may be practically difficult to do.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

One bit which is off about placing the call to clear the cache here is that the cache is cleared before we make the request to the server to check for vulnerabilities, which means we don't use the same resources for the victim and attacker accounts. This shouldn't matter since the execution path to setup the fixtures is the same, but it seems like we should clear the cache after we analyze_requests

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Looking at #10, I don't think we can leverage a per-sequence cache in the same way as used in that PR. My reasoning is that in addition to a FuzzingRequest reading cached values when generating parameters for the request in fuzzer.py, we also need to access the cache within the fixtures themselves. If we didn't allow for dependencies between fixtures (fixture A takes as input the values from fixture B) we could generate all fixtures upfront before running a request sequence then toss the values in a local dict used to generate params as in #10 - the benefit here would be to rely on garbage collection to invalidate the cache as opposed to the gross explicit clear_cache in this PR.

Copy link
Contributor

@domanchi domanchi Sep 19, 2019

Choose a reason for hiding this comment

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

Yeah, it's tricky, and I don't know a better way forward right now.

Let's ship this, and punt on figuring out how to better structure it. After all, we don't need to support manual invocations anymore.

EDIT: Creating #19

@acoover
Copy link
Contributor Author

acoover commented Sep 17, 2019

@acoover: when I envisioned this tool, I imagined fixtures being flexible enough to exist with other helper functions. This means that it supports manual fixture invocations (e.g. if you wanted to specify a precise value, or use it just as another factory to create data).

I don't think our internal use of this tool requires this manual invocation though.

The fixture dependency-injection is magical enough that the additionally complexity required to support manual invocation doesn't seem worth the effort. My feeling is that most fixtures will alias other functions which perform the bulk of the work to setup the fixture. That is to say, most fixtures look like this

@fuzz_lightyear.register_factory('foo')
def foo():
   return foo_factory(bar=1)

Allowing foo to be invoked directly is of little value over just invoking the foo_factory method.

As a datapoint, pytest explicitly disallows fixtures to be invoked directly.

@acoover acoover force-pushed the cache-fixtures-per-request-sequence branch from d36b002 to 74e03af Compare September 18, 2019 21:18
@acoover acoover merged commit 8640b6d into master Sep 20, 2019
@acoover acoover deleted the cache-fixtures-per-request-sequence branch September 20, 2019 18:02
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.

2 participants