My favorites | Sign in
v8
Project Home Downloads Wiki Issues Source Code Search
Checkout   Browse   Changes  
Changes to /branches/bleeding_edge/tools/testrunner/server/work_handler.py
r12633 vs. r12635 Compare: vs.  Format:
Revision r12635
Go to: 
Project members, sign in to write a code review
/branches/bleeding_edge/tools/testrunner/server/work_handler.py   r12633 /branches/bleeding_edge/tools/testrunner/server/work_handler.py   r12635
1 # Copyright 2012 the V8 project authors. All rights reserved. 1 # Copyright 2012 the V8 project authors. All rights reserved.
2 # Redistribution and use in source and binary forms, with or without 2 # Redistribution and use in source and binary forms, with or without
3 # modification, are permitted provided that the following conditions are 3 # modification, are permitted provided that the following conditions are
4 # met: 4 # met:
5 # 5 #
6 # * Redistributions of source code must retain the above copyright 6 # * Redistributions of source code must retain the above copyright
7 # notice, this list of conditions and the following disclaimer. 7 # notice, this list of conditions and the following disclaimer.
8 # * Redistributions in binary form must reproduce the above 8 # * Redistributions in binary form must reproduce the above
9 # copyright notice, this list of conditions and the following 9 # copyright notice, this list of conditions and the following
10 # disclaimer in the documentation and/or other materials provided 10 # disclaimer in the documentation and/or other materials provided
11 # with the distribution. 11 # with the distribution.
12 # * Neither the name of Google Inc. nor the names of its 12 # * Neither the name of Google Inc. nor the names of its
13 # contributors may be used to endorse or promote products derived 13 # contributors may be used to endorse or promote products derived
14 # from this software without specific prior written permission. 14 # from this software without specific prior written permission.
15 # 15 #
16 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 16 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 17 # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 18 # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 19 # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 20 # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 21 # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 22 # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 23 # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 25 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 27
28 28
29 import os 29 import os
30 import SocketServer 30 import SocketServer
31 import stat 31 import stat
32 import subprocess 32 import subprocess
33 import threading 33 import threading
34 34
35 from . import compression 35 from . import compression
36 from . import constants 36 from . import constants
37 from . import signatures 37 from . import signatures
38 from ..network import endpoint 38 from ..network import endpoint
39 from ..objects import workpacket 39 from ..objects import workpacket
40 40
41 41
42 class WorkHandler(SocketServer.BaseRequestHandler): 42 class WorkHandler(SocketServer.BaseRequestHandler):
43 43
44 def handle(self): 44 def handle(self):
45 rec = compression.Receiver(self.request) 45 rec = compression.Receiver(self.request)
46 while not rec.IsDone(): 46 while not rec.IsDone():
47 data = rec.Current() 47 data = rec.Current()
48 with self.server.job_lock: 48 with self.server.job_lock:
49 self._WorkOnWorkPacket(data) 49 self._WorkOnWorkPacket(data)
50 rec.Advance() 50 rec.Advance()
51 51
52 def _WorkOnWorkPacket(self, data): 52 def _WorkOnWorkPacket(self, data):
53 server_root = self.server.daemon.root 53 server_root = self.server.daemon.root
54 v8_root = os.path.join(server_root, "v8") 54 v8_root = os.path.join(server_root, "v8")
55 os.chdir(v8_root) 55 os.chdir(v8_root)
56 packet = workpacket.WorkPacket.Unpack(data) 56 packet = workpacket.WorkPacket.Unpack(data)
57 self.ctx = packet.context 57 self.ctx = packet.context
58 self.ctx.shell_dir = os.path.join("out", 58 self.ctx.shell_dir = os.path.join("out",
59 "%s.%s" % (self.ctx.arch, self.ctx.mode)) 59 "%s.%s" % (self.ctx.arch, self.ctx.mode))
60 if not os.path.isdir(self.ctx.shell_dir): 60 if not os.path.isdir(self.ctx.shell_dir):
61 os.makedirs(self.ctx.shell_dir) 61 os.makedirs(self.ctx.shell_dir)
62 for binary in packet.binaries: 62 for binary in packet.binaries:
63 if not self._UnpackBinary(binary, packet.pubkey_fingerprint): 63 if not self._UnpackBinary(binary, packet.pubkey_fingerprint):
64 return 64 return
65 65
66 if not self._CheckoutRevision(packet.base_revision): 66 if not self._CheckoutRevision(packet.base_revision):
67 return 67 return
68 68
69 if not self._ApplyPatch(packet.patch): 69 if not self._ApplyPatch(packet.patch):
70 return 70 return
71 71
72 tests = packet.tests 72 tests = packet.tests
73 endpoint.Execute(v8_root, self.ctx, tests, self.request, self.server.daemon) 73 endpoint.Execute(v8_root, self.ctx, tests, self.request, self.server.daemon)
74 self._SendResponse() 74 self._SendResponse()
75 75
76 def _SendResponse(self, error_message=None): 76 def _SendResponse(self, error_message=None):
77 try: 77 try:
78 if error_message: 78 if error_message:
79 compression.Send([-1, error_message], self.request) 79 compression.Send([-1, error_message], self.request)
80 compression.Send(constants.END_OF_STREAM, self.request) 80 compression.Send(constants.END_OF_STREAM, self.request)
81 return 81 return
82 except Exception, e: 82 except Exception, e:
83 pass # Peer is gone. There's nothing we can do. 83 pass # Peer is gone. There's nothing we can do.
84 # Clean up. 84 # Clean up.
85 self._Call("git checkout -f") 85 self._Call("git checkout -f")
86 self._Call("git clean -f -d") 86 self._Call("git clean -f -d")
87 self._Call("rm -rf %s" % self.ctx.shell_dir) 87 self._Call("rm -rf %s" % self.ctx.shell_dir)
88 88
89 def _UnpackBinary(self, binary, pubkey_fingerprint): 89 def _UnpackBinary(self, binary, pubkey_fingerprint):
90 binary_name = binary["name"] 90 binary_name = binary["name"]
91 if binary_name == "libv8.so": 91 if binary_name == "libv8.so":
92 libdir = os.path.join(self.ctx.shell_dir, "lib.target") 92 libdir = os.path.join(self.ctx.shell_dir, "lib.target")
93 if not os.path.exists(libdir): os.makedirs(libdir) 93 if not os.path.exists(libdir): os.makedirs(libdir)
94 target = os.path.join(libdir, binary_name) 94 target = os.path.join(libdir, binary_name)
95 else: 95 else:
96 target = os.path.join(self.ctx.shell_dir, binary_name) 96 target = os.path.join(self.ctx.shell_dir, binary_name)
97 pubkeyfile = "../trusted/%s.pem" % pubkey_fingerprint 97 pubkeyfile = "../trusted/%s.pem" % pubkey_fingerprint
98 if not signatures.VerifySignature(target, binary["blob"], 98 if not signatures.VerifySignature(target, binary["blob"],
99 binary["sign"], pubkeyfile): 99 binary["sign"], pubkeyfile):
100 self._SendResponse("Signature verification failed") 100 self._SendResponse("Signature verification failed")
101 return False 101 return False
102 os.chmod(target, stat.S_IRWXU) 102 os.chmod(target, stat.S_IRWXU)
103 return True 103 return True
104 104
105 def _CheckoutRevision(self, base_revision): 105 def _CheckoutRevision(self, base_svn_revision):
106 get_hash_cmd = (
107 "git log -1 --format=%%H --remotes --grep='^git-svn-id:.*@%s'" %
108 base_svn_revision)
109 try:
110 base_revision = subprocess.check_output(get_hash_cmd, shell=True)
111 if not base_revision: raise ValueError
112 except:
113 self._Call("git fetch")
114 try:
115 base_revision = subprocess.check_output(get_hash_cmd, shell=True)
116 if not base_revision: raise ValueError
117 except:
118 self._SendResponse("Base revision not found.")
119 return False
106 code = self._Call("git checkout -f %s" % base_revision) 120 code = self._Call("git checkout -f %s" % base_revision)
107 if code != 0: 121 if code != 0:
108 self._Call("git fetch")
109 code = self._Call("git checkout -f %s" % base_revision)
110 if code != 0:
111 self._SendResponse("Error trying to check out base revision.") 122 self._SendResponse("Error trying to check out base revision.")
112 return False 123 return False
113 code = self._Call("git clean -f -d") 124 code = self._Call("git clean -f -d")
114 if code != 0: 125 if code != 0:
115 self._SendResponse("Failed to reset checkout") 126 self._SendResponse("Failed to reset checkout")
116 return False 127 return False
117 return True 128 return True
118 129
119 def _ApplyPatch(self, patch): 130 def _ApplyPatch(self, patch):
120 patchfilename = "_dtest_incoming_patch.patch" 131 patchfilename = "_dtest_incoming_patch.patch"
121 with open(patchfilename, "w") as f: 132 with open(patchfilename, "w") as f:
122 f.write(patch) 133 f.write(patch)
123 code = self._Call("git apply %s" % patchfilename) 134 code = self._Call("git apply %s" % patchfilename)
124 if code != 0: 135 if code != 0:
125 self._SendResponse("Error applying patch.") 136 self._SendResponse("Error applying patch.")
126 return False 137 return False
127 return True 138 return True
128 139
129 def _Call(self, cmd): 140 def _Call(self, cmd):
130 return subprocess.call(cmd, shell=True) 141 return subprocess.call(cmd, shell=True)
131 142
132 143
133 class WorkSocketServer(SocketServer.ThreadingMixIn, SocketServer.TCPServer): 144 class WorkSocketServer(SocketServer.ThreadingMixIn, SocketServer.TCPServer):
134 def __init__(self, daemon): 145 def __init__(self, daemon):
135 address = (daemon.ip, constants.PEER_PORT) 146 address = (daemon.ip, constants.PEER_PORT)
136 SocketServer.TCPServer.__init__(self, address, WorkHandler) 147 SocketServer.TCPServer.__init__(self, address, WorkHandler)
137 self.job_lock = threading.Lock() 148 self.job_lock = threading.Lock()
138 self.daemon = daemon 149 self.daemon = daemon
Powered by Google Project Hosting