966747: handle a custom facts file being empty

json.loads("") throws a ValueError, so handle that
case

Add log.info about which custom facts we are loading.

Split up custom cache loading into a few methods, so
we can test them easier, and add corresponding tests.

Add lots more tests to test_facts.py, and fix up some
of the issue found.

Handle facts cache file not existing, being empty, or
otherwise failing to load so Facts.has_changed does
the right thing.