Bug 989048 - Clean up emulator temporary files and do not overwrite userdata image. r=ahal
authorTing-Yu Chou <janus926@gmail.com>
Fri, 23 Jan 2015 21:55:43 +0800
changeset 225440 3d9457c7d3906feb45bae9fcd1c9cdd2258e72f7
parent 225439 a919a64df9ef5954ba511cc5f6e1d76b209be003
child 225441 bc72d105c8290bf52084ff12071f03dc99a691f1
push id28163
push userphilringnalda@gmail.com
push dateSat, 24 Jan 2015 16:27:39 +0000
treeherdermozilla-central@1cf171c1a177 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersahal
bugs989048
milestone38.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 989048 - Clean up emulator temporary files and do not overwrite userdata image. r=ahal
testing/mozbase/mozrunner/mozrunner/devices/emulator.py
--- a/testing/mozbase/mozrunner/mozrunner/devices/emulator.py
+++ b/testing/mozbase/mozrunner/mozrunner/devices/emulator.py
@@ -46,38 +46,39 @@ 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 = os.path.join(self.arch.sysdir, 'userdata.img')
-        if userdata:
-            self.userdata = tempfile.NamedTemporaryFile(prefix='qemu-userdata')
-            shutil.copyfile(userdata, self.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
     def args(self):
         """
         Arguments to pass into the emulator binary.
         """
         qemu_args = [self.arch.binary,
                      '-kernel', self.arch.kernel,
                      '-sysdir', self.arch.sysdir,
-                     '-data', self.userdata]
+                     '-data', self.userdata.name,
+                     '-initdata', self.initdata,
+                     '-wipe-data']
         if self.no_window:
             qemu_args.append('-no-window')
         if self.sdcard:
             qemu_args.extend(['-sdcard', self.sdcard])
         qemu_args.extend(['-memory', '512',
                           '-partition-size', '512',
                           '-verbose',
                           '-skin', self.resolution,
@@ -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,17 +146,17 @@ 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
 
@@ -158,19 +164,19 @@ class Emulator(Device):
         """
         Cleans up and kills the emulator.
         """
         Device.cleanup(self)
         if self.proc:
             self.proc.kill()
             self.proc = None
 
-        # 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