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

new API: test containers for zero or more elements #1511

Merged
merged 2 commits into from
Aug 25, 2021

Conversation

MVrachev
Copy link
Collaborator

@MVrachev MVrachev commented Jul 28, 2021

Fixes #1485

Description of the changes being introduced by the pull request:

Test metadata (de)serialization with input data containing containers with zero or more elements.

Here is the status for the different use cases:

Root:

  • many keys: added
  • many roles: added

Root role keyids:

MetaFile hashes:

  • many hashes: already tested
  • zero hashes: added. Testing as invalid test case.

Timestamp meta:

  • zero elements: already tested
  • many elements: added

Snapshot meta:

  • zero items: added
  • many items: added

Delegation:

  • many keys: added
  • many keyids: added

Delegation role:

  • many paths: already tested
  • many path_hash_path_prefixes: already tested

Delegation roles:

  • zero roles: added
  • multiple roles: added

Targets targets:

  • zero items: already tested
  • multiple items: added

Additional tests are added for containers with 0 or more elements for some specific cases.
Those tests are needed to cover use cases when syntactically as
standalone objects the metadata classes and their helper classes defined
in tuf/api/metadata.py are valid even if they cannot be verified.

An example where an object is valid, but cannot be verified is
if we have a Role instance with an empty list of "keyids".
This instance is valid and can be created, but cannot be verified
because there is a requirement that the threshold should be above
1, meaning that there should be at least 1 element inside the "keyids"
list to complete successful threshold verification.

The situation is the same for the rest of the tests I am adding to this
commit:

  • Root object without keys
  • Root object without roles
  • DelegationRole object with empty "keyids"
  • DelegationRole object with an empty list of "paths"
  • DelegationRole object with an empty list of "path_hash_prefixes"
    all of these objects can be instantiated, but cannot complete successfully
    threshold verification.

Signed-off-by: Martin Vrachev mvrachev@vmware.com

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

@jku
Copy link
Member

jku commented Aug 5, 2021

According to the spec having an empty container for any of these cases ... is not allowed

is this really true? 😮

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.

some potential test cases

  • timestamp meta with multiple items
  • timestamp meta with no items
  • snapshot meta with multiple items
  • delegation with multiple roles
  • targets targets with multiple items
  • targets roles with multiple items

or do I misunderstand the scope of the PR?

tests/test_metadata_serialization.py Outdated Show resolved Hide resolved
tests/test_metadata_serialization.py Outdated Show resolved Hide resolved
tests/test_metadata_serialization.py Outdated Show resolved Hide resolved
@MVrachev
Copy link
Collaborator Author

MVrachev commented Aug 6, 2021

@jku I had to rebase, but 92dc844 is unchanged.

The new commits are 75b2c21 and 033e069.

@MVrachev
Copy link
Collaborator Author

MVrachev commented Aug 7, 2021

According to the spec having an empty container for any of these cases ... is not allowed

is this really true? 😮

  • Root keys are not allowed to be empty, because it's required that at least one element is inside it - the key used to sign the root metadata file itself.

  • Root roles are not allowed to be empty, because it's required that there should be information for at least one role - the root role.

  • Root role keyids are not allowed to be empty, because it's required that threshold should be at least 1 (see Metadata API: Add simple threshold validation #1450) and as a consequence, there should be at least a threshold number of elements in keyids

  • Delegation keys and Delegation roles
    For those two it's a little harder and probably my statement is wrong.
    This use case is valid:

