Skip to content

Instantly share code, notes, and snippets.

@a-seskunas
Last active January 27, 2025 05:16
Show Gist options
  • Select an option

  • Save a-seskunas/fe3fc23adb928deb4507da4e3f6f2b97 to your computer and use it in GitHub Desktop.

Select an option

Save a-seskunas/fe3fc23adb928deb4507da4e3f6f2b97 to your computer and use it in GitHub Desktop.
Write a test from Missing Unit Wiki

LibreOffice - Writing a Test from the MissingUnitTest Wiki.

LibreOffice uses some automation to compile a list of bug reports that have been fixed, but are missing a test. Writing a test for a bug fix in this list is a great way to contribute to the LibreOffice open source project.

A successfully merged test is run in the Continuous Integration pipeline via Jenkins each time a patch is uploaded to Gerrit. This ensures that the original bug is not introduced back into the project in the form of a regression. Below we’ll go through some steps to write a test from this list.

Missing Unit Tests Wiki Imagehttps://wiki.documentfoundation.org/MissingUnitTests

Finding a suitable bug

Not all bugs and bug reports are created equal, so finding a good candidate is crucial to successfully writing a test. Here are some things to think about when looking through bug reports.

  1. Find a bug that is obvious to see, a trivial example of this is a bug that causes LibreOffice to crash. It should be obvious to test for a crash, versus testing for a subtle layout issue.
  2. Look for a bug report that is either very new, or where the bug fix is a limited number of lines of code.
  3. Look for clear steps to reproduce the bug.
  4. It is helpful if the bug fix is confirmed in the bug report. If there is no confirmation, the first thing you should do is run LibreOffice and use the steps listed in the bug report to make sure that the bug is indeed fixed.

We are going to use the bug report from tdf#61000 as an example to go through the process of writing a test from the list. A link to the report can be found below the image.

Bug Report Image
https://bugs.documentfoundation.org/show_bug.cgi?id=61000

Looking at the top comment, you can see that the bug is causing LibreOffice to crash when the attached file is opened. There are clear steps to reproduce the bug in comment 1, and the bug has been confirmed in comment 3.

Reverting the bug fix

Using the commit found in comment 8 of the bug report, we can use git to show the bug fix.

git show dbb74ee9950dc706ea4fde3397a4c1d19b172fa9

commit dbb74ee9950dc706ea4fde3397a4c1d19b172fa9
Author: Michael Stahl <mstahl@redhat.com>
Date:   Wed Feb 27 23:20:24 2013 +0100
fdo#61000: writerfilter: filter out unsupported list tab stops

Change-Id: Ic9d31eba84b1d8d9cf93d8289621a65d43521a8b

diff --git a/writerfilter/source/dmapper/NumberingManager.cxx b/writerfilter/source/dmapper/NumberingManager.cxx index fa59bd2c7062..38b1f07a1c9d 100644 --- a/writerfilter/source/dmapper/NumberingManager.cxx +++ b/writerfilter/source/dmapper/NumberingManager.cxx @@ -135,7 +135,13 @@ void ListLevel::SetValue( Id nId, sal_Int32 nValue ) m_nXChFollow = nValue; break; case NS_ooxml::LN_CT_TabStop_pos: - m_nTabstop = nValue; + if (nValue < 0) + { + SAL_INFO("writerfilter", + "unsupported list tab stop position " << nValue); + } + else + m_nTabstop = nValue; break; default: OSL_FAIL( "this line should never be reached");

We can see that reverting the bug fix is straight forward. The lines that were added can be commented out and the original line that was deleted can be added back to the code.

If you try to open the file listed in the commit to do the edit, you will find that the file is not there. When looking at old commits this can happen, sometimes files get moved, so we can search for the relevant function with

git grep "ListLevel::SetValue"

to get

sw/source/writerfilter/dmapper/NumberingManager.cxx:void ListLevel::SetValue( Id nId, sal_Int32 nValue )

which shows us that the function in question now resides in

sw/source/writerfilter/dmapper/NumberingManager.cxx

Having found the correct file to edit, we get

