mozregression – Engineering Productivity Project of the Month

Hello from Engineering Productivity! Once a month we highlight one of our projects to help the Mozilla community discover a useful tool or an interesting contribution opportunity.

This month’s project is mozregression!

Why is mozregression useful ?

mozregression helps to find regressions in Mozilla projects like Firefox or Firefox on Android. It downloads and runs the builds between two dates (or changesets) known to be good and bad, and lets you test each build to finally find by bisection the smallest possible range of changesets where the regression appears.

It does not build locally the application under test, instead, it uses pre-built files, making it fast and easy for everyone to look for the origin of a regression.

Examples:

# Search a Firefox regression in mozilla-central starting from 2016-01-01

mozregression -g 2016-01-01

# Firefox regression, on mozilla-aurora from 2015-09-01 to 2015-10-01

mozregression --repo aurora -g 2015-09-01 -b 2015-10-01

# Look for a regression in fennec (firefox for android)

mozregression --app fennec -g 2015-09-01 -b 2015-10-01

# regression on firefox in inbound, using debug builds and starting from known changesets

mozregression -b 6f4da397ac3c -g eb4dc9b5a928 -B debug --repo inbound

Note that a graphical interface exists also.

Where do I find mozregression ?

Start with:

What are we working on ?

Currently mozregression is improving in multiple areas, among them:

Contributions

William Lachance (:wlach) and myself (:parkouss) are the current maintainers of mozregression.

We welcome contributors! Mike Ling is helping the project for quite some time now, adding useful features and fixing various bugs – he’s currently working on providing ready to use binaries for Mac OS X. A big thanks Mike Ling for your contributions!

Also thanks to Saurabh Singhal and Wasif Hider, who are recent contributors on the graphical user interface.

If you want to contribute as a developer or help us on the documentation, please say hi on the #ateam irc channel!

Reporting bugs / new ideas

You can also help a lot by reporting bugs or new ideas! Please file bugs on bugzilla with the mozregression component:

https://bugzilla.mozilla.org/enter_bug.cgi?product=Testing&component=mozregression

mozregression’s bug list:

https://bugzilla.mozilla.org/buglist.cgi?component=mozregression&bug_status=__open__&product=Testing


For more information about all Engineering Productivity projects visit our wiki. If you’re interested in helping out, the A-Team bootcamp has resources for getting started.

Convert Firefox into Emacs

Firefox is a great browser. One of the reasons I really love it is because it is highly configurable: as an Emacs user, I wanted to use emacs key bindings inside Firefox – well, it’s easy to do that. And much more!

Most of the magic for me comes from the awesome keysnail addon. It basically convert Firefox into Emacs, is also highly configurable and have plugins.

For example, I now use C-x <left> and C-x <right> to switch tabs; C-x b to choose a specific tab (using the Tanything plugin) or C-x k to kill a tab. Tabs are now like Emacs buffers! Keysnail support the mark, incremental search (C-s and C-r), specific functions, … Even M-x is implemented, to search and run specific commands!

Also I use the Find As You Type Firefox feature, for links. It’s awesome: I just hit ‘, then start typing some letters in a link title that I want to follow – I can then use C-s or C-r to find next/previous matching links if needed, then I just press Return to follow the link.

I can browse the web more efficiently, I am less using the mouse and I can reuse the same key bindings in Emacs and Firefox! I keep my configuration files on github, feel free to look at it if you’re interested!

Happy browsing!

mozregression – new way for handling merges

I am currently investigating how we can make mozregression smarter to handle merges, and I will explain how in this post.


Problem

While bisecting builds with mozregression on mozilla-central, we often end up with a merge commit. These commits often incorporate many individual changes, consider for example this url for a merge commit. A regression will be hard to find inside such a large range of commits.


How mozregression currently works

Once we reach a one day range by bisecting mozilla-central or a release branch, we keep the most recent commit tested, and we use that for the end of a new range to bisect mozilla-inbound (or another integration branch, depending on the application) The beginning of that mozilla-inbound range is determined by one commit found 4 days preceding the date of the push of the commit (date pushed on mozilla-central) to be sure we won’t miss any commit in mozilla-central.

