Bug 989048 - Clean up emulator temporary files and do not overwrite userdata image. r=ahal, a=test-only
authorTing-Yu Chou <janus926@gmail.com>
Thu, 22 Jan 2015 10:25:18 -0500
changeset 249405 d1b94a06a364471d2626d029473b81f4c7e81403
parent 249404 8347494bd357d27e1b4e08d43cd0c23f418e86b5
child 249406 fd012f26dc946e7ad694ea9ad23288be8ceea60e
push id4489
push userraliiev@mozilla.com
push dateMon, 23 Feb 2015 15:17:55 +0000
treeherdermozilla-beta@fd7c3dc24146 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersahal, test-only
bugs989048
milestone37.0a2
Bug 989048 - Clean up emulator temporary files and do not overwrite userdata image. r=ahal, a=test-only
testing/mozbase/mozrunner/mozrunner/devices/emulator.py
--- a/testing/mozbase/mozrunner/mozrunner/devices/emulator.py
+++ b/testing/mozbase/mozrunner/mozrunner/devices/emulator.py
@@ -46,20 +46,21 @@ class Emulator(Device):
     telnet = None
 
     def __init__(self, app_ctx, arch, resolution=None, sdcard=None, userdata=None,
                  no_window=None, binary=None, **kwargs):
         Device.__init__(self, app_ctx, **kwargs)
 
         self.arch = ArchContext(arch, self.app_ctx, binary=binary)
         self.resolution = resolution or '320x480'
+        self.tmpdir = tempfile.mkdtemp()
         self.sdcard = None
         if sdcard:
             self.sdcard = self.create_sdcard(sdcard)
-        self.userdata = tempfile.NamedTemporaryFile(prefix='qemu-userdata')
+        self.userdata = tempfile.NamedTemporaryFile(prefix='userdata-qemu', dir=self.tmpdir)
         self.initdata = userdata if userdata else os.path.join(self.arch.sysdir, 'userdata.img')
         self.no_window = no_window
 
         self.battery = EmulatorBattery(self)
         self.geo = EmulatorGeo(self)
         self.screen = EmulatorScreen(self)
 
     @property
@@ -89,16 +90,21 @@ class Emulator(Device):
         """
         Starts a new emulator.
         """
         if self.proc:
             return
 
         original_devices = set(self._get_online_devices())
 
+        # QEMU relies on atexit() to remove temporary files, which does not
+        # work since mozprocess uses SIGKILL to kill the emulator process.
+        # Use a customized temporary directory so we can clean it up.
+        os.environ['ANDROID_TMP'] = self.tmpdir
+
         qemu_log = None
         qemu_proc_args = {}
         if self.logdir:
             # save output from qemu to logfile
             qemu_log = os.path.join(self.logdir, 'qemu.log')
             if os.path.isfile(qemu_log):
                 self._rotate_log(qemu_log)
             qemu_proc_args['logfile'] = qemu_log
@@ -140,39 +146,37 @@ class Emulator(Device):
 
     def create_sdcard(self, sdcard_size):
         """
         Creates an sdcard partition in the emulator.
 
         :param sdcard_size: Size of partition to create, e.g '10MB'.
         """
         mksdcard = self.app_ctx.which('mksdcard')
-        path = tempfile.mktemp(prefix='sdcard')
+        path = tempfile.mktemp(prefix='sdcard', dir=self.tmpdir)
         sdargs = [mksdcard, '-l', 'mySdCard', sdcard_size, path]
         sd = subprocess.Popen(sdargs, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
         retcode = sd.wait()
         if retcode:
             raise Exception('unable to create sdcard: exit code %d: %s'
                             % (retcode, sd.stdout.read()))
         return path
 
     def cleanup(self):
         """
         Cleans up and kills the emulator.
         """
         Device.cleanup(self)
         if self.proc:
             self.proc.kill()
             self.proc = None
-        # Remove temporary user data image
-        if self.userdata:
-            self.userdata.close()
-        # Remove temporary sdcard
-        if self.sdcard and os.path.isfile(self.sdcard):
-            os.remove(self.sdcard)
+
+        # Remove temporary files
+        self.userdata.close()
+        shutil.rmtree(self.tmpdir)
 
     # TODO this function is B2G specific and shouldn't live here
     @uses_marionette
     def wait_for_system_message(self, marionette):
         marionette.set_script_timeout(45000)
         # Telephony API's won't be available immediately upon emulator
         # boot; we have to wait for the syste-message-listener-ready
         # message before we'll be able to use them successfully.  See