"delegations": {
     "keys": {}
     "roles": {}

for which by the way we are not testing. I included a test.
The problem comes if Delegation keys are empty, then means there shouldn't be any roles.
So, maybe my assumption is not correct.

But still, where do you think we should test for that?

  • DelegationRole keyids cannot be empty because every role needs at least one key to be verified because the threshold is >= 1.

I am wrong about those two:

  • DelegationRole paths and DelegationRole path_hash_prefixes
    I am already testing for them.

Do you think I should modify my commit message with more info as I did here?

@jku
Copy link
Member

jku commented Aug 9, 2021

I think you may be mixing "is this a syntactically valid metadata" with "can this metadata file be used successfully in every part of the update process".

I mean when you say things like:

Root role keyids are not allowed to be empty, because it's required that threshold should be at least 1

from the perspective of the file format and the containing metadata, keyids and threshold are not related. The spec does not say metadata files can't exist with a role that has less keys than the corresponding threshold. Yes, we happen to know that those keys then can't possibly verify that roles metadata when needed but the metadata that contains this role is still valid.

@jku
Copy link
Member

jku commented Aug 9, 2021

For Root roles specifically there is a spec mention (with a weird reference to "key list" but the intent seems clear: roles dictionary must contain these 4 or 5 items):

A role for each of "root", "snapshot", "timestamp", and "targets" MUST be specified in the key list. The role of "mirror" is OPTIONAL.

This we should test for in Root construction time I guess.

@@ -878,20 +878,24 @@ def __init__(
version: int,
spec_version: str,
expires: datetime,
meta: Dict[str, MetaFile],
Copy link
Member

Choose a reason for hiding this comment

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

can you explain this?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Yes. I noticed we don't do validation on Timestamp.meta.
According to the spec, the value of Timestamp.meta called "METAFILES" is:

METAFILES is the same as described for the snapshot.json file.
In the case of the timestamp.json file, this MUST only include a
description of the snapshot.json file.

That's why in order to include validation for meta no matter if we create objects with Timestamp.from_dict()
or with the constructor like Timestamp() I moved the meta validation and object creation inside __init__.

Copy link
Member

Choose a reason for hiding this comment

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

I don't agree with this change.

  • it's not in line with all other constructors that do take actual objects and not json-like dicts
  • It's going to make the API for creating a new Timestamp from scratch worse (caller feeds in json-like dicts instead of well defined objects).
  • It makes annotations useless: we should get rid of all Any that we can, not add more

I'm fine with you not doing this validation at all right now: we could just wait for the snapshot_meta discussion to reach a conclusion first

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Now with the new discussion about snapshot_meta I agree that we shouldn't hurry and add validation.
Will remove the commit.

@MVrachev MVrachev force-pushed the test-containers branch 2 times, most recently from 66ea522 to 294f0eb Compare August 19, 2021 13:42
@MVrachev
Copy link
Collaborator Author

MVrachev commented Aug 19, 2021

I had to rebase on top of develop.
Additionally I:

  • added a new commit with tests for those valid cases, but which we cannot verify in a trusted set.
  • squashed to similar commits together
  • updated my commits and pr descriptions
  • had another look through the spec to see if we are missing something and it seems everything is okay.

After a discussion with @jku about his words

I think you may be mixing "is this a syntactically valid metadata" with "can this metadata file be used successfully in every part of the update process".
I mean when you say things like:

Root role keyids are not allowed to be empty, because it's required that threshold should be at least 1

from the perspective of the file format and the containing metadata, keyids and threshold are not related. The spec does not say metadata files can't exist with a role that has less keys than the corresponding threshold. Yes, we happen to know that those keys then can't possibly verify that roles metadata when needed but the metadata that contains this role is still valid.

I realized he is right and standalone objects in those cases can exist and are valid, but cannot be verified.
That's why I created a new commit explaining that.

For Root roles specifically there is a spec mention (with a weird reference to "key list" but the intent seems clear: roles dictionary must contain these 4 or 5 items):
A role for each of "root", "snapshot", "timestamp", and "targets" MUST be specified in the key list. The role of "mirror" is OPTIONAL.
This we should test for in Root construction time I guess.

There is a separate issue for that #1516.

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 (apart from the Timestamp constructor api change which I disagree with), thanks.

some of the targets test data are getting quite big ... but personally I still prefer parsing this sort of multiple lines of json in my head: at least every case is understandable without external context -- opinions may vary though

@@ -878,20 +878,24 @@ def __init__(
version: int,
spec_version: str,
expires: datetime,
meta: Dict[str, MetaFile],
Copy link
Member

Choose a reason for hiding this comment

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

I don't agree with this change.

  • it's not in line with all other constructors that do take actual objects and not json-like dicts
  • It's going to make the API for creating a new Timestamp from scratch worse (caller feeds in json-like dicts instead of well defined objects).
  • It makes annotations useless: we should get rid of all Any that we can, not add more

I'm fine with you not doing this validation at all right now: we could just wait for the snapshot_meta discussion to reach a conclusion first

Test metadata (de)serialization with input data containing containers
with zero or more elements.

Here is the status for the different use cases:
Root keys:
- many keys: added
Root roles:
- many roles: added
Root role keyids:
- many keids: already added in theupdateframework#1481
MetaFile hashes:
- many hashes: already tested
- zero hashes: added. Testing as invalid test case.
Timestamp meta:
- zero elements: already tested
- many elements: added
Snapshot meta:
- zero items: added
- many items: added
Delegation keys:
- many keys: added
Delegation role keyids:
- many keyids: added
Delegation role paths:
- many paths: already tested
Delegation role path_hash_prefixes:
- many path_hash_path_prefixes: already tested
Delegation roles:
- zero roles: added
- multiple roles: added
Targets targets:
- zero items: already tested
- multiple items: added

Signed-off-by: Martin Vrachev <mvrachev@vmware.com>
Those tests are needed to cover use cases when syntatcticly as
standalone objects the metadata classes and their helper classes defined
in tuf/api/metadata.py are valid even if they cannot be verified.

An example where an object is valid, but cannot be verified is
if we have a Role instance with an empty list of "keyids".
This instance is valid and can be created, but cannot be verified
because there is a requirement that the threshold should be above
1, meaning that there should be at least 1 element inside the "keyids"
list to complete successful threshold verification.

The situation is the same for the rest of the tests I am adding to this
commit:
- Root object without keys
- Root object without roles
- DelegationRole object with empty "keyids"
- DelegationRole object with an empty list of "paths"
- DelegationRole object with an empty list of "path_hash_prefixes"
all of these objects can be instantiated, but cannot complete
successfully threshold verification.

Signed-off-by: Martin Vrachev <mvrachev@vmware.com>
@MVrachev
Copy link
Collaborator Author

@jku updated the pr by dropping the timestamp meta validation commit and removing multiple metafiles in timestamp test.

MVrachev added a commit to MVrachev/tuf that referenced this pull request Aug 24, 2021
Move the Delegation class serialization tests from "test_api.py"
to test_metadata_serialization.py module focused on serialization
testing.

Additionally, a test for empty keys and roles will be added in my
upcomming pr theupdateframework#1511.

Signed-off-by: Martin Vrachev <mvrachev@vmware.com>
MVrachev added a commit to MVrachev/tuf that referenced this pull request Aug 24, 2021
Move the Delegation class serialization tests from "test_api.py"
to test_metadata_serialization.py module focused on serialization
testing.

Additionally, a test for empty keys and roles will be added in my
upcomming pr theupdateframework#1511.

Signed-off-by: Martin Vrachev <mvrachev@vmware.com>
MVrachev added a commit to MVrachev/tuf that referenced this pull request Aug 24, 2021
Move the Delegation class serialization tests from "test_api.py"
to test_metadata_serialization.py module focused on serialization
testing.

Additionally, a test for empty keys and roles will be added in my
upcomming pr theupdateframework#1511.

Signed-off-by: Martin Vrachev <mvrachev@vmware.com>
MVrachev added a commit to MVrachev/tuf that referenced this pull request Aug 25, 2021
Move the Delegation class serialization tests from "test_api.py"
to test_metadata_serialization.py module focused on serialization
testing.

Additionally, a test for empty keys and roles will be added in my
upcomming pr theupdateframework#1511.

Signed-off-by: Martin Vrachev <mvrachev@vmware.com>
@MVrachev MVrachev requested a review from jku August 25, 2021 11:48
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.

Thanks!

@jku jku merged commit 66aac38 into theupdateframework:develop Aug 25, 2021
@MVrachev MVrachev deleted the test-containers branch August 25, 2021 18:29
MVrachev added a commit to MVrachev/tuf that referenced this pull request Aug 26, 2021
Move the Delegation class serialization tests from "test_api.py"
to test_metadata_serialization.py module focused on serialization
testing.

Additionally, a test for empty keys and roles will be added in my
upcomming pr theupdateframework#1511.

Signed-off-by: Martin Vrachev <mvrachev@vmware.com>
MVrachev added a commit to MVrachev/tuf that referenced this pull request Aug 27, 2021
Move the Delegation class serialization tests from "test_api.py"
to test_metadata_serialization.py module focused on serialization
testing.

Additionally, a test for empty keys and roles will be added in my
upcomming pr theupdateframework#1511.

Signed-off-by: Martin Vrachev <mvrachev@vmware.com>
MVrachev added a commit to MVrachev/tuf that referenced this pull request Sep 1, 2021
Move the Delegation class serialization tests from "test_api.py"
to test_metadata_serialization.py module focused on serialization
testing.

Additionally, a test for empty keys and roles will be added in my
upcomming pr theupdateframework#1511.

Signed-off-by: Martin Vrachev <mvrachev@vmware.com>
MVrachev added a commit to MVrachev/tuf that referenced this pull request Sep 2, 2021
Move the Delegation class serialization tests from "test_api.py"
to test_metadata_serialization.py module focused on serialization
testing.

Additionally, a test for empty keys and roles will be added in my
upcomming pr theupdateframework#1511.

Signed-off-by: Martin Vrachev <mvrachev@vmware.com>
MVrachev added a commit to MVrachev/tuf that referenced this pull request Sep 3, 2021
Move the Delegation class serialization tests from "test_api.py"
to test_metadata_serialization.py module focused on serialization
testing.

Additionally, a test for empty keys and roles will be added in my
upcomming pr theupdateframework#1511.

Signed-off-by: Martin Vrachev <mvrachev@vmware.com>
MVrachev added a commit to MVrachev/tuf that referenced this pull request Sep 14, 2021
Move the Delegation class serialization tests from "test_api.py"
to test_metadata_serialization.py module focused on serialization
testing.

Additionally, a test for empty keys and roles will be added in my
upcomming pr theupdateframework#1511.

Signed-off-by: Martin Vrachev <mvrachev@vmware.com>
MVrachev added a commit to MVrachev/tuf that referenced this pull request Sep 16, 2021
Move the Delegation class serialization tests from "test_api.py"
to test_metadata_serialization.py module focused on serialization
testing.

Additionally, a test for empty keys and roles will be added in my
upcomming pr theupdateframework#1511.

Signed-off-by: Martin Vrachev <mvrachev@vmware.com>
MVrachev added a commit to MVrachev/tuf that referenced this pull request Sep 20, 2021
Move the Delegation class serialization tests from "test_api.py"
to test_metadata_serialization.py module focused on serialization
testing.

Additionally, a test for empty keys and roles will be added in my
upcomming pr theupdateframework#1511.

Signed-off-by: Martin Vrachev <mvrachev@vmware.com>
MVrachev added a commit to MVrachev/tuf that referenced this pull request Sep 20, 2021
Move the Delegation class serialization tests from "test_api.py"
to test_metadata_serialization.py module focused on serialization
testing.

Additionally, a test for empty keys and roles will be added in my
upcomming pr theupdateframework#1511.

Signed-off-by: Martin Vrachev <mvrachev@vmware.com>
MVrachev added a commit to MVrachev/tuf that referenced this pull request Sep 21, 2021
Move the Delegation class serialization tests from "test_api.py"
to test_metadata_serialization.py module focused on serialization
testing.

Additionally, a test for empty keys and roles will be added in my
upcomming pr theupdateframework#1511.

Signed-off-by: Martin Vrachev <mvrachev@vmware.com>
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.

Test [de]serialization of metadata with more than one item in each container and zero items (where valid)
2 participants