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

Move sensitive configuration options into separate files #93

Merged
merged 1 commit into from
Jan 25, 2017

Conversation

davehunt
Copy link
Contributor

Read credentials for cloud testing services from configuration files in the working or home directory. Fixes #60

@@ -2,6 +2,12 @@
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.

try:
import configparser
except ImportError:
Copy link
Member

Choose a reason for hiding this comment

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

Hey @davehunt a small comment here: in my experience it is better to try to import using a version check rather than fallback from an import error, because the latter might make it harder to debug some import errors. For example, if one has a botched installation or someone has mocked configparser somehow and it fails to import, it will fallback to the second import and "hide" the original error (in Python 2 at least, in Python 3 it won't be a big deal). I had this issue in pytest-dev/pytest-mock#68, where import mock was failing because some missing dependencies.

In summary, I suggest using this instead:

if sys.version_info[0] == 2:
    import ConfigParser as configparser
else:
    import configparser

try:
username = config.get('credentials', 'username')
except (configparser.NoSectionError, configparser.NoOptionError, KeyError):
username = os.getenv('BROWSERSTACK_USERNAME')
if not username:
raise pytest.UsageError('BrowserStack username must be set')
Copy link
Member

Choose a reason for hiding this comment

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

It would be nice to mention BROWSERSTACK_USERNAME in this error message.

except (configparser.NoSectionError, configparser.NoOptionError, KeyError):
key = os.getenv('BROWSERSTACK_ACCESS_KEY')
if not key:
raise pytest.UsageError('BrowserStack access key must be set')
Copy link
Member

Choose a reason for hiding this comment

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

Ditto on this error message as well.


def _username(config):
username = config.getini('sauce_labs_username')
def credentials():
Copy link
Member

Choose a reason for hiding this comment

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

Perhaps it would be worth refactoring credentials so it can be reused by the various drivers? The logic seems to be identical across them: read a config file, try to get the credentials from it, fallback to an environment variable, etc.



def test_invalid_credentials_env(failure, monkeypatch, tmpdir):
monkeypatch.setattr(os.path, 'expanduser', lambda p: str(tmpdir))
Copy link
Member

Choose a reason for hiding this comment

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

If you refactor credentials() so it can be reused, I suggest then refactoring the tests as well so you can use the same set of tests related to credentials in all the drivers.

I usually do this by having a base class with test methods, and then subclass that base class in each module configuring it (perhaps using class variables) with the specifics for that driver.

@davehunt
Copy link
Contributor Author

@nicoddemus thank you so much for the review... your suggestions were spot on! I've addressed the duplication in the cloud drivers, but have left the test duplication for now. I've also introduced a much more helpful custom exception. This refactoring will allow for further improvements, but I'll leave those for another time. If you get a chance, I'd appreciate another review.

Copy link
Member

@nicoddemus nicoddemus left a comment

Choose a reason for hiding this comment

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

Looks great, I think the new classes improved the code significantly. 👍 😄

**1.8.0 (unreleased)**

* **BREAKING CHANGE:** Moved cloud testing provider credentials into separate
files for improved security.
Copy link
Member

Choose a reason for hiding this comment

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

I think it would be nice to mention the changes in a little more detail, perhaps mentioning #60, and a little example of what users should do to migrate their current configuration.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks, I've made some updates and rebased/squashed in preparation for a merge and release later today. I really appreciate your time @nicoddemus!

Copy link
Member

Choose a reason for hiding this comment

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

Absolutely, my pleasure! 😁

Thanks for all the time and effort you put in your excellent plugins as well! 👍

Read credentials for cloud testing services from configuration files in the working or home directory. Fixes pytest-dev#60
@davehunt davehunt merged commit 2b3d913 into pytest-dev:master Jan 25, 2017
@davehunt davehunt deleted the issue60 branch August 14, 2017 12:43
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