But there are multiple problems. First, it is not always the case that the offending commit really comes from m-i. It could be from any other integration branch (fx-team, b2g-inbound, etc). Second, bisecting over a 4 days range in mozilla-inbound may involve testing a lot of builds, with some that are useless to test.


Another approach

How can we improve this ? As just stated, there are two points that can be improved:

  • do not automatically bisect on mozilla-inbound when we finished mozilla-central or a release branch bisection. Merges can comes from fx-team, or another integration branch and this is not really application dependent.
  • try to avoid going back 4 days before the merge when going to the integration branch, there is a loss in productivity since we are likely to test commits that we already tested.

So, how can this be achieved ? Here is my current approach (technical):

  1. Once we are done with the nightlies (one build per day) from a bisection from m-c or any release branch, switch to use taskcluster to download possible builds between. This way we reduce the range to two pushes (one good, one bad) instead of a full day. But since we tested them both, only the commits in the most recent push may contain the regression.
  2. Read the commit message of the top most commit in the most recent push. If it does not looks like a merge commit, then we can’t do anything (maybe this is not a merge, then we are done).
  3. We have a merge push. So now we try to find the exact commits around, on the branch where the merged commits come from.
  4. Bisect this new push range using the changesets and the branch found above, reduce that range and go to 2.

Let’s take an example:

mozregression -g 2015-09-20 -b 2015-10-10

We are bisecting firefox, on mozilla-central. Let’s say we end up with a range 2015-10-01 – 2015-10-02. This is how the pushlog will looks like at the end, 4 pushes and more than 250 changesets.

Now mozregression will automatically reduce the range (still on mozilla-central) by asking you good/bad for those remaining pushes. So, we would end up with two pushes – one we know is good because we tested the top most commit, and the other we know is bad for the same reason. Look at the following pushlog, showing what is still untested (except for the merge commit itself) – 96 commits, coming from m-i.

And then mozregression will detect that it is a merge push from m-i, so automatically it will let you bisect this range of pushes from m-i. That is, our 96 changesets from m-c now converted to testable pushes in m-i. And we will end with a smaller range, for example this one where it will be easy to find our regression because this is one push without any merge.


Comparison

Note that both methods for the example above would have worked. Mainly because we are ending in commits originated from m-i. I tried with another bisection, this time trying to find a commit in fx-team – in that case, current mozregression is simply out – but with the new method it was handled well.

Also using the current method, it would have required around 7 steps after reducing to the one day range for the example above. The new approach can achieve the same with around 5 steps.

Last but not least, this new flow is much more cleaner:

  1. start to bisect from a given branch. Reduce the range to one push on that branch.
  2. if we found a merge, find the branch, the new pushes, and go to 1 to bisect some more with this new data. Else we are done.

Is this applicable ?

Well, it relies on two things. The first one (and we already rely on that a bit currently) is that a merged commit can be found in the branch where it comes from, using the changeset. I have to ask vcs gurus to know if that is reliable, but from my tests this is working well.

Second thing it that we need to detect a merge commit – and from which branch commits comes from. Thanks to the consistency of the sheriffs in their commit messages, this is easy.

Even if it is not applicable everywhere for some reason, it appears that it often works. Using this technique would result in a more accurate and helpful bisection, with speed gain and increased chances to find the root cause of a regression.

This need some more thinking and testing, to determine the limits (what if this doesn’t work ? Should we/can we use the old method in that case ?) but this is definitely something I will explore more to improve the usefulness of mozregression.

mozregression updates!

A lot of new things have been added in mozregression recently, and I think this deserve a blog post.

  • I released mozregression 1.0.0! Plenty of new cool stuff in there, the ability to launch a single build, to choose the build to test after a skipped build (allowing to go back faster in the good/bad perimeter) and other goodies. Well, just try it!
  • A new release for the GUI interface, 0.4.0! So here again, new cool features and a lot of bug fixes. For example, new releases are automatically checked so it will be easy to know when updates are available.
  • mozregression command line is now integrated as a mach command for mozilla developers! You can try “./mach mozregression -h”. I will probably send a mail on dev-platform about that.

