Bug 1565332 - change how pulseaudio is initialized for Debian 10 test image without affecting existing Ubuntu 16.04 process r=jlund,dustin
authorEdwin Takahashi <egao@mozilla.com>
Mon, 21 Oct 2019 16:34:43 +0000
changeset 498401 fd0d2f3403803d8a66ceb55595ca5a2202d858e9
parent 498400 c67e0b10b52fc8e6b17591b77fee324cac2fc38d
child 498402 563f437f24b9e12495b0f2c364538a2b8d8a0ca7
child 498403 5686e9cc48b26a8ec550f94091d5b8b4ed840f7d
push id36717
push usernbeleuzu@mozilla.com
push dateMon, 21 Oct 2019 21:51:55 +0000
treeherdermozilla-central@563f437f24b9 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjlund, dustin
bugs1565332
milestone71.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 1565332 - change how pulseaudio is initialized for Debian 10 test image without affecting existing Ubuntu 16.04 process r=jlund,dustin Changes: - for Debian platforms, do not initialize pulseaudio in `test-linux.sh`; instead initialize pulseaudio if required in the `desktop_unittest.py` mozharness script Differential Revision: https://phabricator.services.mozilla.com/D45768
taskcluster/docker/debian10-test/dot-files/pulse/default.pa
taskcluster/scripts/tester/test-linux.sh
testing/mozharness/mozharness/base/python.py
testing/mozharness/mozharness/base/script.py
testing/mozharness/scripts/desktop_unittest.py
deleted file mode 100644
--- a/taskcluster/docker/debian10-test/dot-files/pulse/default.pa
+++ /dev/null
@@ -1,164 +0,0 @@
-#!/usr/bin/pulseaudio -nF
-#
-# This file is part of PulseAudio.
-#
-# PulseAudio is free software; you can redistribute it and/or modify it
-# under the terms of the GNU Lesser General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# PulseAudio is distributed in the hope that it will be useful, but
-# WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public License
-# along with PulseAudio; if not, write to the Free Software Foundation,
-# Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
-
-# This startup script is used only if PulseAudio is started per-user
-# (i.e. not in system mode)
-
-.nofail
-
-### Load something into the sample cache
-#load-sample-lazy x11-bell /usr/share/sounds/gtk-events/activate.wav
-#load-sample-lazy pulse-hotplug /usr/share/sounds/startup3.wav
-#load-sample-lazy pulse-coldplug /usr/share/sounds/startup3.wav
-#load-sample-lazy pulse-access /usr/share/sounds/generic.wav
-
-.fail
-
-### Automatically restore the volume of streams and devices
-load-module module-device-restore
-load-module module-stream-restore
-load-module module-card-restore
-
-### Automatically augment property information from .desktop files
-### stored in /usr/share/application
-load-module module-augment-properties
-
-### Load audio drivers statically
-### (it's probably better to not load these drivers manually, but instead
-### use module-udev-detect -- see below -- for doing this automatically)
-#load-module module-alsa-sink
-#load-module module-alsa-source device=hw:1,0
-#load-module module-oss device="/dev/dsp" sink_name=output source_name=input
-#load-module module-oss-mmap device="/dev/dsp" sink_name=output source_name=input
-#load-module module-null-sink
-#load-module module-pipe-sink
-
-### Automatically load driver modules depending on the hardware available
-.ifexists module-udev-detect.so
-load-module module-udev-detect
-.else
-### Use the static hardware detection module (for systems that lack udev/hal support)
-load-module module-detect
-.endif
-
-### Automatically connect sink and source if JACK server is present
-.ifexists module-jackdbus-detect.so
-.nofail
-load-module module-jackdbus-detect
-.fail
-.endif
-
-### Automatically load driver modules for Bluetooth hardware
-# This module causes a pulseaudio startup failure on "gecko-tester"
-#.ifexists module-bluetooth-discover.so
-#load-module module-bluetooth-discover
-#.endif
-
-### Load several protocols
-.ifexists module-esound-protocol-unix.so
-load-module module-esound-protocol-unix
-.endif
-load-module module-native-protocol-unix
-
-### Network access (may be configured with paprefs, so leave this commented
-### here if you plan to use paprefs)
-#load-module module-esound-protocol-tcp
-#load-module module-native-protocol-tcp
-#load-module module-zeroconf-publish
-
-### Load the RTP receiver module (also configured via paprefs, see above)
-#load-module module-rtp-recv
-
-### Load the RTP sender module (also configured via paprefs, see above)
-#load-module module-null-sink sink_name=rtp format=s16be channels=2 rate=44100 sink_properties="device.description='RTP Multicast Sink'"
-#load-module module-rtp-send source=rtp.monitor
-
-### Load additional modules from GConf settings. This can be configured with the paprefs tool.
-### Please keep in mind that the modules configured by paprefs might conflict with manually
-### loaded modules.
-.ifexists module-gconf.so
-.nofail
-load-module module-gconf
-.fail
-.endif
-
-### Automatically restore the default sink/source when changed by the user
-### during runtime
-### NOTE: This should be loaded as early as possible so that subsequent modules
-### that look up the default sink/source get the right value
-load-module module-default-device-restore
-
-### Automatically move streams to the default sink if the sink they are
-### connected to dies, similar for sources
-load-module module-rescue-streams
-
-### Make sure we always have a sink around, even if it is a null sink.
-load-module module-always-sink
-
-### Honour intended role device property
-load-module module-intended-roles
-
-### Automatically suspend sinks/sources that become idle for too long
-load-module module-suspend-on-idle
-
-### If autoexit on idle is enabled we want to make sure we only quit
-### when no local session needs us anymore.
-# This module causes a pulseaudio startup failure on "gecko-tester"
-#.ifexists module-console-kit.so
-#load-module module-console-kit
-#.endif
-
-### Enable positioned event sounds
-load-module module-position-event-sounds
-
-### Cork music streams when a phone stream is active
-#load-module module-cork-music-on-phone
-
-### Modules to allow autoloading of filters (such as echo cancellation)
-### on demand. module-filter-heuristics tries to determine what filters
-### make sense, and module-filter-apply does the heavy-lifting of
-### loading modules and rerouting streams.
-load-module module-filter-heuristics
-load-module module-filter-apply
-
-### Load DBus protocol
-#.ifexists module-dbus-protocol.so
-#load-module module-dbus-protocol
-#.endif
-
-# X11 modules should not be started from default.pa so that one daemon
-# can be shared by multiple sessions.
-
-### Load X11 bell module
-#load-module module-x11-bell sample=bell-windowing-system
-
-### Register ourselves in the X11 session manager
-#load-module module-x11-xsmp
-
-### Publish connection data in the X11 root window
-#.ifexists module-x11-publish.so
-#.nofail
-#load-module module-x11-publish
-#.fail
-#.endif
-
-load-module module-switch-on-port-available
-
-### Make some devices default
-#set-default-sink output
-#set-default-source input
--- a/taskcluster/scripts/tester/test-linux.sh
+++ b/taskcluster/scripts/tester/test-linux.sh
@@ -44,43 +44,19 @@ fail() {
     echo # make sure error message is on a new line
     echo "[test-linux.sh:error]" "${@}"
     exit 1
 }
 
 # start pulseaudio
 maybe_start_pulse() {
     if $NEED_PULSEAUDIO; then
-        # call pulseaudio with varying parameters
+        # call pulseaudio for Ubuntu only
         if [ $DISTRIBUTION == "Ubuntu" ]; then
             pulseaudio --fail --daemonize --start
-        elif [ $DISTRIBUTION == "Debian" ]; then
-            # temporarily turn errexit off
-            # nicely kill existing daemons/processes if exist
-            set +e
-            pulseaudio --kill
-
-            # Debian needs additional stabilization and debugging
-            ps ax | grep 'pulseaudio'
-            ps -ef | grep 'pulseaudio' | grep -v grep | awk '{print $2}' | xargs -r kill -9
-            ps ax | grep 'pulseaudio'
-
-            # check and start pulseaudio with debugging
-            pulseaudio --check; echo $?
-            pulseaudio --fail --daemonize --start -vvvv --exit-idle-time=-1 --log-level=4 --log-time=1
-            set -e
-        else
-            :
-        fi
-
-        pulseaudio --check
-        if [ $? -eq 0 ]; then
-            echo "Pulseaudio successfully initialized"
-        else
-            echo "Pulseaudio failed to initialize, trying again"
         fi
     fi
 }
 
 # test required parameters are supplied
 if [ -z "${MOZHARNESS_PATH}" -a -z "${MOZHARNESS_URL}" ]; then
     fail "MOZHARNESS_PATH or MOZHARNESS_URL must be defined";
 fi
