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

Add puppet tests for syncing and publishing with puppet_distributor #48

Closed
wants to merge 1 commit into from

Conversation

peterlacko
Copy link

PR contains tests for following functionality:

  • It is possible to create two puppet repos, with and without feed URLs respectively (CreateTestCase),
  • Create repo with valid feed and run sync ends without errors for both valid and invalid query (SyncValidFeedTestCase),
  • Create repo with invalid feed and run sync ends with error (SyncInvalidFeedTestCase),
  • Following steps finish without errors (PublishTestCase)
    • Create two repositories: foo and bar.
    • upload custom puppet module to foo,
    • copy foo to bar and publish both,
    • query pulp server for modules using all query formats supported by given pulp version
    • download modules from their expected locations on pulp server file system,
    • verify integrity of downloaded modules.

@Ichimonji10
Copy link
Contributor

Please rebase onto master.

@peterlacko peterlacko force-pushed the puppet-repo-test branch 2 times, most recently from 326ec33 to 2494550 Compare December 2, 2015 14:34
└── It is possible to upload an puppet module to a repository, copy the
repository's contents to a second repository, add distributor to both
both repositories, publish them. Data integrity of queried modules
from pul serverver is also verified (PublishTestCase)
Copy link
Contributor

Choose a reason for hiding this comment

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

Can we re-word this?

Copy link
Author

Choose a reason for hiding this comment

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

Thanks, done.

@peterlacko peterlacko force-pushed the puppet-repo-test branch 2 times, most recently from 0ff9ad6 to 1f20e0d Compare December 3, 2015 18:43
@Ichimonji10
Copy link
Contributor

@placko, if the tests in this new module are in good shape, please run them and capture some test output, and put that test output in the commit message.

While we're at it, please update the commit message. I notice that the PR message here on GitHub is significantly more fleshed out than the commit itself.

@peterlacko
Copy link
Author

@Ichimonji10 Ok, I will also split commits into two as is written above

@Ichimonji10
Copy link
Contributor

Thank you.

@Ichimonji10
Copy link
Contributor

Version handling logic has been added on the master branch. The big new difference is that pulp_smash.config.ServerConfig objects all now have a version attribute. This attribute is a packaging.version.Version object. These Version objects have quite intuitive usage:

>>> from packaging.version import Version
>>> Version('1') < Version('10')
True
>>> Version('2.7.3') > Version('2.7')
True
>>> Version('2.7.0') == Version('2.7')                                                                    
True

Version handling objects are useful for a number of reasons. Among others, they are superior to (codepoint-based) string comparisons:

>>> '1' < '10'  # OK
True
>>> '6' < '10'  # uh oh
False

They're also better than tuple comparisons in that they properly implement PEP 0440. While that PEP has come from the Python community, it's useful in the general sense, and compatible with semantic versioning. Should we want less strict version handling, we can also use packaging.version.parse. See more info here.

How do you use these new versioning objects in Pulp Smash? As mentioned, they're available on ServerConfig objects. Check it out:

>>> from pulp_smash.config import ServerConfig
>>> cfg = ServerConfig()
>>> type(cfg.version)
<class 'packaging.version.Version'>
>>> str(cfg.version)
'1!0'

What in the world is '1!0'? It's a valid version string - no, really! It reads "epoch 1, version 0". Any version with "epoch 1" or above will always be greater than a version in "epoch 0", and by default, every version is implicitly in epoch 0:

>>> from packaging.version import Version
>>> Version('1!0') > Version('2.6')                                                                       
True
>>> Version('1!0') > Version('3.1')                                                                       
True
>>> Version('0!3.1') == Version('3.1')
True

By the way, version string epochs aren't some wacky weird thing. They're widely recognized and used. I use them in some of the software packages I maintain, due to the fact that the developers have messed up and used incorrect version numbers, or due to developers changing numbering schemes.

Back to Pulp Smash.

How can we use these versions in our code? Let's take an example from this pull request. This bit of code is only valid on Pulp 2.7 and above:

        # Query modules on server. Data integrity is tested in tests below.
        query_href = '/v3/releases?module={}/{}'.format(
            _PUPPET_QUERY_PACKAGE['name'],
            _PUPPET_QUERY_PACKAGE['author']
        )
        cls.bodies['query units'] = tuple((
            _query_repo(
                cls.cfg,
                query_href,
                body['repo_id'],
                cls.responses['query units']
            ) for body in cls.bodies['distribute']
        ))

Now, I don't know the details of Pulp's behaviour here. But I'm going to assume that Pulp 2.6 and older also let you query for puppet modules, but with a different query. You can add in some conditional logic like so:

        # Query modules on server. Data integrity is tested in tests below.
        if cls.cfg.version < Version('2.7'):
            query_href =else:
            query_href = '/v3/releases?module={}/{}'.format(
                _PUPPET_QUERY_PACKAGE['name'],
                _PUPPET_QUERY_PACKAGE['author']
            )
        cls.bodies['query units'] = tuple((
            _query_repo(
                cls.cfg,
                query_href,
                body['repo_id'],
                cls.responses['query units']
            ) for body in cls.bodies['distribute']
        ))

Just to be clear, this works as-is with absolutely no changes to the end user. An end user can now add a "version" attribute to their configuration file to explicitly state which version of Pulp they're testing against, like so:

{
    "default": {
        "version": "2.6.3",
        "base_url": "https://192.168.121.222",
        "verify": false,
        "auth": ["admin", "admin"]
    }
}

But this is entirely optional. Again, by default, Pulp Smash will assume that you're testing the most up-to-date development version of Pulp. It does this by automatically setting a vesrion of '1!0' if none is specified.

poll_spawned_tasks(cls.cfg, call_report)

# Query modules on server. Data integrity is tested in tests below.
query_href = '/v3/releases?module={}/{}'.format(
Copy link
Member

Choose a reason for hiding this comment

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

We need to test that you can use the older versions of the puppet forge API (puppet clients prior to version 3.3).

On my dev environment I am able to run:

http --verify=no GET http://.:repo1@hostname/api/v1/releases.json?module=domcleal/katellovirt

In response I get json that tells me where that module can be downloaded. The basic auth in the above request is explained here [0].

We should also attempt to query the forge API used for clients between versions 3.3 and 3.6. The way the request is formulated is described here [1] These two additional scenarios will work on Pulp 2.6+, however the test that is already implemented will only work for Pulp version 2.7+.

[0] http://pulp-puppet.readthedocs.org/en/latest/tech-reference/forge_api.html#basic-auth
[1] http://pulp-puppet.readthedocs.org/en/latest/user-guide/recipes.html#installing-with-puppet-client-3-3

Copy link
Contributor

Choose a reason for hiding this comment

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

@dkliban I don't understand the bit about "we should attempt to query the forge API for clients between version 3.3 and 3.6.". Are you saying that the portion of the test case below this line is simply not applicable on Pulp 2.6 and older due to its use of an old pulp_python version or something? ELI5, please.

Copy link
Author

Choose a reason for hiding this comment

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

After discussion with @dkliban querying the module will look as follows:

  • for pulp >= 2.7, 3 puppet queries formats will be tested, namely for puppet <=3.3, 3.3 - 3.5 and >=3.6
  • for pulp <= 2.6 only queries from puppet <3.6 will be tested, as pulp in these versions doesn't support queries to new forge API [1]

I hope it makes sense.
[1] https://forgeapi.puppetlabs.com/

))
for i in range(2):
for call_report in cls.bodies['publish'][i]:
poll_spawned_tasks(cls.cfg, call_report)
Copy link
Contributor

Choose a reason for hiding this comment

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

I think the index variable can be dropped:

        for call_report in cls.bodies['publish']:
            poll_spawned_tasks(cls.cfg, call_report)

Copy link
Author

Choose a reason for hiding this comment

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

cls.bodies['publish'] is tuple so we have to iterate over it like

for publish_report in cls.bodies['publish']:
    for call_report in publish_report:
        poll_spawned_tasks(cls.cfg, call_report)

but got the idea, avoid hard coded indexes whenever possible.

Copy link
Contributor

Choose a reason for hiding this comment

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

Thanks for the correction. Yes, the idea is to just avoid hard coded indices.

@Ichimonji10
Copy link
Contributor

FYI, I've moved added functions to module pulp_smash.utils:

  • get_importers
  • publish_repository
  • sync_repository

They should be usable in module pulp_smash.tests.puppet.api_v2.test_sync_publish.



