Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(151)

Side by Side Diff: client/tests/kvm/kvm_monitor.py

Issue 6883035: Merge remote branch 'autotest-upstream/master' into autotest-merge (Closed) Base URL: ssh://gitrw.chromium.org:9222/autotest.git@master
Patch Set: patch Created 9 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 """ 1 """
2 Interfaces to the QEMU monitor. 2 Interfaces to the QEMU monitor.
3 3
4 @copyright: 2008-2010 Red Hat Inc. 4 @copyright: 2008-2010 Red Hat Inc.
5 """ 5 """
6 6
7 import socket, time, threading, logging, select 7 import socket, time, threading, logging, select
8 import kvm_utils 8 import kvm_utils
9 try: 9 try:
10 import json 10 import json
(...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after
169 self.protocol = "human" 169 self.protocol = "human"
170 170
171 # Find the initial (qemu) prompt 171 # Find the initial (qemu) prompt
172 s, o = self._read_up_to_qemu_prompt(20) 172 s, o = self._read_up_to_qemu_prompt(20)
173 if not s: 173 if not s:
174 raise MonitorProtocolError("Could not find (qemu) prompt " 174 raise MonitorProtocolError("Could not find (qemu) prompt "
175 "after connecting to monitor. " 175 "after connecting to monitor. "
176 "Output so far: %r" % o) 176 "Output so far: %r" % o)
177 177
178 # Save the output of 'help' for future use 178 # Save the output of 'help' for future use
179 self._help_str = self.cmd("help") 179 self._help_str = self.cmd("help", debug=False)
180 180
181 except MonitorError, e: 181 except MonitorError, e:
182 if suppress_exceptions: 182 if suppress_exceptions:
183 logging.warn(e) 183 logging.warn(e)
184 else: 184 else:
185 raise 185 raise
186 186
187 187
188 # Private methods 188 # Private methods
189 189
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
221 except socket.error, e: 221 except socket.error, e:
222 raise MonitorSocketError("Could not send monitor command %r" % 222 raise MonitorSocketError("Could not send monitor command %r" %
223 cmd, e) 223 cmd, e)
224 224
225 finally: 225 finally:
226 self._lock.release() 226 self._lock.release()
227 227
228 228
229 # Public methods 229 # Public methods
230 230
231 def cmd(self, command, timeout=20): 231 def cmd(self, command, timeout=20, debug=True):
232 """ 232 """
233 Send command to the monitor. 233 Send command to the monitor.
234 234
235 @param command: Command to send to the monitor 235 @param command: Command to send to the monitor
236 @param timeout: Time duration to wait for the (qemu) prompt to return 236 @param timeout: Time duration to wait for the (qemu) prompt to return
237 @param debug: Whether to print the commands being sent and responses
237 @return: Output received from the monitor 238 @return: Output received from the monitor
238 @raise MonitorLockError: Raised if the lock cannot be acquired 239 @raise MonitorLockError: Raised if the lock cannot be acquired
239 @raise MonitorSocketError: Raised if a socket error occurs 240 @raise MonitorSocketError: Raised if a socket error occurs
240 @raise MonitorProtocolError: Raised if the (qemu) prompt cannot be 241 @raise MonitorProtocolError: Raised if the (qemu) prompt cannot be
241 found after sending the command 242 found after sending the command
242 """ 243 """
244 if debug:
245 logging.debug("(monitor %s) Sending command '%s'",
246 self.name, command)
243 if not self._acquire_lock(20): 247 if not self._acquire_lock(20):
244 raise MonitorLockError("Could not acquire exclusive lock to send " 248 raise MonitorLockError("Could not acquire exclusive lock to send "
245 "monitor command '%s'" % command) 249 "monitor command '%s'" % command)
246 250
247 try: 251 try:
248 # Read any data that might be available 252 # Read any data that might be available
249 self._recvall() 253 self._recvall()
250 # Send command 254 # Send command
251 self._send(command) 255 self._send(command)
252 # Read output 256 # Read output
253 s, o = self._read_up_to_qemu_prompt(timeout) 257 s, o = self._read_up_to_qemu_prompt(timeout)
254 # Remove command echo from output 258 # Remove command echo from output
255 o = "\n".join(o.splitlines()[1:]) 259 o = "\n".join(o.splitlines()[1:])
256 # Report success/failure 260 # Report success/failure
257 if s: 261 if s:
262 if debug and o:
263 logging.debug("(monitor %s) "
264 "Response to '%s'", self.name,
265 command)
266 for l in o.splitlines():
267 logging.debug("(monitor %s) %s", self.name, l)
258 return o 268 return o
259 else: 269 else:
260 msg = ("Could not find (qemu) prompt after command '%s'. " 270 msg = ("Could not find (qemu) prompt after command '%s'. "
261 "Output so far: %r" % (command, o)) 271 "Output so far: %r" % (command, o))
262 raise MonitorProtocolError(msg) 272 raise MonitorProtocolError(msg)
263 273
264 finally: 274 finally:
265 self._lock.release() 275 self._lock.release()
266 276
267 277
268 def verify_responsive(self): 278 def verify_responsive(self):
269 """ 279 """
270 Make sure the monitor is responsive by sending a command. 280 Make sure the monitor is responsive by sending a command.
271 """ 281 """
272 self.cmd("info status") 282 self.cmd("info status", debug=False)
273 283
274 284
275 # Command wrappers 285 # Command wrappers
276 # Notes: 286 # Notes:
277 # - All of the following commands raise exceptions in a similar manner to 287 # - All of the following commands raise exceptions in a similar manner to
278 # cmd(). 288 # cmd().
279 # - A command wrapper should use self._help_str if it requires information 289 # - A command wrapper should use self._help_str if it requires information
280 # about the monitor's capabilities. 290 # about the monitor's capabilities.
281 291
282 def quit(self): 292 def quit(self):
(...skipping 10 matching lines...) Expand all
293 return self.cmd("info %s" % what) 303 return self.cmd("info %s" % what)
294 304
295 305
296 def query(self, what): 306 def query(self, what):
297 """ 307 """
298 Alias for info. 308 Alias for info.
299 """ 309 """
300 return self.info(what) 310 return self.info(what)
301 311
302 312
303 def screendump(self, filename): 313 def screendump(self, filename, debug=True):
304 """ 314 """
305 Request a screendump. 315 Request a screendump.
306 316
307 @param filename: Location for the screendump 317 @param filename: Location for the screendump
308 @return: The command's output 318 @return: The command's output
309 """ 319 """
310 return self.cmd("screendump %s" % filename) 320 return self.cmd(command="screendump %s" % filename, debug=debug)
311 321
312 322
313 def migrate(self, uri, full_copy=False, incremental_copy=False, wait=False): 323 def migrate(self, uri, full_copy=False, incremental_copy=False, wait=False):
314 """ 324 """
315 Migrate. 325 Migrate.
316 326
317 @param uri: destination URI 327 @param uri: destination URI
318 @param full_copy: If true, migrate with full disk copy 328 @param full_copy: If true, migrate with full disk copy
319 @param incremental_copy: If true, migrate with incremental disk copy 329 @param incremental_copy: If true, migrate with incremental disk copy
320 @param wait: If true, wait for completion 330 @param wait: If true, wait for completion
(...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after
507 for obj in self._read_objects(): 517 for obj in self._read_objects():
508 if isinstance(obj, dict): 518 if isinstance(obj, dict):
509 if id is not None and obj.get("id") != id: 519 if id is not None and obj.get("id") != id:
510 continue 520 continue
511 if "return" in obj or "error" in obj: 521 if "return" in obj or "error" in obj:
512 return obj 522 return obj
513 523
514 524
515 # Public methods 525 # Public methods
516 526
517 def cmd(self, cmd, args=None, timeout=20): 527 def cmd(self, cmd, args=None, timeout=20, debug=True):
518 """ 528 """
519 Send a QMP monitor command and return the response. 529 Send a QMP monitor command and return the response.
520 530
521 Note: an id is automatically assigned to the command and the response 531 Note: an id is automatically assigned to the command and the response
522 is checked for the presence of the same id. 532 is checked for the presence of the same id.
523 533
524 @param cmd: Command to send 534 @param cmd: Command to send
525 @param args: A dict containing command arguments, or None 535 @param args: A dict containing command arguments, or None
526 @param timeout: Time duration to wait for response 536 @param timeout: Time duration to wait for response
527 @return: The response received 537 @return: The response received
528 @raise MonitorLockError: Raised if the lock cannot be acquired 538 @raise MonitorLockError: Raised if the lock cannot be acquired
529 @raise MonitorSocketError: Raised if a socket error occurs 539 @raise MonitorSocketError: Raised if a socket error occurs
530 @raise MonitorProtocolError: Raised if no response is received 540 @raise MonitorProtocolError: Raised if no response is received
531 @raise QMPCmdError: Raised if the response is an error message 541 @raise QMPCmdError: Raised if the response is an error message
532 (the exception's args are (cmd, args, data) where data is the 542 (the exception's args are (cmd, args, data) where data is the
533 error data) 543 error data)
534 """ 544 """
545 if debug:
546 logging.debug("(monitor %s) Sending command '%s'",
547 self.name, cmd)
535 if not self._acquire_lock(20): 548 if not self._acquire_lock(20):
536 raise MonitorLockError("Could not acquire exclusive lock to send " 549 raise MonitorLockError("Could not acquire exclusive lock to send "
537 "QMP command '%s'" % cmd) 550 "QMP command '%s'" % cmd)
538 551
539 try: 552 try:
540 # Read any data that might be available 553 # Read any data that might be available
541 self._read_objects() 554 self._read_objects()
542 # Send command 555 # Send command
543 id = kvm_utils.generate_random_string(8) 556 id = kvm_utils.generate_random_string(8)
544 self._send(json.dumps(self._build_cmd(cmd, args, id)) + "\n") 557 self._send(json.dumps(self._build_cmd(cmd, args, id)) + "\n")
545 # Read response 558 # Read response
546 r = self._get_response(id, timeout) 559 r = self._get_response(id, timeout)
547 if r is None: 560 if r is None:
548 raise MonitorProtocolError("Received no response to QMP " 561 raise MonitorProtocolError("Received no response to QMP "
549 "command '%s', or received a " 562 "command '%s', or received a "
550 "response with an incorrect id" 563 "response with an incorrect id"
551 % cmd) 564 % cmd)
552 if "return" in r: 565 if "return" in r:
566 if debug and r["return"]:
567 logging.debug("(monitor %s) "
568 "Response to '%s'", self.name, cmd)
569 o = str(r["return"])
570 for l in o.splitlines():
571 logging.debug("(monitor %s) %s", self.name, l)
553 return r["return"] 572 return r["return"]
554 if "error" in r: 573 if "error" in r:
555 raise QMPCmdError(cmd, args, r["error"]) 574 raise QMPCmdError(cmd, args, r["error"])
556 575
557 finally: 576 finally:
558 self._lock.release() 577 self._lock.release()
559 578
560 579
561 def cmd_raw(self, data, timeout=20): 580 def cmd_raw(self, data, timeout=20):
562 """ 581 """
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
621 @raise MonitorSocketError: Raised if a socket error occurs 640 @raise MonitorSocketError: Raised if a socket error occurs
622 @raise MonitorProtocolError: Raised if no response is received 641 @raise MonitorProtocolError: Raised if no response is received
623 """ 642 """
624 return self.cmd_obj(self._build_cmd(cmd, args, id), timeout) 643 return self.cmd_obj(self._build_cmd(cmd, args, id), timeout)
625 644
626 645
627 def verify_responsive(self): 646 def verify_responsive(self):
628 """ 647 """
629 Make sure the monitor is responsive by sending a command. 648 Make sure the monitor is responsive by sending a command.
630 """ 649 """
631 self.cmd("query-status") 650 self.cmd(cmd="query-status", debug=False)
632 651
633 652
634 def get_events(self): 653 def get_events(self):
635 """ 654 """
636 Return a list of the asynchronous events received since the last 655 Return a list of the asynchronous events received since the last
637 clear_events() call. 656 clear_events() call.
638 657
639 @return: A list of events (the objects returned have an "event" key) 658 @return: A list of events (the objects returned have an "event" key)
640 @raise MonitorLockError: Raised if the lock cannot be acquired 659 @raise MonitorLockError: Raised if the lock cannot be acquired
641 """ 660 """
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
699 return self.cmd("query-%s" % what) 718 return self.cmd("query-%s" % what)
700 719
701 720
702 def query(self, what): 721 def query(self, what):
703 """ 722 """
704 Alias for info. 723 Alias for info.
705 """ 724 """
706 return self.info(what) 725 return self.info(what)
707 726
708 727
709 def screendump(self, filename): 728 def screendump(self, filename, debug=True):
710 """ 729 """
711 Request a screendump. 730 Request a screendump.
712 731
713 @param filename: Location for the screendump 732 @param filename: Location for the screendump
714 @return: The response to the command 733 @return: The response to the command
715 """ 734 """
716 args = {"filename": filename} 735 args = {"filename": filename}
717 return self.cmd("screendump", args) 736 return self.cmd(cmd="screendump", args=args, debug=debug)
718 737
719 738
720 def migrate(self, uri, full_copy=False, incremental_copy=False, wait=False): 739 def migrate(self, uri, full_copy=False, incremental_copy=False, wait=False):
721 """ 740 """
722 Migrate. 741 Migrate.
723 742
724 @param uri: destination URI 743 @param uri: destination URI
725 @param full_copy: If true, migrate with full disk copy 744 @param full_copy: If true, migrate with full disk copy
726 @param incremental_copy: If true, migrate with incremental disk copy 745 @param incremental_copy: If true, migrate with incremental disk copy
727 @param wait: If true, wait for completion 746 @param wait: If true, wait for completion
728 @return: The response to the command 747 @return: The response to the command
729 """ 748 """
730 args = {"uri": uri, 749 args = {"uri": uri,
731 "blk": full_copy, 750 "blk": full_copy,
732 "inc": incremental_copy} 751 "inc": incremental_copy}
733 return self.cmd("migrate", args) 752 return self.cmd("migrate", args)
734 753
735 754
736 def migrate_set_speed(self, value): 755 def migrate_set_speed(self, value):
737 """ 756 """
738 Set maximum speed (in bytes/sec) for migrations. 757 Set maximum speed (in bytes/sec) for migrations.
739 758
740 @param value: Speed in bytes/sec 759 @param value: Speed in bytes/sec
741 @return: The response to the command 760 @return: The response to the command
742 """ 761 """
743 args = {"value": value} 762 args = {"value": value}
744 return self.cmd("migrate_set_speed", args) 763 return self.cmd("migrate_set_speed", args)
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698