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

[wip] Add Tor Browser-based functional testing #4029

Closed
wants to merge 84 commits into from
Closed

Conversation

redshiftzero
Copy link
Contributor

@redshiftzero redshiftzero commented Jan 10, 2019

Status

This is getting merged in stages, sub PRs:

Description of Changes

Fixes #3659. Fixes #1502. We'll need to file a followup when this PR is merged for testing over Tor (we have #3661 but there could be an intermediate step which is getting the external server testing working prior to the CI integration).

Changes proposed in this pull request:

  • Primarily, run (most) functional tests using Tor Browser

Testing

Does CI pass?

If flakes are discovered, we should resolve them in this PR.

Deployment

Testing only.

Checklist

If you made non-trivial code changes:

  • I have written a test plan and validated it for this PR

If you made changes to documentation:

  • Doc linting (make docs-lint) passed locally

kushaldas and others added 30 commits December 20, 2018 19:14
This prevents the accidental commit of private information.
The 'when' conditional detecting a grsec kernel, used for running the
paxctl commands on the TBB binary, was needlessly duplicated on the
relevant task. Fortunately that didn't cause breakage, because the
'when' lines were identical, but only one was active.
Now installs Firefox 52 ESR, rather than Firefox 46, for use inside the
test container.

Includes changes to run-test shell script:

    TOR_FORCE_NET_CONFIG=0 is required to directly connect to Tor
    network, otherwise it will wait for userinput to either connect
    or to configure

    The `run_xvfb` invocation is no longer necessary, since the test suite
    code bootstraps the headless server now.
Bootstrapping the application services within the functional test suite.
Includes some cleanup, culling unused debugging code, and also cleans up
the various print statements.

Ignore functional test firefox logs (thanks, @msheiny!)

Adds retries for tor network connection failure, using the pre-existing
logic.
The version of torsocks in the Trusty repos isn't recent enough to
support custom ports. Rather than install from other sources, which
requires manual package verification (or configuring non-trusty repos,
which could break other packages), let's fall back to good ol' nc.
We need to create a new firefox profile to test the orbot specific
warning. This works for both locally and over Tor.
Now we can safely execute the account changes in the tests running
on the Tor browser. The logic update makes sure to create different
user for this test than any other test.
@codecov-io
Copy link

Codecov Report

Merging #4029 into develop will decrease coverage by 0.13%.
The diff coverage is n/a.

Impacted file tree graph

@@             Coverage Diff             @@
##           develop    #4029      +/-   ##
===========================================
- Coverage     84.7%   84.56%   -0.14%     
===========================================
  Files           43       43              
  Lines         2765     2767       +2     
  Branches       300      300              
===========================================
- Hits          2342     2340       -2     
- Misses         355      359       +4     
  Partials        68       68
Impacted Files Coverage Δ
securedrop/securedrop/crypto_util.py 96.22% <0%> (-0.07%) ⬇️
securedrop/securedrop/create-dev-data.py 0% <0%> (ø) ⬆️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 985c59c...4224404. Read the comment docs.

Copy link
Contributor

@heartsucker heartsucker left a comment

Choose a reason for hiding this comment

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

First pass at reviewing. Just some nits and questions.

wget https://www.torproject.org/dist/torbrowser/${TBB_VERSION}/tor-browser-linux64-${TBB_VERSION}_en-US.tar.xz.asc && \
gpg --verify tor-browser-linux64-${TBB_VERSION}_en-US.tar.xz.asc tor-browser-linux64-${TBB_VERSION}_en-US.tar.xz

RUN tar -xvJf tor-browser-linux64-${TBB_VERSION}_en-US.tar.xz && \
Copy link
Contributor

Choose a reason for hiding this comment

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

Is there a reason to make this a separate step? At the very least it seems that the extract should be a part of the previous RUN in order to cut down on the size of the intermediate layers.

@@ -34,6 +60,8 @@ RUN pip install -r requirements/securedrop-app-code-requirements.txt && \
pip install -r requirements/test-requirements.txt

RUN if test $USER_NAME != root ; then useradd --no-create-home --home-dir /tmp --uid $USER_ID $USER_NAME && echo "$USER_NAME ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers ; fi
RUN cp -r /root/.local /tmp/ && chmod +x /tmp/.local/tbb/tor-browser_en-US/Browser/firefox && chmod -R 777 /tmp/.local
Copy link
Contributor

Choose a reason for hiding this comment

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

It might be worth squashing these three RUNs together to save space

--rm \
--user "${USER:-root}" \
--volume "${TOPLEVEL}:${TOPLEVEL}" \
--workdir "${TOPLEVEL}/securedrop" \
-ti ${DOCKER_RUN_ARGUMENTS:-} securedrop-test "$@"
-ti ${DOCKER_RUN_ARGUMENTS:---rm --name securedrop-dev} securedrop-test "$@"
Copy link
Contributor