def _import_puppet_to_repo(server_config, upload_id, href, responses=None):
"""Import an puppet from an upload into a repository.
Copy link
Member

Choose a reason for hiding this comment

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

Import a puppet module from an upload request into a repository.

Copy link
Author

Choose a reason for hiding this comment

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

Thanks.

Tests in this commit check following pulp functionality:

* It is possible to create two puppet repos, with and without feedURLs respectively
  (CreateTestCase),
* Create repo with valid feed and run sync ends without errors for both
  valid and invalid query (SyncValidFeedTestCase),
* Create repo with invalid feed and run sync ends with error
  (SyncInvalidFeedTestCase),
* Following steps finish without errors (PublishTestCase)
  * Create two repositories: foo and bar.
  * upload custom puppet module to foo,
  * copy foo to bar and publish both,
  * query pulp server for modules using all query formats supported by given pulp version
  * download modules from their expected locations on pulp server file system,
  * verify integrity of downloaded modules.

Sample output tested on machine with RedHat 7.1 and pulp 2.7 installed:
$ python -m unittest2 -v pulp_smash.tests.puppet.api_v2.test_sync_publish
test_id_notes (pulp_smash.tests.puppet.api_v2.test_sync_publish.CreateTestCase)
Validate the ``id`` and ``notes`` attributes for each repo. ... ok
test_importer_config (pulp_smash.tests.puppet.api_v2.test_sync_publish.CreateTestCase)
Validate the ``config`` attribute of each importer. ... ok
test_importer_type_id (pulp_smash.tests.puppet.api_v2.test_sync_publish.CreateTestCase)
Validate the ``importer_type_id`` attribute of each importer. ... ok
test_number_importers (pulp_smash.tests.puppet.api_v2.test_sync_publish.CreateTestCase)
Each repository should have only one importer. ... ok
test_call_reports_keys (pulp_smash.tests.puppet.api_v2.test_sync_publish.PublishTestCase)
Verify each call report has the correct keys. ... ok
test_call_reports_values (pulp_smash.tests.puppet.api_v2.test_sync_publish.PublishTestCase)
Verify no call report contains any errors. ... ok
test_sanity (pulp_smash.tests.puppet.api_v2.test_sync_publish.PublishTestCase)
Verify we collected a correct set of response bodies. ... ok
test_search_units (pulp_smash.tests.puppet.api_v2.test_sync_publish.PublishTestCase)
Verify the two repositories have the same units. ... ok
test_status_codes (pulp_smash.tests.puppet.api_v2.test_sync_publish.PublishTestCase)
Verify the HTTP status code of each server response. ... ok
test_units_integrity (pulp_smash.tests.puppet.api_v2.test_sync_publish.PublishTestCase)
Verify integrity of modules downloaded from pulp server. ... ok
test_upload (pulp_smash.tests.puppet.api_v2.test_sync_publish.PublishTestCase)
Verify the response body for uploading module. ... ok
test_upload_free (pulp_smash.tests.puppet.api_v2.test_sync_publish.PublishTestCase)
Verify  the response body for ending an upload request. ... ok
test_upload_malloc (pulp_smash.tests.puppet.api_v2.test_sync_publish.PublishTestCase)
Verify the response body for starting an upload request. ... ok
test_error_details (pulp_smash.tests.puppet.api_v2.test_sync_publish.SyncInvalidFeedTestCase)
Assert each task's progress report contains error details. ... ok
test_number_tasks (pulp_smash.tests.puppet.api_v2.test_sync_publish.SyncInvalidFeedTestCase)
Assert that only one task was spawned. ... ok
test_start_sync_code (pulp_smash.tests.puppet.api_v2.test_sync_publish.SyncInvalidFeedTestCase)
Assert the call to sync a repository returns an HTTP 202. ... ok
test_task_error (pulp_smash.tests.puppet.api_v2.test_sync_publish.SyncInvalidFeedTestCase)
Assert each task's "error" field is non-null. ... ok
test_task_traceback (pulp_smash.tests.puppet.api_v2.test_sync_publish.SyncInvalidFeedTestCase)
Assert each task's "traceback" field is non-null. ... ok
test_start_sync_code (pulp_smash.tests.puppet.api_v2.test_sync_publish.SyncValidFeedTestCase)
Assert the call to sync each repository returns an HTTP 202. ... ok
test_task_error (pulp_smash.tests.puppet.api_v2.test_sync_publish.SyncValidFeedTestCase)
Assert each task's "error" field is null. ... ok
test_task_progress_report (pulp_smash.tests.puppet.api_v2.test_sync_publish.SyncValidFeedTestCase)
Assert no task's progress report contains error details. ... ok
test_task_traceback (pulp_smash.tests.puppet.api_v2.test_sync_publish.SyncValidFeedTestCase)
Assert each task's "traceback" field is null. ... ok

----------------------------------------------------------------------
Ran 22 tests in 41.743s

OK
@Ichimonji10
Copy link
Contributor

@peterlacko, I've walked through this pull request and given it a thorough once-over. Please take a look at master...Ichimonji10:puppet, and let me know if I've messed anything up.

@peterlacko
Copy link
Author

@Ichimonji10: looks OK.

@Ichimonji10
Copy link
Contributor

Merged as c0d8d08.

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.

None yet

3 participants