#2891 new defect

fix intermittent test coverage — at Version 8

Reported by: warner Owned by:
Priority: normal Milestone: undecided
Component: code Version: 1.12.1
Keywords: Cc:
Launchpad Bug:

Description (last modified by warner)

This ticket is to keep track of lines which sometimes get covered during unit tests and which sometimes do not. This probably happens because those lines are only exercised by "system" -style tests, which randomly hit some servers and not others. We should fix these by writing more narrowly-focussed "unit"-style tests that exercise just the function in question, deterministically.

The most annoying thing about these tests is when they cause perfectly valid pull requests to be flagged as broken (because the test coverage happened to drop when they went through CI, through no fault of the PR's changes).

Let's strikeout these items as we fix them.

  • src/allmydata/mutable/servermap.py
    • ~L 39: UpdateStatus.add_per_server_time~
      • the status object's .timings["per_server"] attribute is a dict-of-lists, and line 39 handles the case where we *don't* have to add a new entry to the dict. This should just be replaced by a collections.defaultdict, rather than needing any new tests.
    • L 923: ServermapUpdater._try_to_validate_privkey
      • this clause checks that the share contained an (encrypted) RSA signing key that matches the expectation we got from the writecap. The clause should succeed for normal shares, but will fail for corrupted shares. Apparently we have a test that corrupts some shares, but which then doesn't always look at them.
  • src/allmydata/immutable/downloader/share.py
    • Share.loop()
      • this share-is-corrupted branch is not always exercised
    • L228-236
      • the DataUnavailable branch is not always exercised
    • L277-279 Share._do_loop()
      • this doesn't always see a non-empty disappointment array, and sometimes doesn't raise DataUnavailable. This is the parent cause of the L228-L236 non-coverage above.
    • L386-389 _satisfy_offsets()
      • the share_hashes_size test doesn't exercise both sides of the branch
    • L761 _got_data()
      • the if not self._alive check doesn't always exercise both branches
  • src/allmydata/stats.py
    • L64-68 LoadMonitor.get_stats()
      • noticed in a build of PR421
      • get_stats() returns an average of the last 60 datapoints, but if there are no datapoints at all, a different branch is taken
      • that no-datapoints branch is sometimes not covered by the tests

Change History (8)

comment:1 Changed at 2017-07-28T04:04:30Z by Brian Warner <warner@…>

In a4be2dc/trunk:

avoid variable coverage by using a defaultdict

refs ticket:2891

comment:2 Changed at 2017-08-10T17:40:23Z by warner

  • Description modified (diff)

added dictutil misses, updated format of the table, struck out the add_per_server_time that was fixed in [a4be2dc]

comment:3 Changed at 2017-08-10T18:40:06Z by Brian Warner <warner@…>

In 3f2f7df/trunk:

dictutil: fix bug in str(ValueOrderedDict?), and improve test coverage

It looks like str() was meant to truncate the dict, but a missing i+=1 meant
that it never actually did. I also changed the format to include a clear
"..." in case we truncate it, to avoid confusion with a non-truncated dict of
the same size.

This also improves test coverage in subtract() and
NumDict?.item_with_largest_value().

refs ticket:2891

comment:4 Changed at 2017-08-10T18:41:50Z by warner

  • Description modified (diff)

fixed dictutil.py (lines 29, 230, 438) with [3f2f7df]

comment:5 Changed at 2017-08-10T20:02:55Z by warner

  • Description modified (diff)

added intermittence from an old build of PR421 (stats.py, web/status.py)

comment:6 Changed at 2017-08-10T21:59:23Z by warner

  • Description modified (diff)

more intermittence noticed in tests: immutable/upload.py and immutable/downloader/share.py

comment:7 Changed at 2017-08-15T21:12:15Z by Brian Warner <warner@…>

In 27348be/trunk:

Merge PR438 from branch '2891-remove-numdict'

This removes some code in dictutil.py that we weren't using, or which could
be replaced by something simpler. This code is troublesome, because our unit
tests only achieve intermittent coverage, so other (unrelated) PRs are
failing CI when the coverage appears to go down.

I tried to improve the tests to reliably cover everything in dictutil.py, and
discovered code that couldn't possibly have worked in the first place. So the
easiest approach was just to delete it all.

refs ticket:2891

comment:8 Changed at 2017-08-15T21:14:24Z by warner

  • Description modified (diff)

[27348be] deleted most of dictutil.py, so those lines are no longer a problem

Note: See TracTickets for help on using tickets.