@@ -167,16 +143,17 @@ if $NEED_WINDOW_MANAGER; then
     # XXX: it would be ideal to add a semaphore logic to make sure that the
     # window manager is ready
     /etc/X11/Xsession 2>&1 &
 
     # Turn off the screen saver and screen locking
     gsettings set org.gnome.desktop.screensaver idle-activation-enabled false
     gsettings set org.gnome.desktop.screensaver lock-enabled false
     gsettings set org.gnome.desktop.screensaver lock-delay 3600
+
     # Disable the screen saver
     xset s off s reset
 
     # This starts the gnome-keyring-daemon with an unlocked login keyring. libsecret uses this to
     # store secrets. Firefox uses libsecret to store a key that protects sensitive information like
     # credit card numbers.
     if test -z "$DBUS_SESSION_BUS_ADDRESS" ; then
         # if not found, launch a new one
@@ -188,22 +165,16 @@ fi
 if $NEED_COMPIZ; then
     if [ $DISTRIBUTION == "Ubuntu" ]; then
         compiz 2>&1 &
     fi
 fi
 
 maybe_start_pulse
 
-if $NEED_PULSEAUDIO; then
-    # Load null-sink using pactl, and if it was successful.
-    pactl load-module module-null-sink
-    pactl list modules short
-fi
-
 # For telemetry purposes, the build process wants information about the
 # source it is running
 export MOZ_SOURCE_REPO="${GECKO_HEAD_REPOSITORY}"
 export MOZ_SOURCE_CHANGESET="${GECKO_HEAD_REV}"
 
 # support multiple, space delimited, config files
 config_cmds=""
 for cfg in $MOZHARNESS_CONFIG; do
