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

ngclient: Avoid loading targets metadata twice #1593

Merged
merged 1 commit into from
Nov 24, 2021

Conversation

sechkova
Copy link
Contributor

Fixes #1578

Description of the changes being introduced by the pull request:
When traversing the delegations tree looking for targets, avoid re-loading already verified targets metadata.

Please verify and check that the pull request fulfills the following
requirements
:

  • The code follows the Code Style Guidelines
  • Tests have been added for the bug fix or new feature
  • Docs have been added for the bug fix or new feature

@sechkova sechkova changed the title Avoid loading targets metadata twice ngclient: Avoid loading targets metadata twice Sep 27, 2021
@coveralls
Copy link

coveralls commented Sep 27, 2021

Pull Request Test Coverage Report for Build 1470873479

Warning: This coverage report may be inaccurate.

This pull request's base commit is no longer the HEAD commit of its target branch. This means it includes changes from outside the original pull request, including, potentially, unrelated coverage changes.

Details

  • 5 of 5 (100.0%) changed or added relevant lines in 1 file are covered.
  • 6 unchanged lines in 1 file lost coverage.
  • Overall coverage increased (+1.0%) to 98.472%

Files with Coverage Reduction New Missed Lines %
tuf/ngclient/updater.py 6 95.22%
Totals Coverage Status
Change from base Build 1470751886: 1.0%
Covered Lines: 3283
Relevant Lines: 3303

💛 - Coveralls

@jku
Copy link
Member

jku commented Sep 28, 2021

Did you consider if we could use RepositorySimulator to test this (to continue avoiding the actual web server tests)?

A similar mocking approach could work or this could even be a feature in RespositorySimulator if you think there might be more demand for it

EDIT: actually the second loading of course loads the local metadata only so the repository side is irrelevant and your mocking should work as is in a RepositorySimulator test

@sechkova
Copy link
Contributor Author

Did you consider if we could use RepositorySimulator to test this (to continue avoiding the actual web server tests)?

It has to be extended a bit for delegations but why not doing it now.

@jku
Copy link
Member

jku commented Sep 29, 2021

We discussed this already but documenting here: An implementation of delegation support for RepositorySimulator exists but not in develop yet

The options for this PR are:

  • merge as is with expectation that we update the tests when the delegation support is in
  • leave this on back burner until delegation support is in

I think the latter is fine: this is not an urgent change

@sechkova sechkova marked this pull request as draft October 1, 2021 12:37
@jku
Copy link
Member

jku commented Oct 20, 2021

okay, current RepositorySimulator should have basic delegation support now

Comment on lines 376 to 380
with patch.object(
self.repository_updater,
"_load_targets",
wraps=self.repository_updater._load_targets,
) as wrapped_load_targets:
Copy link
Member

@jku jku Oct 22, 2021

Choose a reason for hiding this comment

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

I think this could mock builtins.open to actually test for file loads: the test wouldn't then depend so much on knowledge of updater implementation details.

It's not a major thing I guess: If mocking open() is significantly more complex then let's not do it.

@sechkova sechkova force-pushed the avoid_reloading_targets branch 2 times, most recently from f86b045 to 3f6b439 Compare November 16, 2021 14:39
@sechkova sechkova marked this pull request as ready for review November 16, 2021 14:39
@sechkova
Copy link
Contributor Author

Added the test in test_updater_with_simulator until a better place comes up (#1641).

@sechkova
Copy link
Contributor Author

Now these changes are not compatible with #1680 ...

Copy link
Member

@jku jku left a comment

Choose a reason for hiding this comment

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

I like it, mocking open() feels like the correct thing to check for and is readable.

LGTM to merge. Left two comments for you to decide.

self._load_targets(role_name, parent_role)
# The metadata for 'role_name' must be loaded
# before its targets and delegations can be inspected.
if not self._trusted_set.get(role_name):
Copy link
Member

Choose a reason for hiding this comment

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

more pythonic IMO:

Suggested change
if not self._trusted_set.get(role_name):
if role_name not in self._trusted_set:

Copy link
Contributor Author

Choose a reason for hiding this comment

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

yeah, very pythonic :) it is updated now.

Comment on lines +246 to +249
# Run refresh, top-level roles are loaded
updater = self._run_refresh()
# Clean up calls to open during refresh()
wrapped_open.reset_mock()
Copy link
Member

@jku jku Nov 17, 2021

Choose a reason for hiding this comment

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

you're adding a test for a specific bug fix, that makes sense... but this obviously leads to "shouldn't we check that refresh opens correct files the correct number of times as well?" Maybe a follow up issue if you don't feel like handling here?

Copy link
Contributor Author

@sechkova sechkova Nov 17, 2021

Choose a reason for hiding this comment

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

I was planning to open an issue about testing the loading of metadata. Doing it now ... #1681

@jku
Copy link
Member

jku commented Nov 18, 2021

Now these changes are not compatible with #1680 ...

oof, I just understood what you mean (originally thought you just referred to a plain merge conflict)... this change looks trivial but with that other PR it means you need to handle the else-case in _preorder_depth_first_walk() as well making a it a bit ugly. Let's make sure the approach is reasonable WRT 1680 before merging this.

I think that _preorder_depth_first_walk() should not have to handle these different cases (it's complex enough):
So should _load_targets() handle the "already loaded" case and return the cached one if it is already loaded? I think that makes sense: the top-level metadata is "immutable" so if we have loaded a specific targets, it is the correct one. It'll mean _load_targets() operates a little differently than other _load_*() but I think that's natural: loading targets is a special case as we do it implicitly during get_targetinfo().

@jku jku self-requested a review November 23, 2021 10:11
Copy link
Member

@jku jku left a comment

Choose a reason for hiding this comment

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

marking "request changes" for the merge conflict plus previous comment

When traversing the delegations tree looking for targets,
avoid re-loading already verified targets metadata.

Signed-off-by: Teodora Sechkova <tsechkova@vmware.com>
@sechkova sechkova force-pushed the avoid_reloading_targets branch from 1792f1e to 4db4737 Compare November 23, 2021 10:24
@sechkova
Copy link
Contributor Author

It should be ready now.

Copy link
Member

@jku jku left a comment

Choose a reason for hiding this comment

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

LGTM, thanks

@jku jku merged commit a24c4e9 into theupdateframework:develop Nov 24, 2021
@lukpueh lukpueh mentioned this pull request Dec 13, 2021
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.

ngclient: top-level targets is unnecessarily updated twice
3 participants