diff --git a/autopush/diagnostic_cli.py b/autopush/diagnostic_cli.py index 24debb1f..376a1128 100644 --- a/autopush/diagnostic_cli.py +++ b/autopush/diagnostic_cli.py @@ -5,12 +5,33 @@ import configargparse from twisted.logger import Logger +from cryptography.fernet import InvalidToken from autopush.config import AutopushConfig from autopush.db import DatabaseManager, Message +from autopush.exceptions import ItemNotFound, InvalidTokenException from autopush.main import AutopushMultiService from autopush.main_argparse import add_shared_args +""" +Diagnostic Command Line Interface for Autopush Subscription URLS. + +This tool extracts the User Agent ID and Channel ID from a +Push Subscription URL. + +Push subscription endpoints generally follow the form: +``` +https://updates.push.services.mozilla.com/wpush/v1/gAAA...f9x +``` + +To use this tool: +``` +endpoint_diagnostic +``` + + +""" + PUSH_RE = re.compile(r"push/(?:(?Pv\d+)/)?(?P[^/]+)") @@ -54,26 +75,36 @@ def run(self): md = match.groupdict() api_ver, token = md.get("api_ver", "v1"), md["token"] - parsed = self._conf.parse_endpoint( - self.db.metrics, - token=token, - version=api_ver, - ) - uaid, chid = parsed["uaid"], parsed["chid"] + try: + parsed = self._conf.parse_endpoint( + self.db.metrics, + token=token, + version=api_ver, + ) + uaid, chid = parsed["uaid"], parsed["chid"] + except (InvalidTokenException, InvalidToken) as ex: + print(("Token could not be deciphered: {}. " + "Are you using the correct configuration or platform?") + .format(ex)) + return "Invalid Token" print("UAID: {}\nCHID: {}\n".format(uaid, chid)) - rec = self.db.router.get_uaid(uaid) - print("Router record:") - self._pp.pprint(rec._data) + try: + rec = self.db.router.get_uaid(uaid) + print("Router record:") + self._pp.pprint(rec) + if "current_month" in rec: + chans = Message(rec["current_month"], + boto_resource=self.db.resource).all_channels( + uaid) + print("Channels in message table:") + self._pp.pprint(chans) + except ItemNotFound as ex: + print("Item Missing from database: {}".format(ex)) + return "Not Found" print("\n") - if "current_month" in rec: - chans = Message(rec["current_month"], - boto_resource=self.db.resource).all_channels(uaid) - print("Channels in message table:") - self._pp.pprint(chans) - def run_endpoint_diagnostic_cli(sysargs=None, use_files=True, resource=None): cli = EndpointDiagnosticCLI(sysargs, diff --git a/autopush/tests/test_diagnostic_cli.py b/autopush/tests/test_diagnostic_cli.py index b4fbaaf6..e5f8c284 100644 --- a/autopush/tests/test_diagnostic_cli.py +++ b/autopush/tests/test_diagnostic_cli.py @@ -2,6 +2,9 @@ from mock import Mock, patch +from cryptography.fernet import InvalidToken + +from autopush.exceptions import ItemNotFound import autopush.tests @@ -33,6 +36,31 @@ def test_bad_endpoint(self): returncode = cli.run() assert returncode not in (None, 0) + def test_invalid_endpoint(self): + def err(*args, **kwargs): + raise InvalidToken("You are unworthy") + + cli = self._makeFUT([ + "--router_tablename=fred", + "http://something/wpush/v1/indecipherable_token"]) + cli._conf = Mock() + cli._conf.parse_endpoint.side_effect = err + returncode = cli.run() + assert returncode == "Invalid Token" + + def test_invalid_db(self): + cli = self._makeFUT([ + "--router_tablename=fred", + "http://something/wpush/v1/indecipherable_token"]) + cli._conf = Mock() + cli._conf.parse_endpoint.return_value = dict( + uaid="adsf", chid="adsf" + ) + cli.db.router.get_uaid = Mock() + cli.db.router.get_uaid.side_effect = ItemNotFound + returncode = cli.run() + assert returncode == "Not Found" + @patch("autopush.diagnostic_cli.Message") @patch("autopush.diagnostic_cli.AutopushConfig") @patch("autopush.diagnostic_cli.DatabaseManager.from_config") diff --git a/docs/testing.rst b/docs/testing.rst index 3b5133ad..caa19ea5 100644 --- a/docs/testing.rst +++ b/docs/testing.rst @@ -4,6 +4,26 @@ Testing ======= +Testing Configuration +===================== + +When testing, it's important to reduce the number of potential conflicts as much +as possible. To that end, it's advised to have as clean a testing environment as +possible before running tests. + +This includes: + +* Making sure notifications are not globally blocked by your browser. +* "Do Not Disturb" or similar "distraction free" mode is disabled on your OS +* You run a "fresh" Firefox profile (start `firefox --P` to display the profile picker) which does not have extra extensions or optional plug-ins running. Running `firefox --P --no-remote` allows two different firefox profiles run at the same time.) + +You may find it useful to run firefox in a Virtual Machine (like VirtualBox or +VMWare), but this is not required. + +In addition, it may be useful to open the Firefox Brower Console (Ctrl+Shift+J) +as well as the Firefox Web Console (Ctrl+Shift+K). Both are located under the *Web +Developer* sub-menu. + Running Tests ============= @@ -21,6 +41,7 @@ Once the Makefile has been run, you can run ``make test`` to run the test suite. Failures may occur if a ``.boto`` file exists in your home directory. This file should be moved elsewhere before running the tests. + Disabling Integration Tests ---------------------------