15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#!/usr/bin/env python 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Copyright (c) 2011 The Chromium Authors. All rights reserved. 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Use of this source code is governed by a BSD-style license that can be 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# found in the LICENSE file. 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)"""This functional test spawns a web server, and runs chrome to point 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)at that web server. 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)The content served contains prefetch requests, and the tests assert that the 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)webserver logs reflect that. 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Run like any functional test: 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)$ python chrome/test/functional/prefetch.py 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)in a repo with a built pyautolib 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)The import of multiprocessing implies python 2.6 is required 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)""" 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import os 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import time 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import multiprocessing 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import Queue 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import string 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)from BaseHTTPServer import BaseHTTPRequestHandler, HTTPServer 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import pyauto_functional # Must be imported before pyauto 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import pyauto 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# this class handles IPC retrieving server "logs" from our integral 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# server. Each test should clear() the log, and then run asserts on 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# the retrieval list. 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# at startup, the server puts an int in the queue which is its port, 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# we store that for subsequent tests 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class ServerLog: 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def clear(self): 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.log = {} 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def __init__(self,queue): 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.clear() 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.port = None 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.queue = queue 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def _readQueue(self): 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) try: 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while True: 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) queueval = self.queue.get(False) 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if isinstance(queueval,int): 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.port = queueval 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else: 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.log[queueval] = True 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) except Queue.Empty: 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def getPort(self): 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if not self.port: 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self._readQueue() 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return self.port 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def isRetrieved(self,path): 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self._readQueue() 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) try: 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return self.log[path] 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) except KeyError: 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return None 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# The next few classes run a simple web server that returns log information 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# via a multiprocessing.Queue. 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class AbstractPrefetchServerHandler(BaseHTTPRequestHandler): 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content = { 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "prefetch-origin.html": 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (200, """<html><head> 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)<link rel="prefetch" href="static-prefetch-target.html"> 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)<script type="text/javascript"> 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)function changeParagraph() 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) var newPara = document.createElement("p"); 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) newPara.innerHTML = 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "<link rel=\\"prefetch\\" href=\\"dynamic-prefetch-target.html\\">" + 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "<p>This paragraph contains a dynamic link prefetch. " + 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "The target of this prefetch is " + 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "<a href=\\"dynamic-prefetch-target.html\\">this document.</a>"; 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) var para = document.getElementById("p1"); 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) document.body.insertBefore(newPara,para); 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)</script> 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)</head> 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)<body onload="changeParagraph()"> 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)<p id="p1">This is a document that contains a link prefetch. The target of 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)that prefetch is <a href="static-prefetch-target.html">this document.</a> 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)</body>"""), 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "static-prefetch-target.html": 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (200, "<html><head></head><body>empty</body>"), 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "dynamic-prefetch-target.html": 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (200, "<html><head></head><body>empty</body>")} 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def do_GET(self): 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.queue.put(self.path[1:]) 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) try: 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) response_code, response = self.content[self.path[1:]] 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.send_response(response_code) 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.end_headers() 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.wfile.write(response) 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) except KeyError: 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.send_response(404) 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.end_headers() 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)def run_web_server(queue_arg): 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) class PrefetchServerHandler(AbstractPrefetchServerHandler): 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) queue = queue_arg 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) server = HTTPServer(('',0), PrefetchServerHandler) 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) queue.put(server.server_port) 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) server.serve_forever() 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Here's the test itself 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)queue = multiprocessing.Queue() 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)server_log = ServerLog(queue) 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class PrefetchTest(pyauto.PyUITest): 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) """Testcase for Prefetching""" 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def testBasic(self): 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) server_log.clear() 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) url = "http://localhost:%d/prefetch-origin.html" % server_log.getPort() 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.NavigateToURL(url) 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.assertEqual(True, server_log.isRetrieved("prefetch-origin.html")) 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) time.sleep(0.1) # required since prefetches occur after onload 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.assertEqual(True, server_log.isRetrieved( 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "static-prefetch-target.html")) 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.assertEqual(True, server_log.isRetrieved( 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "dynamic-prefetch-target.html")) 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)if __name__ == '__main__': 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) web_server = multiprocessing.Process(target=run_web_server,args=(queue,)) 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) web_server.daemon = True 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) web_server.start() 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pyauto_functional.Main() 142