--- a/testing/mozharness/mozharness/base/python.py
+++ b/testing/mozharness/mozharness/base/python.py
@@ -360,17 +360,17 @@ class VirtualenvMixin(object):
         ]
         virtualenv_options = c.get('virtualenv_options', [])
         # Creating symlinks in the virtualenv may cause issues during
         # virtualenv creation or operation on non-Redhat derived
         # distros. On Redhat derived distros --always-copy causes
         # imports to fail. See
         # https://github.com/pypa/virtualenv/issues/565. Therefore
         # only use --alway-copy when not using Redhat.
-        if self._is_redhat():
+        if self._is_redhat_based():
             self.warning("creating virtualenv without --always-copy "
                          "due to issues on Redhat derived distros")
         else:
             virtualenv_options.append('--always-copy')
 
         if os.path.exists(self.query_python_path()):
             self.info(
                 "Virtualenv %s appears to already exist; "
--- a/testing/mozharness/mozharness/base/script.py
+++ b/testing/mozharness/mozharness/base/script.py
@@ -114,17 +114,30 @@ class PlatformMixin(object):
         Returns:
             bool: True if the current platform is a Linux distro, False otherwise
         """
         if platform.system() in ("Linux"):
             return True
         if sys.platform.startswith("linux"):
             return True
 
-    def _is_redhat(self):
+    def _is_debian(self):
+        """ check if the current operating system is explicitly Debian.
+        This intentionally doesn't count Debian derivatives like Ubuntu.
+
+        Returns:
+            bool: True if the current platform is debian, False otherwise
+        """
+        if not self._is_linux():
+            return False
+        self.info(mozinfo.linux_distro)
+        re_debian_distro = re.compile('debian')
+        return re_debian_distro.match(mozinfo.linux_distro) is not None
+
+    def _is_redhat_based(self):
         """ check if the current operating system is a Redhat derived Linux distribution.
 
         Returns:
             bool: True if the current platform is a Redhat Linux distro, False otherwise
         """
         if not self._is_linux():
             return False
         re_redhat_distro = re.compile('Redhat|Fedora|CentOS|Oracle')
--- a/testing/mozharness/scripts/desktop_unittest.py
+++ b/testing/mozharness/scripts/desktop_unittest.py
@@ -191,16 +191,17 @@ class DesktopUnittest(TestingMixin, Merc
         # abs_dirs defined already in BaseScript but is here to make pylint happy
         self.abs_dirs = None
         super(DesktopUnittest, self).__init__(
             config_options=self.config_options,
             all_actions=[
                 'clobber',
                 'download-and-extract',
                 'create-virtualenv',
+                'start-pulseaudio',
                 'install',
                 'stage-files',
                 'run-tests',
             ],
             require_config_file=require_config_file,
             config={'require_test_zip': True})
 
         c = self.config
@@ -604,16 +605,37 @@ class DesktopUnittest(TestingMixin, Merc
         if c.get('run_all_suites'):
             target_categories = SUITE_CATEGORIES
         else:
             target_categories = [cat for cat in SUITE_CATEGORIES
                                  if self._query_specified_suites(cat) is not None]
         super(DesktopUnittest, self).download_and_extract(extract_dirs=extract_dirs,
                                                           suite_categories=target_categories)
 
+    def start_pulseaudio(self):
+        command = []
+        if (os.environ.get('NEED_PULSEAUDIO') == 'true' and self._is_debian()):
+            # Debian platform requires additional idle timer specification so
+            # that it will not terminate the process on its own.
+            command.extend([
+                'pulseaudio',
+                '--daemonize',
+                '--log-level=4',
+                '--log-time=1',
+                '-vvvvv',
+                '--exit-idle-time=-1'
+            ])
+
+        # Instantiate pulseaudio.
+        if self._is_debian():
+            self._kill_named_proc('pulseaudio')
+            self.run_command(command)
+        self.run_command('pactl load-module module-null-sink')
+        self.run_command('pactl list modules short')
+
     def stage_files(self):
         for category in SUITE_CATEGORIES:
             suites = self._query_specified_suites(category)
             stage = getattr(self, '_stage_{}'.format(category), None)
             if suites and stage:
                 stage(suites)
 
     def _stage_files(self, bin_name=None):