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 more integration tests #615

Merged
merged 3 commits into from
Oct 19, 2020

Conversation

lucasmoura
Copy link
Contributor

Translate tests from cloud_test to the new integration test framework.

We are translating the following tests:

  • test_runcmd.py
  • seed_random_data.py
  • set_hostname.py
  • set_hostname_fqdn.py
  • snap.py
  • ssh_auth_key_fingerprints_disable.py
  • ssh_auth_key_fingerprints_enable.py
  • ssh_import_id.py
  • ssh_keys_generate.py
  • ssh_keys_provided.py
  • timezone.py
  • write_files.py

Copy link
Collaborator

@OddBloke OddBloke left a comment

Choose a reason for hiding this comment

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

Thanks for this change Lucas! You've clearly done a great job of understanding both the old and new test frameworks. My comments inline are generally either requests for docstring cleanup/clarification, or suggest that we parameterise some tests which I think would lend themselves to it well; this latter suggestion will involve understanding how class_client works (vs client), and you can see an example of this in test_users_groups.py.

Comment on lines 1 to 3
"""Integration test for the runcmd module.
This test specifies a command to be executed by the ``runcmd`` module
Copy link
Collaborator

Choose a reason for hiding this comment

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

Per PEP-257, which we generally try to follow:

Multi-line docstrings consist of a summary line just like a one-line docstring, followed by a blank line, followed by a more elaborate description.

Suggested change
"""Integration test for the runcmd module.
This test specifies a command to be executed by the ``runcmd`` module
"""Integration test for the runcmd module.
This test specifies a command to be executed by the ``runcmd`` module

(This is a nit, but an easily fixable one.)

@@ -0,0 +1,43 @@
"""Integration test for the set_hostname module.
This test specifies a hostname and fqdn through the ``set_hostname`` module
Copy link
Collaborator

Choose a reason for hiding this comment

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

This test

This file is two tests, we should describe each of them separately. (This is particularly important because they are two test methods in a single class: people may very easily assume that you're using a class_client based on this description, which makes it harder for them to understand what is going on.)

@@ -0,0 +1,27 @@
"""Integration test for the snap module.
This test specifies a command to be executed by the ``runcmd`` module
Copy link
Collaborator

Choose a reason for hiding this comment

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

runcmd

This needs an update.

Comment on lines 26 to 27
assert "core" in snap_output
assert "hello-world" in snap_output
Copy link
Collaborator

Choose a reason for hiding this comment

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

Perhaps worth adding spaces here to reduce the likelihood that we match substrings elsewhere in the output?

Suggested change
assert "core" in snap_output
assert "hello-world" in snap_output
assert "core " in snap_output
assert "hello-world " in snap_output



USER_DATA = """\
#cloud-config
Copy link
Collaborator

Choose a reason for hiding this comment

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

This is all indented by two more spaces than necessary.

class TestSshKeysProvided:

@pytest.mark.user_data(USER_DATA)
def test_ssh_keys_provided(self, client):
Copy link
Collaborator

Choose a reason for hiding this comment

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

This feels like another good candidate for parameterisation, what do you think?

Comment on lines 11 to 13
# NOTE: on trusty 'file' has an output formatting error for binary files and
# has 2 spaces in 'LSB executable', which causes a failure here
#
Copy link
Collaborator

Choose a reason for hiding this comment

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

We don't expect to run these tests against trusty, so I think we can drop this disclaimer:

Suggested change
# NOTE: on trusty 'file' has an output formatting error for binary files and
# has 2 spaces in 'LSB executable', which causes a failure here
#

class TestWriteFiles:

@pytest.mark.user_data(USER_DATA)
def test_write_files(self, client):
Copy link
Collaborator

Choose a reason for hiding this comment

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

Another good candidate for parameterisation?

#cloud-config
write_files:
- encoding: b64
content: CiMgVGhpcyBmaWxlIGNvbnRyb2xzIHRoZSBzdGF0ZSBvZiBTRUxpbnV4
Copy link
Collaborator

Choose a reason for hiding this comment

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

As we are defining this string in Python, what do you think to doing something like:

ASCII_TEXT = "ASCII text"
B64_CONTENT = base64.b64encode(ASCII_TEXT)

and then using .format() to include it in USER_DATA?

This saves us from having the "ASCII text" string defined only in the assertion code, which I think makes it easier to parse what is going on.

@lucasmoura
Copy link
Contributor Author

Thanks for the review @OddBloke. I think I have addressed all of the comments

Copy link
Collaborator

@OddBloke OddBloke left a comment

Choose a reason for hiding this comment

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

Thanks Lucas, this is really good work! I have a couple of minor doc nits, which I'll apply myself before landing.

(I also have started a convo with James inline, perhaps we should take that to a different forum.)

@pytest.mark.user_data(USER_DATA)
class TestPackageUpdateUpgradeInstall:

def assert_package_installed(self, pkg_out, name, version=None):
Copy link
Collaborator

Choose a reason for hiding this comment

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

@TheRealFalcon This assertion helper mirrors one in the cloud_tests/ which is used in multiple places: do you have any thoughts as to whether we should store such shared "test" code on client, or elsewhere?

(No change needed as part of this PR, to be clear!)

Copy link
Member

Choose a reason for hiding this comment

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

Yeah, that's a good question. I'm worried about seeing every conceivable helper function going into that class with implementations being nothing more than a series of execs or push/pulls and parsing what's returned, though I realize we're kind of already doing that with the install_* and read/write methods.

Would it make sense to start putting these kinds of helper functions into separate files (not named util.py) and have the helper function take an IntegrationClient as an argument?

@OddBloke OddBloke merged commit b94962b into canonical:master Oct 19, 2020
@OddBloke
Copy link
Collaborator

OddBloke commented Oct 19, 2020 via email

@TheRealFalcon
Copy link
Member

Yeah, that's a good option too. It makes the calling semantics a nicer. I do get a little nervous about having the IntegrationClient "own" these additional modules when it doesn't really need to. Tradeoffs either way I guess.

This was referenced May 12, 2023
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