#!/usr/bin/env python from __future__ import absolute_import, print_function import unittest import mozunit import io import os import shutil import tempfile import requests import threading import time import re import mock import six from mozgeckoprofiler import view_gecko_profile if six.PY2: # Import for Python 2 from urllib import unquote else: # Import for Python 3 from urllib.parse import unquote def access_profiler_link(file_url, response): """Attempts to access the profile in a loop for 5 seconds. This is run from a separate thread. """ timeout = 5 # seconds start = time.time() while time.time() - start < timeout: # Poll the server to try and get a response. result = requests.get(url=file_url) if result.ok: # Return the text back in a list. response[0] = result.text return time.sleep(0.1) response[0] = "Accessing the profiler link timed out after %s seconds" % timeout class TestViewGeckoProfile(unittest.TestCase): """Tests the opening local profiles in the Firefox Profiler.""" def setUp(self): self.firefox_profiler_url = None self.thread = None self.response = [None] def test_view_gecko_profile(self): # Create a temporary fake performance profile. temp_dir = tempfile.mkdtemp() profile_path = os.path.join(temp_dir, "fakeprofile.json") with io.open(profile_path, "w") as f: f.write(u"FAKE_PROFILE") # Mock the open_new_tab function so that we know when the view_gecko_profile # function has done all of its work, and we can assert ressult of the # user behavior. def mocked_open_new_tab(firefox_profiler_url): self.firefox_profiler_url = firefox_profiler_url encoded_file_url = firefox_profiler_url.split("/")[-1] decoded_file_url = unquote(encoded_file_url) # Extract the actual file from the path. self.thread = threading.Thread( target=access_profiler_link, args=(decoded_file_url, self.response) ) print("firefox_profiler_url %s" % firefox_profiler_url) print("encoded_file_url %s" % encoded_file_url) print("decoded_file_url %s" % decoded_file_url) self.thread.start() with mock.patch("webbrowser.open_new_tab", new=mocked_open_new_tab): # Run the test view_gecko_profile(profile_path) self.thread.join() # Compare the URLs, but replace the PORT value supplied, as that is dynamic. expected_url = ( "https://profiler.firefox.com/from-url/" "http%3A%2F%2F127.0.0.1%3A{PORT}%2Ffakeprofile.json" ) actual_url = re.sub("%3A\d+%2F", "%3A{PORT}%2F", self.firefox_profiler_url) self.assertEqual( actual_url, expected_url, "The URL generated was correct for the Firefox Profiler.", ) self.assertEqual( self.response[0], "FAKE_PROFILE", "The response from the serve provided the profile contents.", ) shutil.rmtree(temp_dir) if __name__ == "__main__": mozunit.main()