Choose a reason for hiding this comment

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

This --rm seems to be a duplicate since it is included above.

@@ -7,4 +7,7 @@ py
pytest
pytest-cov
pytest-mock
selenium < 3
requests[socks]>2.19.1
Copy link
Contributor

Choose a reason for hiding this comment

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

We should specify in a comment why we're requiring at least this version.

@@ -37,6 +36,9 @@ def _source_clicks_submit_documents_on_homepage(self):
assert submit_button_icon.is_displayed() is False
submit_button_hover_icon = self.driver.find_element_by_css_selector(
'a#submit-documents-button > img.on-hover')
ActionChains(self.driver).move_to_element(
submit_button_hover_icon).perform()
self.wait_for(lambda: submit_button_hover_icon.is_displayed())
Copy link
Contributor

Choose a reason for hiding this comment

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

Doing a wait_for on condition X then asserting X below seems redundant. There are several instances of this, but maybe we want to leave it for clarity / explicitness.

@@ -14,11 +14,13 @@ def test_submit_and_retrieve_happy_path(self):
self._source_continues_to_submit_page()
self._source_submits_a_file()
self._source_logs_out()
self.swap_drivers() # To use Firefox
Copy link
Contributor

Choose a reason for hiding this comment

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

What is the reasoning for using both FF and Tor in a single test run? I think this should be clarified somewhere in a comment.

Copy link
Contributor

Choose a reason for hiding this comment

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

The Tor Browser does not allow get any cookies, that is why we have to use both firefox and tor browser.

Copy link
Contributor

Choose a reason for hiding this comment

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

Word. That's fair. I think we should note that somewhere so it's understood why it's happening since these tests are already complex.

actions.send_keys(Keys.RETURN)
actions.perform()

def swap_drivers(self):
Copy link
Contributor

Choose a reason for hiding this comment

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

It might be worth adding a named argument here like

def swap_drivers(self, new_driver):
    if new_driver == 'tor':
        ...

That way at the call sites here it's clear why driver we're swapping to and not just via a comment. This would also robustify tests so that we're not unexpectedly swapping drivers when we really don't want. This could even raise an error to fail the test if we try to swap to the driver that's already in use.

Like are these swaps done because we are only swapping between FF and TB? Or at they also used to swap between two Tor instances, one pointing at the source interface and one pointing at the journalist interface?


self.source_app = source_app.create_app(config)
self.journalist_app = journalist_app.create_app(config)
self.patcher2 = mock.patch('source_app.main.get_entropy_estimate')
Copy link
Contributor

Choose a reason for hiding this comment

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

Nit: I know we don't access this patcher2 anywhere except on teardown, but it could have a more specific name.

tbb_sleep_time: 160
tbb_selenium_user: journalist
tbb_selenium_password: correct horse battery staple profanity oil chewy
tbb_selenium_secret: JHCOGO7VCER3EJ4L
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 this variable could be renamed tbb_selenium_totp_secret because at first I thought this meant "secret that is for selenium".

def _edit_user(self, username):
user = Journalist.query.filter_by(username=username).one()
def _edit_user(self, username, is_admin=False):
# XXXX
Copy link
Contributor

Choose a reason for hiding this comment

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

Is this a TODO? If so, can we add why it's here, and if not can we remove it?

@redshiftzero
Copy link
Contributor Author

Recapping what I said in Gitter earlier: there is so much divergence from develop, and the git history is so messy here in parts (i.e. we add logic that we then remove later in the history), I propose the fastest way to merge this is by merging in parts of the diff in separate PRs, cherry picking where it makes sense and making new commits where it doesn't. This will enable us to get the changes in here merged without making it too nightmarish for those working on this branch, i.e. no more rebasing 80+ commits and sometimes introducing errors during conflict resolution.

These individual PRs would include:

  • Removal of Firefox/test dependencies from app-test Ansible role
  • Adding addition of user creation to staging (the changes to create-dev-data.py and the molecule logic)
  • VNC logic
  • Finally, the Install of Tor Browser and functional test changes

Other PRs may make sense along the way, but these above changes that are all self-contained and can be merged separately to scope this task down to something that is hopefully easier for us to manage. What do y'all think @rmol @zenmonkeykstop @kushaldas ?

@eloquence
Copy link
Member

eloquence commented Mar 22, 2019

The plan of record is consistent with the above. See follow-up issues: #4286, #4289, #4290 and pending PR #4288.

I've removed this PR from the board; I'm assuming it can be closed at this point, but waiting for confirmation.

@eloquence
Copy link
Member

Checked with Jen, OK to close.

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.

Use Tor for functional testing and pre-release QA Selenium 3 support
7 participants