break;
        case NS_ooxml::LN_CT_TabStop_pos:
            m_nTabstop = nValue;
            #if (nValue < 0)
            #{
                #SAL_INFO("writerfilter",
                        #"unsupported list tab stop position " << nValue);
            #}
            #else
                #m_nTabstop = nValue;
        break;
        default:
            OSL_FAIL( "this line should never be reached");

Compile and Test

The next step is to build with the bug fix reverted and test that the bug is now present. Testing for the bug is simple in this case, just download attachment 1 from the bug report and try to open it with the bug fix reverted.

Once we are sure the bug is reintroduced, it is a good idea to create a branch in git and commit the revert. In this way, you will be able to switch between having the bug present, and not present. Once you have your top commit as the bug fix revert, you can use

git checkout HEAD~

to go back one commit, where the bug is fixed and

git switch - 

to go back to the bug being reintroduced. In this way you can easily and quickly switch the behavior of LibreOffice in order to test, if your test 😆, is working correctly.

Writing the test

Now we need to decide where our test will reside. Since the bug shows when using writer, we will look in sw/qa/extras

accessibility  globalfilter  mailmerge    pdf             tiledrendering2  unowriter
autocorrect    htmlexport    odfexport    README          txtencexport     ww8export
data           htmlimport    odfimport    rtfexport       txtexport        ww8import
docbookexport  indexing      ooxmlexport  rtfimport       txtimport
fodfexport     layout        ooxmlimport  tiledrendering  uiwriter

The README file is very helpful here, I’d encourage anyone writing a test to read it, it contains a lot of helpful information. When deciding where to put a test, a few ideas to keep in mind are:

  1. Take note of the file or area of files the bug fix resides in. In this case, source/writerfilter is a clue that this is an export bug.
  2. What file type are we dealing with? A problem opening up a .docx file would suggest that the test may go in ooxmlexport.
  3. Look for similar tests. Sometimes it can be helpful to look through some of the test suites to see if there are other similar tests.

In this case we’re dealing with a crash when opening a .docx file. This points to ooxmlexport as a good place to put the test.

Writing and executing the test

The last part of the process is to actually write the test. In order to test for a crash, we just open the file and see if LibreOffice crashes.

CPPUNIT_TEST_FIXTURE(Test, testTdf61000)
{
    // Without the fix in place this crashes on opening
    loadAndSave("tdf61000.docx");
    xmlDocUniquePtr pXmlDoc = parseExport(u"word/numbering.xml"_ustr);
    assertXPath(
        pXmlDoc,
        "//w:numbering/w:abstractNum[@w:abstractNumId='1']/w:lvl[@w:ilvl='0']/w:numFmt"_ostr,
        "val"_ostr, u"bullet"_ustr);
    // Without the fix in place, this would be -540, and the abstractNumId is 4
    // The negative value of the tab stop is the culprit for the crash
    assertXPath(
        pXmlDoc,
        "//w:numbering/w:abstractNum[@w:abstractNumId='1']/w:lvl[@w:ilvl='0']/w:pPr/w:tabs/w:tab"_ostr,
        "pos"_ostr, u"0"_ustr);
}

We use loadAndSave to open the file since this is an export test, then we do some checks on the document model using assertXPath. To learn more about using assertXPath you can look in the README file located in
sw/qa/extras/README

Once the test is written and it fails with the bug fix reverted, you can switch back to a state where the bug is fixed and run the test again.

If it now passes, you’ve successfully written a test from the MissingUnitTest wiki 😃 🏆

You would now submit the test as a patch to Gerrit, I won’t go into the details on how to do that here. Follow the link below for more information.
https://wiki.documentfoundation.org/Development/gerrit

For more information about writing tests check, out the Document Foundation Wiki.
https://wiki.documentfoundation.org/Development/Cpp_Unit_Tests

Thanks for reading, I hope this was helpful. Writing a test is great way to learn how to get involved in the LibreOffice project. I’d encourage anyone thinking about contributing to checkout the links above or click the link below for some general information.
https://www.libreoffice.org/community/get-involved/



Written with StackEdit.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment