blob: 822b86476bd40e469b9ec2b45da2f957f4afd05d [file] [log] [blame]
# Copyright 2018 The Cobalt Authors. All Rights Reserved.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# See the License for the specific language governing permissions and
# limitations under the License.
"""Tests retry of asynchronous loading of scripts on Suspend/Resume."""
# This test script works by splitting the work over 3 threads, so that they
# can each make progress even if they come across blocking operations.
# The three threads are:
# 1. Main thread, runs BlackBoxTestCase, sends suspend/resume signals, etc.
# 2. HTTP Server, responsible for slowly responding to a fetch of a javascript
# file.
# 3. Webdriver thread, instructs Cobalt to navigate to a URL
# Steps in ~ chronological order:
# 1. Create a TCP socket and listen on all interfaces.
# 2. Start Cobalt, and point it to the socket created in Step 1.
# 3. Wait HTTP request for html resource.
# 4. Respond to a HTTP request.
# 5. Wait for a request for javascript resource.
# 6. Suspend Cobalt process.
# 7. Cobalt disconnects from the socket.
# 8. Resume Cobalt process.
# 9. Retry javascript resource, which allows the test to pass.
# 9. Check to see if JSTestsSucceeded().
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
import _env # pylint: disable=unused-import,g-bad-import-order
import logging
import os
import SimpleHTTPServer
import threading
import traceback
import urlparse
from cobalt.black_box_tests import black_box_tests
from cobalt.black_box_tests.threaded_web_server import MakeRequestHandlerClass
from cobalt.black_box_tests.threaded_web_server import ThreadedWebServer
_HTML_FILE_TO_REQUEST = 'retry_async_script_loads_after_suspend.html'
_JS_FILE_TO_REQUEST = 'script_executed.js'
_received_script_resource_request = threading.Event()
_test_finished = threading.Event()
# The base path of the requested assets is the parent directory.
_SERVER_ROOT_PATH = os.path.join(os.path.dirname(__file__), os.pardir)
class JavascriptRequestDetector(MakeRequestHandlerClass(_SERVER_ROOT_PATH)):
"""Proxies everything to SimpleHTTPRequestHandler, except some paths."""
_counter_lock = threading.Lock()
_request_counter = 0
def do_GET(self): # pylint: disable=invalid-name
"""Handles HTTP GET requests for resources."""
parsed_path = urlparse.urlparse(self.path)
if parsed_path.path == '/testdata/' + _JS_FILE_TO_REQUEST:
current_count = None
with self._counter_lock:
JavascriptRequestDetector._request_counter += 1
current_count = JavascriptRequestDetector._request_counter
if current_count < 2:
# It is important not to send any response back, so we block.'Waiting on test to finish.')
# Returns a 404, to make sure the page isn't loaded by the first
# request.
return SimpleHTTPServer.SimpleHTTPRequestHandler.do_GET(self)
class RetryAsyncScriptLoadsAfterSuspend(black_box_tests.BlackBoxTestCase):
"""Tests cancelation of synchronous loading of scripts on Suspend."""
def _LoadPage(self, webdriver, url):
"""Instructs webdriver to navigate to url."""
# Note: The following is a blocking request, and returns only when the
# page has fully loaded. In this test, the page will not fully load
# so, this does not return until Cobalt exits.
except: # pylint: disable=bare-except
def test_simple(self):
# Step 2. Start Cobalt, and point it to the socket created in Step 1.
with ThreadedWebServer(JavascriptRequestDetector,
self.GetBindingAddress()) as server:
with self.CreateCobaltRunner(url='about:blank') as runner:
target_url = server.GetURL(file_name='../testdata/' +
cobalt_launcher_thread = threading.Thread(
args=(self, runner.webdriver, target_url))
# Step 3. Wait HTTP request for html resource.'Waiting for script resource request')
request_received = _received_script_resource_request.wait(
_MAX_ALLOTTED_TIME_SECONDS)'Request received: {}'.format(request_received))
# Step 5. Wait for a request for javascript resource.
# Step 6. Suspend Cobalt process.'Suspending Cobalt.')
# Step 7. Cobalt disconnects from the socket.
# Step 8. Resume Cobalt process, which enables the JS test to pass.'Resuming Cobalt.')
# Step 9. Check to see if JSTestsSucceeded().
# Note that this call will check the DOM multiple times for a period
# of time (current default is 30 seconds).
except: # pylint: disable=bare-except
# Consider an exception being thrown as a test failure.
finally:'Cleaning up.')