summaryrefslogtreecommitdiffstats
path: root/taskcluster/docker/diffoscope
diff options
context:
space:
mode:
Diffstat (limited to 'taskcluster/docker/diffoscope')
-rw-r--r--taskcluster/docker/diffoscope/Dockerfile30
-rw-r--r--taskcluster/docker/diffoscope/get_and_diffoscope140
-rw-r--r--taskcluster/docker/diffoscope/readelf13
3 files changed, 183 insertions, 0 deletions
diff --git a/taskcluster/docker/diffoscope/Dockerfile b/taskcluster/docker/diffoscope/Dockerfile
new file mode 100644
index 0000000000..20d79c016f
--- /dev/null
+++ b/taskcluster/docker/diffoscope/Dockerfile
@@ -0,0 +1,30 @@
+FROM $DOCKER_IMAGE_PARENT
+MAINTAINER Mike Hommey <mhommey@mozilla.com>
+
+VOLUME /builds/worker/checkouts
+VOLUME /builds/worker/workspace
+VOLUME /builds/worker/tooltool-cache
+
+ENV LANG=en_US.UTF-8
+
+RUN apt-get install \
+ binutils-multiarch \
+ bzip2 \
+ curl \
+ enjarify \
+ diffoscope/buster-backports \
+ jsbeautifier \
+ libc++abi1 \
+ locales \
+ default-jdk-headless \
+ python3-progressbar \
+ unzip \
+ zip \
+ && \
+ sed -i '/en_US.UTF-8/s/^# *//' /etc/locale.gen && \
+ locale-gen
+
+COPY get_and_diffoscope /builds/worker/bin/get_and_diffoscope
+COPY readelf /builds/worker/bin/readelf
+
+RUN chown -R worker:worker /builds/worker/bin && chmod 755 /builds/worker/bin/*
diff --git a/taskcluster/docker/diffoscope/get_and_diffoscope b/taskcluster/docker/diffoscope/get_and_diffoscope
new file mode 100644
index 0000000000..7409313275
--- /dev/null
+++ b/taskcluster/docker/diffoscope/get_and_diffoscope
@@ -0,0 +1,140 @@
+#!/bin/bash
+
+set -e
+set -x
+
+cd /builds/worker
+
+mkdir a b
+
+# /builds/worker/bin contains wrapper binaries to divert what diffoscope
+# needs to use, so it needs to appear first.
+export PATH=/builds/worker/bin:$PATH
+
+# Until https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=879010 is
+# implemented, it's better to first manually extract the data.
+# Plus dmg files are not supported yet.
+
+case "$ORIG_URL" in
+*.zip|*.apk)
+ curl -L "$ORIG_URL" > a.zip
+ curl -L "$NEW_URL" > b.zip
+ unzip -d a a.zip
+ unzip -d b b.zip
+ ;;
+*.tar.bz2)
+ curl -L "$ORIG_URL" | tar -C a -jxf -
+ curl -L "$NEW_URL" | tar -C b -jxf -
+ ;;
+*.tar.gz)
+ curl -L "$ORIG_URL" | tar -C a -zxf -
+ curl -L "$NEW_URL" | tar -C b -zxf -
+ ;;
+*.dmg)
+ for tool in lipo otool; do
+ ln -s $MOZ_FETCHES_DIR/cctools/bin/x86_64-apple-darwin*-$tool bin/$tool
+ done
+ curl -L "$ORIG_URL" > a.dmg
+ curl -L "$NEW_URL" > b.dmg
+ for i in a b; do
+ $MOZ_FETCHES_DIR/dmg/dmg extract $i.dmg $i.hfs
+ $MOZ_FETCHES_DIR/dmg/hfsplus $i.hfs extractall / $i
+ done
+ ;;
+*)
+ ARTIFACT=$(basename "${ORIG_URL}")
+ curl -L "$ORIG_URL" > "a/${ARTIFACT}"
+ curl -L "$NEW_URL" > "b/${ARTIFACT}"
+esac
+
+case "$ORIG_URL" in
+*/target.apk)
+ OMNIJAR=assets/omni.ja
+ ;;
+*)
+ OMNIJAR=omni.ja
+ ;;
+esac
+
+report_error() {
+ # We "parse" the diff output, so we look at the lines that contain a "tee", like:
+ # ├── firefox
+ # │ ├── libxul.so
+ # │ │ ├── readelf --wide --notes {}
+ # We ignore lines like the last one, to only report file names. And we ignore
+ # lines for directories such as the first one, but still look at them to report
+ # full paths.
+ python3 <<-EOF
+ TEE = '├──'
+ paths = set()
+ path = []
+ with open("$1.txt") as fh:
+ for l in fh:
+ if TEE not in l:
+ continue
+ fields = l.split()
+ # We rely on the number of │ to figure out at what level the file
+ # name applies.
+ if fields[-2:-1] == [TEE]:
+ path[len(fields) - 2:] = [fields[-1]]
+ else:
+ # Align path length to match the number of │
+ path.append(None)
+ path_ = [p for p in path if p]
+ full_path = '/'.join(path_)
+ parent_path = '/'.join(path_[:-1])
+ if parent_path in paths:
+ paths.remove(parent_path)
+ if full_path:
+ paths.add(full_path)
+
+ for p in sorted(paths):
+ print('TEST-UNEXPECTED-FAIL | {} differs. See the $1.html or $1.txt artifact'.format(p))
+ EOF
+}
+
+# Builds are 99% of the time differing in some small ways, so it's not
+# really useful to report a failure (at least not until we actually
+# care about the builds being 100% identical).
+POST=true
+
+fail() {
+ exit 1
+}
+
+for option; do
+ case "$option" in
+ --unpack)
+ CURDIR=$PWD
+ for dir in a b; do
+ # Need to run mach python from inside the gecko source.
+ # See bug #1533642.
+ (cd $GECKO_PATH && ./mach python --no-virtualenv toolkit/mozapps/installer/unpack.py --omnijar $OMNIJAR $CURDIR/$dir)
+ done
+ ;;
+ --fail)
+ POST="fail"
+ ;;
+ *)
+ echo "Unsupported option: $option" >&2
+ exit 1
+ esac
+done
+
+if [ -n "$PRE_DIFF" ]; then
+ eval $PRE_DIFF
+fi
+
+if diffoscope \
+ --html diff.html \
+ --text diff.txt \
+ --progress \
+ $DIFFOSCOPE_ARGS \
+ a b
+then
+ # Ok
+ :
+else
+ report_error diff
+ $POST
+fi
diff --git a/taskcluster/docker/diffoscope/readelf b/taskcluster/docker/diffoscope/readelf
new file mode 100644
index 0000000000..6b864171d7
--- /dev/null
+++ b/taskcluster/docker/diffoscope/readelf
@@ -0,0 +1,13 @@
+#!/bin/sh
+
+case "$1 $2" in
+"--wide --symbols")
+ # When called with --wide --symbols, we remove the first column (which
+ # is essentially a line number that is not very useful), and then sort,
+ # which will order symbols by address, making a diff more useful.
+ /usr/bin/readelf "$@" | awk -F: '{print $2}' | sort
+ ;;
+*)
+ exec /usr/bin/readelf "$@"
+ ;;
+esac