Well, big thanks for MikeLing and Jonathan Pigree for their great work on those tools! They are an important part of the team, helping with discussions and patches. Oh, and also a big thanks to users who report bugs and make great proposals: Elbart, Ray Satiro, arni2033, Jukka Jylänki, and all others!

Python [aggressive] pep8 conversion using autopep8

Some time ago, I started to look at Talos, the python performance testing framework for firefox that is usable on Windows, Mac and Linux.

Talos has been around for a long time, and has seen many contributors! Unfortunately the codebase reflects that, and as an example there was simply no common code style around for all the Python files.

Sometimes a 2 spaces based indentation, sometimes 4 spaces based, sometimes something else. No limit for the lines length. This end up with something that is really hard to read, understand and maintain. So one of my first goal was to try to clean this up.

And I heard about autopep8. As the name suggests, this is a tool (command line) that will automatically do some pep8 conversion on Python source files.

Awesome! I highly recommend that to you if you are trying to adapt the coding style of some Python code to pep8 convention, this worked really well for me. This is a pain to do that by hand, and almost impracticable when the indentation needs to be fixed, but autopep8 makes that for you in a safe way.

Tip: the –aggressive flag is really nice for fixing long lines.

So, as an example this is how I used autopep8 on talos:

autopep8 --recursive --in-place --aggressive --aggressive /path/to/talos

Simple and effective. See the usage documentation to see with an example what it really does and other command line flags.

RunSnakeRun – graphical visualisation of dumped python profiling data

If you are a Python developer like me, you probably know the profile and cProfile modules that provides deterministic profiling of Python programs.

These modules are awesome – however, when it comes to analysing the data to improve your program, the provided pstats module is generally not powerful enough if you have quite a large codebase.

And here graphical tools comes in handy! I tried RunSnakeRun, and this is a really great program that allows you to analyse the profiling data under multiple angles (a nice view is by file), so you can find easily the bottlenecks and fix them.

RunSnakeRun helped me to improve the “mach help” command. It is a cross platform tool. Note that if you are on GNU/Linux and that you have the KDE desktop (or don’t mind to install the required KDE dependencies), KCacheGrind can be used with Python also.

Python code cleanup – vulture

I’m pretty sure you all already know about flake8, a great tool that combine other tools (PyFlakes, pep8 and Ned Batchelder’s McCabe script) to check style issues and code errors.

Working on Talos, I needed to find a way to find dead code on the codebase (the less code, the better!). I found a pretty good tool that helped me: vulture. This is a one shot tool – it can not be automated like flake8 as there is some false positives, but still running it once on an old codebase may be a big win to find and remove useless stuff.

Obviously it is easier to use on python programs – you will have to whitelist a lot of things if you run this on a python library that offers a public API.

If you want to seek and destoy dead code on your python program, give it a try!

mozregression-gui first release!

A year from now, I started to contribute to Mozilla. Mozregression (a regression range finder for Mozilla nightly and inbound builds) was one of the first projects that catched my attention: I made one patch, then another, and one again… I was mentored by the awesome William Lachance. Since then, I became one of the core contributors and a packager for mozregression and am now myself mentoring people for new contributions on this project!

At the time of the Google Summer of Code, William and I thought about adding a graphical interface for mozregression. Unfortunately, Mozilla was not accepted for gsoc 2015 – but still the idea was interesting – and we worked on it anyway.

And here we are! Ready for a first release of mozregression-gui! Please give it a try, and help us by reporting bugs and giving feedback. 🙂 For now we provide binaries for Windows and Linux 64 (a Mac port is planned) but it is still possible to build from sources for each platform.

Much work remains to be done on the GUI, and this is a good place to start contributing to Mozilla – so if you’d like to hack with Python and Qt don’t wait and get involved!mozregui