def test_file_write_and_restore(self):
     filename = _temp_filename()
     _setup_file(filename)
     ch = JsonFileLicenseCache(filename)
     self.assertIsNone(ch.read("not there"))
     self.assertEqual(ch.read("one"), LicenseReportEntry(package="one"))
     self.assertEqual(ch.read("two"), LicenseReportEntry(package="two"))
예제 #2
0
 def test_github_recognizer(self):
     recognizers.recognize_all(self.entries, [self.github])
     self.assertEqual(7, len(self.entries))
     self.assertTrue(
         _matches(
             self.entries[0],
             LicenseReportEntry(
                 package='github.com/Azure/go-ansiterm',
                 license_name='MIT License',
                 license_url=
                 'https://raw.githubusercontent.com/Azure/go-ansiterm/master/LICENSE',
                 license_encoded=
                 'VGhlIE1JVCBMaWNlbnNlIChNSVQpCgpDb3B5cmlnaHQgKGMpIDIwMTUgTWlj\ncm9zb2Z0IENvcnBvcmF0aW9uCgpQZXJtaXNzaW9uIGlzIGhlcmVieSBncmFu\ndGVkLCBmcmVlIG9mIGNoYXJnZSwgdG8gYW55IHBlcnNvbiBvYnRhaW5pbmcg\nYSBjb3B5Cm9mIHRoaXMgc29mdHdhcmUgYW5kIGFzc29jaWF0ZWQgZG9jdW1l\nbnRhdGlvbiBmaWxlcyAodGhlICJTb2Z0d2FyZSIpLCB0byBkZWFsCmluIHRo\nZSBTb2Z0d2FyZSB3aXRob3V0IHJlc3RyaWN0aW9uLCBpbmNsdWRpbmcgd2l0\naG91dCBsaW1pdGF0aW9uIHRoZSByaWdodHMKdG8gdXNlLCBjb3B5LCBtb2Rp\nZnksIG1lcmdlLCBwdWJsaXNoLCBkaXN0cmlidXRlLCBzdWJsaWNlbnNlLCBh\nbmQvb3Igc2VsbApjb3BpZXMgb2YgdGhlIFNvZnR3YXJlLCBhbmQgdG8gcGVy\nbWl0IHBlcnNvbnMgdG8gd2hvbSB0aGUgU29mdHdhcmUgaXMKZnVybmlzaGVk\nIHRvIGRvIHNvLCBzdWJqZWN0IHRvIHRoZSBmb2xsb3dpbmcgY29uZGl0aW9u\nczoKClRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1p\nc3Npb24gbm90aWNlIHNoYWxsIGJlIGluY2x1ZGVkIGluCmFsbCBjb3BpZXMg\nb3Igc3Vic3RhbnRpYWwgcG9ydGlvbnMgb2YgdGhlIFNvZnR3YXJlLgoKVEhF\nIFNPRlRXQVJFIElTIFBST1ZJREVEICJBUyBJUyIsIFdJVEhPVVQgV0FSUkFO\nVFkgT0YgQU5ZIEtJTkQsIEVYUFJFU1MgT1IKSU1QTElFRCwgSU5DTFVESU5H\nIEJVVCBOT1QgTElNSVRFRCBUTyBUSEUgV0FSUkFOVElFUyBPRiBNRVJDSEFO\nVEFCSUxJVFksCkZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFO\nRCBOT05JTkZSSU5HRU1FTlQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRQpBVVRI\nT1JTIE9SIENPUFlSSUdIVCBIT0xERVJTIEJFIExJQUJMRSBGT1IgQU5ZIENM\nQUlNLCBEQU1BR0VTIE9SIE9USEVSCkxJQUJJTElUWSwgV0hFVEhFUiBJTiBB\nTiBBQ1RJT04gT0YgQ09OVFJBQ1QsIFRPUlQgT1IgT1RIRVJXSVNFLCBBUklT\nSU5HIEZST00sCk9VVCBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFNP\nRlRXQVJFIE9SIFRIRSBVU0UgT1IgT1RIRVIgREVBTElOR1MgSU4KVEhFIFNP\nRlRXQVJFLgo=\n',
                 license_recognized_at='...something...',
                 license_recognizer_name='GitHubRecognizer')))
     self.assertEqual(self.entries[1],
                      LicenseReportEntry(package='mybsd/package1'))
     self.assertEqual(self.entries[2],
                      LicenseReportEntry(package='mymit/package1'))
     self.assertEqual(self.entries[3],
                      LicenseReportEntry(package='mymit/package2'))
     self.assertEqual(self.entries[4],
                      LicenseReportEntry(package='mymit/package3'))
     self.assertEqual(
         self.entries[5],
         LicenseReportEntry(package='myserver1.com/continuity'))
     self.assertEqual(self.entries[6],
                      LicenseReportEntry(package='myserver2.com/backoff'))
    def test_cache_read_and_write(self):
        ch = JsonFileLicenseCache("/tmp/no-file-needed-for-this-test")
        self.assertIsNone(ch.read("my package name"))

        ch.write(
            LicenseReportEntry(package="my package name",
                               license_name="license"))
        self.assertEqual(
            ch.read("my package name"),
            LicenseReportEntry(package="my package name",
                               license_name="license"))

        l = ch.read("my package name")
        l.license_url = "http://no.such.machine/"
        ch.write(l)
        self.assertEqual(
            ch.read("my package name"),
            LicenseReportEntry(package="my package name",
                               license_name="license",
                               license_url="http://no.such.machine/"))
예제 #4
0
def _initial_entries() -> List[LicenseReportEntry]:
    return [
        LicenseReportEntry(package='github.com/Azure/go-ansiterm'),
        LicenseReportEntry(package='mybsd/package1'),
        LicenseReportEntry(package='mymit/package1'),
        LicenseReportEntry(package='mymit/package2'),
        LicenseReportEntry(package='mymit/package3'),
        LicenseReportEntry(package='myserver1.com/continuity'),
        LicenseReportEntry(package='myserver2.com/backoff')
    ]
예제 #5
0
    def test_json_report(self):
        entries = [
            LicenseReportEntry(
                package='cloud.google.com',
                license_name='Apache License 2.0',
                license_url='http://www.apache.org/licenses/LICENSE-2.0.txt'),
            LicenseReportEntry(
                package='github.com/Azure/go-ansiterm',
                license_name='MIT License',
                license_url=
                'https://raw.githubusercontent.com/Azure/go-ansiterm/master/LICENSE'
            ),
            LicenseReportEntry(
                package='github.com/Flaque/filet',
                license_name='Apache License 2.0',
                license_url='http://www.apache.org/licenses/LICENSE-2.0.txt'),
            LicenseReportEntry(
                package='github.com/cenkalti/backoff',
                license_name='MIT License',
                license_url=
                'https://raw.githubusercontent.com/cenkalti/backoff/v3/LICENSE'
            ),
            LicenseReportEntry(
                package='github.com/client9/misspell',
                license_name='MIT License',
                license_url=
                'https://raw.githubusercontent.com/client9/misspell/master/LICENSE'
            )
        ]
        unaccepted = [
            LicenseReportEntry(
                package='cloud.google.com',
                license_name='Apache License 2.0',
                license_url='http://www.apache.org/licenses/LICENSE-2.0.txt'),
            LicenseReportEntry(
                package='github.com/Flaque/filet',
                license_name='Apache License 2.0',
                license_url='http://www.apache.org/licenses/LICENSE-2.0.txt')
        ]

        filename = _temp_filename()
        reporters.report_all(entries, unaccepted,
                             [reporters.JsonReporter(filename)])

        with open(filename) as json_file:
            data = json.load(json_file)

        self.assertEqual(1, len(data))
        self.assertEqual(data['dependencies'], _CORRECT_LICENSE_ARRAY)
예제 #6
0
 def test_common_prefix_recognizer(self):
     recognizers.recognize_all(self.entries, [self.mit, self.bsd])
     self.assertEqual(7, len(self.entries))
     self.assertEqual(
         self.entries[0],
         LicenseReportEntry(package='github.com/Azure/go-ansiterm'))
     self.assertTrue(
         _matches(
             self.entries[1],
             LicenseReportEntry(
                 package='mybsd/package1',
                 license_name='BSD',
                 license_url='my_bsd_url',
                 license_recognized_at='...something...',
                 license_recognizer_name='CommonPrefixRecognizer(mybsd/)')))
     self.assertTrue(
         _matches(
             self.entries[2],
             LicenseReportEntry(
                 package='mymit/package1',
                 license_name='MIT',
                 license_url='my_mit_url',
                 license_recognized_at='...something...',
                 license_recognizer_name='CommonPrefixRecognizer(mymit/)')))
     self.assertTrue(
         _matches(
             self.entries[3],
             LicenseReportEntry(
                 package='mymit/package2',
                 license_name='MIT',
                 license_url='my_mit_url',
                 license_recognized_at='...something...',
                 license_recognizer_name='CommonPrefixRecognizer(mymit/)')))
     self.assertTrue(
         _matches(
             self.entries[4],
             LicenseReportEntry(
                 package='mymit/package3',
                 license_name='MIT',
                 license_url='my_mit_url',
                 license_recognized_at='...something...',
                 license_recognizer_name='CommonPrefixRecognizer(mymit/)')))
     self.assertEqual(
         self.entries[5],
         LicenseReportEntry(package='myserver1.com/continuity'))
     self.assertEqual(self.entries[6],
                      LicenseReportEntry(package='myserver2.com/backoff'))
예제 #7
0
 def test_no_recognizer(self):
     recognizers.recognize_all(self.entries, [])
     self.assertEqual(7, len(self.entries))
     self.assertEqual(
         self.entries[0],
         LicenseReportEntry(package='github.com/Azure/go-ansiterm'))
     self.assertEqual(self.entries[1],
                      LicenseReportEntry(package='mybsd/package1'))
     self.assertEqual(self.entries[2],
                      LicenseReportEntry(package='mymit/package1'))
     self.assertEqual(self.entries[3],
                      LicenseReportEntry(package='mymit/package2'))
     self.assertEqual(self.entries[4],
                      LicenseReportEntry(package='mymit/package3'))
     self.assertEqual(
         self.entries[5],
         LicenseReportEntry(package='myserver1.com/continuity'))
     self.assertEqual(self.entries[6],
                      LicenseReportEntry(package='myserver2.com/backoff'))
예제 #8
0
 def test_mapping_recognizer(self):
     recognizers.recognize_all(self.entries, [self.mapped])
     self.assertEqual(7, len(self.entries))
     self.assertEqual(
         self.entries[0],
         LicenseReportEntry(package='github.com/Azure/go-ansiterm'))
     self.assertEqual(self.entries[1],
                      LicenseReportEntry(package='mybsd/package1'))
     self.assertEqual(self.entries[2],
                      LicenseReportEntry(package='mymit/package1'))
     self.assertEqual(self.entries[3],
                      LicenseReportEntry(package='mymit/package2'))
     self.assertEqual(self.entries[4],
                      LicenseReportEntry(package='mymit/package3'))
     self.assertTrue(
         _matches(
             self.entries[5],
             LicenseReportEntry(
                 package='myserver1.com/continuity',
                 license_name='Apache License 2.0',
                 license_url=
                 'https://raw.githubusercontent.com/containerd/continuity/master/LICENSE',
                 license_encoded=
                 'CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEFwYWNoZSBMaWNl\nbnNlCiAgICAgICAgICAgICAgICAgICAgICAgICAgIFZlcnNpb24gMi4wLCBK\nYW51YXJ5IDIwMDQKICAgICAgICAgICAgICAgICAgICAgICAgaHR0cHM6Ly93\nd3cuYXBhY2hlLm9yZy9saWNlbnNlcy8KCiAgIFRFUk1TIEFORCBDT05ESVRJ\nT05TIEZPUiBVU0UsIFJFUFJPRFVDVElPTiwgQU5EIERJU1RSSUJVVElPTgoK\nICAgMS4gRGVmaW5pdGlvbnMuCgogICAgICAiTGljZW5zZSIgc2hhbGwgbWVh\nbiB0aGUgdGVybXMgYW5kIGNvbmRpdGlvbnMgZm9yIHVzZSwgcmVwcm9kdWN0\naW9uLAogICAgICBhbmQgZGlzdHJpYnV0aW9uIGFzIGRlZmluZWQgYnkgU2Vj\ndGlvbnMgMSB0aHJvdWdoIDkgb2YgdGhpcyBkb2N1bWVudC4KCiAgICAgICJM\naWNlbnNvciIgc2hhbGwgbWVhbiB0aGUgY29weXJpZ2h0IG93bmVyIG9yIGVu\ndGl0eSBhdXRob3JpemVkIGJ5CiAgICAgIHRoZSBjb3B5cmlnaHQgb3duZXIg\ndGhhdCBpcyBncmFudGluZyB0aGUgTGljZW5zZS4KCiAgICAgICJMZWdhbCBF\nbnRpdHkiIHNoYWxsIG1lYW4gdGhlIHVuaW9uIG9mIHRoZSBhY3RpbmcgZW50\naXR5IGFuZCBhbGwKICAgICAgb3RoZXIgZW50aXRpZXMgdGhhdCBjb250cm9s\nLCBhcmUgY29udHJvbGxlZCBieSwgb3IgYXJlIHVuZGVyIGNvbW1vbgogICAg\nICBjb250cm9sIHdpdGggdGhhdCBlbnRpdHkuIEZvciB0aGUgcHVycG9zZXMg\nb2YgdGhpcyBkZWZpbml0aW9uLAogICAgICAiY29udHJvbCIgbWVhbnMgKGkp\nIHRoZSBwb3dlciwgZGlyZWN0IG9yIGluZGlyZWN0LCB0byBjYXVzZSB0aGUK\nICAgICAgZGlyZWN0aW9uIG9yIG1hbmFnZW1lbnQgb2Ygc3VjaCBlbnRpdHks\nIHdoZXRoZXIgYnkgY29udHJhY3Qgb3IKICAgICAgb3RoZXJ3aXNlLCBvciAo\naWkpIG93bmVyc2hpcCBvZiBmaWZ0eSBwZXJjZW50ICg1MCUpIG9yIG1vcmUg\nb2YgdGhlCiAgICAgIG91dHN0YW5kaW5nIHNoYXJlcywgb3IgKGlpaSkgYmVu\nZWZpY2lhbCBvd25lcnNoaXAgb2Ygc3VjaCBlbnRpdHkuCgogICAgICAiWW91\nIiAob3IgIllvdXIiKSBzaGFsbCBtZWFuIGFuIGluZGl2aWR1YWwgb3IgTGVn\nYWwgRW50aXR5CiAgICAgIGV4ZXJjaXNpbmcgcGVybWlzc2lvbnMgZ3JhbnRl\nZCBieSB0aGlzIExpY2Vuc2UuCgogICAgICAiU291cmNlIiBmb3JtIHNoYWxs\nIG1lYW4gdGhlIHByZWZlcnJlZCBmb3JtIGZvciBtYWtpbmcgbW9kaWZpY2F0\naW9ucywKICAgICAgaW5jbHVkaW5nIGJ1dCBub3QgbGltaXRlZCB0byBzb2Z0\nd2FyZSBzb3VyY2UgY29kZSwgZG9jdW1lbnRhdGlvbgogICAgICBzb3VyY2Us\nIGFuZCBjb25maWd1cmF0aW9uIGZpbGVzLgoKICAgICAgIk9iamVjdCIgZm9y\nbSBzaGFsbCBtZWFuIGFueSBmb3JtIHJlc3VsdGluZyBmcm9tIG1lY2hhbmlj\nYWwKICAgICAgdHJhbnNmb3JtYXRpb24gb3IgdHJhbnNsYXRpb24gb2YgYSBT\nb3VyY2UgZm9ybSwgaW5jbHVkaW5nIGJ1dAogICAgICBub3QgbGltaXRlZCB0\nbyBjb21waWxlZCBvYmplY3QgY29kZSwgZ2VuZXJhdGVkIGRvY3VtZW50YXRp\nb24sCiAgICAgIGFuZCBjb252ZXJzaW9ucyB0byBvdGhlciBtZWRpYSB0eXBl\ncy4KCiAgICAgICJXb3JrIiBzaGFsbCBtZWFuIHRoZSB3b3JrIG9mIGF1dGhv\ncnNoaXAsIHdoZXRoZXIgaW4gU291cmNlIG9yCiAgICAgIE9iamVjdCBmb3Jt\nLCBtYWRlIGF2YWlsYWJsZSB1bmRlciB0aGUgTGljZW5zZSwgYXMgaW5kaWNh\ndGVkIGJ5IGEKICAgICAgY29weXJpZ2h0IG5vdGljZSB0aGF0IGlzIGluY2x1\nZGVkIGluIG9yIGF0dGFjaGVkIHRvIHRoZSB3b3JrCiAgICAgIChhbiBleGFt\ncGxlIGlzIHByb3ZpZGVkIGluIHRoZSBBcHBlbmRpeCBiZWxvdykuCgogICAg\nICAiRGVyaXZhdGl2ZSBXb3JrcyIgc2hhbGwgbWVhbiBhbnkgd29yaywgd2hl\ndGhlciBpbiBTb3VyY2Ugb3IgT2JqZWN0CiAgICAgIGZvcm0sIHRoYXQgaXMg\nYmFzZWQgb24gKG9yIGRlcml2ZWQgZnJvbSkgdGhlIFdvcmsgYW5kIGZvciB3\naGljaCB0aGUKICAgICAgZWRpdG9yaWFsIHJldmlzaW9ucywgYW5ub3RhdGlv\nbnMsIGVsYWJvcmF0aW9ucywgb3Igb3RoZXIgbW9kaWZpY2F0aW9ucwogICAg\nICByZXByZXNlbnQsIGFzIGEgd2hvbGUsIGFuIG9yaWdpbmFsIHdvcmsgb2Yg\nYXV0aG9yc2hpcC4gRm9yIHRoZSBwdXJwb3NlcwogICAgICBvZiB0aGlzIExp\nY2Vuc2UsIERlcml2YXRpdmUgV29ya3Mgc2hhbGwgbm90IGluY2x1ZGUgd29y\na3MgdGhhdCByZW1haW4KICAgICAgc2VwYXJhYmxlIGZyb20sIG9yIG1lcmVs\neSBsaW5rIChvciBiaW5kIGJ5IG5hbWUpIHRvIHRoZSBpbnRlcmZhY2VzIG9m\nLAogICAgICB0aGUgV29yayBhbmQgRGVyaXZhdGl2ZSBXb3JrcyB0aGVyZW9m\nLgoKICAgICAgIkNvbnRyaWJ1dGlvbiIgc2hhbGwgbWVhbiBhbnkgd29yayBv\nZiBhdXRob3JzaGlwLCBpbmNsdWRpbmcKICAgICAgdGhlIG9yaWdpbmFsIHZl\ncnNpb24gb2YgdGhlIFdvcmsgYW5kIGFueSBtb2RpZmljYXRpb25zIG9yIGFk\nZGl0aW9ucwogICAgICB0byB0aGF0IFdvcmsgb3IgRGVyaXZhdGl2ZSBXb3Jr\ncyB0aGVyZW9mLCB0aGF0IGlzIGludGVudGlvbmFsbHkKICAgICAgc3VibWl0\ndGVkIHRvIExpY2Vuc29yIGZvciBpbmNsdXNpb24gaW4gdGhlIFdvcmsgYnkg\ndGhlIGNvcHlyaWdodCBvd25lcgogICAgICBvciBieSBhbiBpbmRpdmlkdWFs\nIG9yIExlZ2FsIEVudGl0eSBhdXRob3JpemVkIHRvIHN1Ym1pdCBvbiBiZWhh\nbGYgb2YKICAgICAgdGhlIGNvcHlyaWdodCBvd25lci4gRm9yIHRoZSBwdXJw\nb3NlcyBvZiB0aGlzIGRlZmluaXRpb24sICJzdWJtaXR0ZWQiCiAgICAgIG1l\nYW5zIGFueSBmb3JtIG9mIGVsZWN0cm9uaWMsIHZlcmJhbCwgb3Igd3JpdHRl\nbiBjb21tdW5pY2F0aW9uIHNlbnQKICAgICAgdG8gdGhlIExpY2Vuc29yIG9y\nIGl0cyByZXByZXNlbnRhdGl2ZXMsIGluY2x1ZGluZyBidXQgbm90IGxpbWl0\nZWQgdG8KICAgICAgY29tbXVuaWNhdGlvbiBvbiBlbGVjdHJvbmljIG1haWxp\nbmcgbGlzdHMsIHNvdXJjZSBjb2RlIGNvbnRyb2wgc3lzdGVtcywKICAgICAg\nYW5kIGlzc3VlIHRyYWNraW5nIHN5c3RlbXMgdGhhdCBhcmUgbWFuYWdlZCBi\neSwgb3Igb24gYmVoYWxmIG9mLCB0aGUKICAgICAgTGljZW5zb3IgZm9yIHRo\nZSBwdXJwb3NlIG9mIGRpc2N1c3NpbmcgYW5kIGltcHJvdmluZyB0aGUgV29y\naywgYnV0CiAgICAgIGV4Y2x1ZGluZyBjb21tdW5pY2F0aW9uIHRoYXQgaXMg\nY29uc3BpY3VvdXNseSBtYXJrZWQgb3Igb3RoZXJ3aXNlCiAgICAgIGRlc2ln\nbmF0ZWQgaW4gd3JpdGluZyBieSB0aGUgY29weXJpZ2h0IG93bmVyIGFzICJO\nb3QgYSBDb250cmlidXRpb24uIgoKICAgICAgIkNvbnRyaWJ1dG9yIiBzaGFs\nbCBtZWFuIExpY2Vuc29yIGFuZCBhbnkgaW5kaXZpZHVhbCBvciBMZWdhbCBF\nbnRpdHkKICAgICAgb24gYmVoYWxmIG9mIHdob20gYSBDb250cmlidXRpb24g\naGFzIGJlZW4gcmVjZWl2ZWQgYnkgTGljZW5zb3IgYW5kCiAgICAgIHN1YnNl\ncXVlbnRseSBpbmNvcnBvcmF0ZWQgd2l0aGluIHRoZSBXb3JrLgoKICAgMi4g\nR3JhbnQgb2YgQ29weXJpZ2h0IExpY2Vuc2UuIFN1YmplY3QgdG8gdGhlIHRl\ncm1zIGFuZCBjb25kaXRpb25zIG9mCiAgICAgIHRoaXMgTGljZW5zZSwgZWFj\naCBDb250cmlidXRvciBoZXJlYnkgZ3JhbnRzIHRvIFlvdSBhIHBlcnBldHVh\nbCwKICAgICAgd29ybGR3aWRlLCBub24tZXhjbHVzaXZlLCBuby1jaGFyZ2Us\nIHJveWFsdHktZnJlZSwgaXJyZXZvY2FibGUKICAgICAgY29weXJpZ2h0IGxp\nY2Vuc2UgdG8gcmVwcm9kdWNlLCBwcmVwYXJlIERlcml2YXRpdmUgV29ya3Mg\nb2YsCiAgICAgIHB1YmxpY2x5IGRpc3BsYXksIHB1YmxpY2x5IHBlcmZvcm0s\nIHN1YmxpY2Vuc2UsIGFuZCBkaXN0cmlidXRlIHRoZQogICAgICBXb3JrIGFu\nZCBzdWNoIERlcml2YXRpdmUgV29ya3MgaW4gU291cmNlIG9yIE9iamVjdCBm\nb3JtLgoKICAgMy4gR3JhbnQgb2YgUGF0ZW50IExpY2Vuc2UuIFN1YmplY3Qg\ndG8gdGhlIHRlcm1zIGFuZCBjb25kaXRpb25zIG9mCiAgICAgIHRoaXMgTGlj\nZW5zZSwgZWFjaCBDb250cmlidXRvciBoZXJlYnkgZ3JhbnRzIHRvIFlvdSBh\nIHBlcnBldHVhbCwKICAgICAgd29ybGR3aWRlLCBub24tZXhjbHVzaXZlLCBu\nby1jaGFyZ2UsIHJveWFsdHktZnJlZSwgaXJyZXZvY2FibGUKICAgICAgKGV4\nY2VwdCBhcyBzdGF0ZWQgaW4gdGhpcyBzZWN0aW9uKSBwYXRlbnQgbGljZW5z\nZSB0byBtYWtlLCBoYXZlIG1hZGUsCiAgICAgIHVzZSwgb2ZmZXIgdG8gc2Vs\nbCwgc2VsbCwgaW1wb3J0LCBhbmQgb3RoZXJ3aXNlIHRyYW5zZmVyIHRoZSBX\nb3JrLAogICAgICB3aGVyZSBzdWNoIGxpY2Vuc2UgYXBwbGllcyBvbmx5IHRv\nIHRob3NlIHBhdGVudCBjbGFpbXMgbGljZW5zYWJsZQogICAgICBieSBzdWNo\nIENvbnRyaWJ1dG9yIHRoYXQgYXJlIG5lY2Vzc2FyaWx5IGluZnJpbmdlZCBi\neSB0aGVpcgogICAgICBDb250cmlidXRpb24ocykgYWxvbmUgb3IgYnkgY29t\nYmluYXRpb24gb2YgdGhlaXIgQ29udHJpYnV0aW9uKHMpCiAgICAgIHdpdGgg\ndGhlIFdvcmsgdG8gd2hpY2ggc3VjaCBDb250cmlidXRpb24ocykgd2FzIHN1\nYm1pdHRlZC4gSWYgWW91CiAgICAgIGluc3RpdHV0ZSBwYXRlbnQgbGl0aWdh\ndGlvbiBhZ2FpbnN0IGFueSBlbnRpdHkgKGluY2x1ZGluZyBhCiAgICAgIGNy\nb3NzLWNsYWltIG9yIGNvdW50ZXJjbGFpbSBpbiBhIGxhd3N1aXQpIGFsbGVn\naW5nIHRoYXQgdGhlIFdvcmsKICAgICAgb3IgYSBDb250cmlidXRpb24gaW5j\nb3Jwb3JhdGVkIHdpdGhpbiB0aGUgV29yayBjb25zdGl0dXRlcyBkaXJlY3QK\nICAgICAgb3IgY29udHJpYnV0b3J5IHBhdGVudCBpbmZyaW5nZW1lbnQsIHRo\nZW4gYW55IHBhdGVudCBsaWNlbnNlcwogICAgICBncmFudGVkIHRvIFlvdSB1\nbmRlciB0aGlzIExpY2Vuc2UgZm9yIHRoYXQgV29yayBzaGFsbCB0ZXJtaW5h\ndGUKICAgICAgYXMgb2YgdGhlIGRhdGUgc3VjaCBsaXRpZ2F0aW9uIGlzIGZp\nbGVkLgoKICAgNC4gUmVkaXN0cmlidXRpb24uIFlvdSBtYXkgcmVwcm9kdWNl\nIGFuZCBkaXN0cmlidXRlIGNvcGllcyBvZiB0aGUKICAgICAgV29yayBvciBE\nZXJpdmF0aXZlIFdvcmtzIHRoZXJlb2YgaW4gYW55IG1lZGl1bSwgd2l0aCBv\nciB3aXRob3V0CiAgICAgIG1vZGlmaWNhdGlvbnMsIGFuZCBpbiBTb3VyY2Ug\nb3IgT2JqZWN0IGZvcm0sIHByb3ZpZGVkIHRoYXQgWW91CiAgICAgIG1lZXQg\ndGhlIGZvbGxvd2luZyBjb25kaXRpb25zOgoKICAgICAgKGEpIFlvdSBtdXN0\nIGdpdmUgYW55IG90aGVyIHJlY2lwaWVudHMgb2YgdGhlIFdvcmsgb3IKICAg\nICAgICAgIERlcml2YXRpdmUgV29ya3MgYSBjb3B5IG9mIHRoaXMgTGljZW5z\nZTsgYW5kCgogICAgICAoYikgWW91IG11c3QgY2F1c2UgYW55IG1vZGlmaWVk\nIGZpbGVzIHRvIGNhcnJ5IHByb21pbmVudCBub3RpY2VzCiAgICAgICAgICBz\ndGF0aW5nIHRoYXQgWW91IGNoYW5nZWQgdGhlIGZpbGVzOyBhbmQKCiAgICAg\nIChjKSBZb3UgbXVzdCByZXRhaW4sIGluIHRoZSBTb3VyY2UgZm9ybSBvZiBh\nbnkgRGVyaXZhdGl2ZSBXb3JrcwogICAgICAgICAgdGhhdCBZb3UgZGlzdHJp\nYnV0ZSwgYWxsIGNvcHlyaWdodCwgcGF0ZW50LCB0cmFkZW1hcmssIGFuZAog\nICAgICAgICAgYXR0cmlidXRpb24gbm90aWNlcyBmcm9tIHRoZSBTb3VyY2Ug\nZm9ybSBvZiB0aGUgV29yaywKICAgICAgICAgIGV4Y2x1ZGluZyB0aG9zZSBu\nb3RpY2VzIHRoYXQgZG8gbm90IHBlcnRhaW4gdG8gYW55IHBhcnQgb2YKICAg\nICAgICAgIHRoZSBEZXJpdmF0aXZlIFdvcmtzOyBhbmQKCiAgICAgIChkKSBJ\nZiB0aGUgV29yayBpbmNsdWRlcyBhICJOT1RJQ0UiIHRleHQgZmlsZSBhcyBw\nYXJ0IG9mIGl0cwogICAgICAgICAgZGlzdHJpYnV0aW9uLCB0aGVuIGFueSBE\nZXJpdmF0aXZlIFdvcmtzIHRoYXQgWW91IGRpc3RyaWJ1dGUgbXVzdAogICAg\nICAgICAgaW5jbHVkZSBhIHJlYWRhYmxlIGNvcHkgb2YgdGhlIGF0dHJpYnV0\naW9uIG5vdGljZXMgY29udGFpbmVkCiAgICAgICAgICB3aXRoaW4gc3VjaCBO\nT1RJQ0UgZmlsZSwgZXhjbHVkaW5nIHRob3NlIG5vdGljZXMgdGhhdCBkbyBu\nb3QKICAgICAgICAgIHBlcnRhaW4gdG8gYW55IHBhcnQgb2YgdGhlIERlcml2\nYXRpdmUgV29ya3MsIGluIGF0IGxlYXN0IG9uZQogICAgICAgICAgb2YgdGhl\nIGZvbGxvd2luZyBwbGFjZXM6IHdpdGhpbiBhIE5PVElDRSB0ZXh0IGZpbGUg\nZGlzdHJpYnV0ZWQKICAgICAgICAgIGFzIHBhcnQgb2YgdGhlIERlcml2YXRp\ndmUgV29ya3M7IHdpdGhpbiB0aGUgU291cmNlIGZvcm0gb3IKICAgICAgICAg\nIGRvY3VtZW50YXRpb24sIGlmIHByb3ZpZGVkIGFsb25nIHdpdGggdGhlIERl\ncml2YXRpdmUgV29ya3M7IG9yLAogICAgICAgICAgd2l0aGluIGEgZGlzcGxh\neSBnZW5lcmF0ZWQgYnkgdGhlIERlcml2YXRpdmUgV29ya3MsIGlmIGFuZAog\nICAgICAgICAgd2hlcmV2ZXIgc3VjaCB0aGlyZC1wYXJ0eSBub3RpY2VzIG5v\ncm1hbGx5IGFwcGVhci4gVGhlIGNvbnRlbnRzCiAgICAgICAgICBvZiB0aGUg\nTk9USUNFIGZpbGUgYXJlIGZvciBpbmZvcm1hdGlvbmFsIHB1cnBvc2VzIG9u\nbHkgYW5kCiAgICAgICAgICBkbyBub3QgbW9kaWZ5IHRoZSBMaWNlbnNlLiBZ\nb3UgbWF5IGFkZCBZb3VyIG93biBhdHRyaWJ1dGlvbgogICAgICAgICAgbm90\naWNlcyB3aXRoaW4gRGVyaXZhdGl2ZSBXb3JrcyB0aGF0IFlvdSBkaXN0cmli\ndXRlLCBhbG9uZ3NpZGUKICAgICAgICAgIG9yIGFzIGFuIGFkZGVuZHVtIHRv\nIHRoZSBOT1RJQ0UgdGV4dCBmcm9tIHRoZSBXb3JrLCBwcm92aWRlZAogICAg\nICAgICAgdGhhdCBzdWNoIGFkZGl0aW9uYWwgYXR0cmlidXRpb24gbm90aWNl\ncyBjYW5ub3QgYmUgY29uc3RydWVkCiAgICAgICAgICBhcyBtb2RpZnlpbmcg\ndGhlIExpY2Vuc2UuCgogICAgICBZb3UgbWF5IGFkZCBZb3VyIG93biBjb3B5\ncmlnaHQgc3RhdGVtZW50IHRvIFlvdXIgbW9kaWZpY2F0aW9ucyBhbmQKICAg\nICAgbWF5IHByb3ZpZGUgYWRkaXRpb25hbCBvciBkaWZmZXJlbnQgbGljZW5z\nZSB0ZXJtcyBhbmQgY29uZGl0aW9ucwogICAgICBmb3IgdXNlLCByZXByb2R1\nY3Rpb24sIG9yIGRpc3RyaWJ1dGlvbiBvZiBZb3VyIG1vZGlmaWNhdGlvbnMs\nIG9yCiAgICAgIGZvciBhbnkgc3VjaCBEZXJpdmF0aXZlIFdvcmtzIGFzIGEg\nd2hvbGUsIHByb3ZpZGVkIFlvdXIgdXNlLAogICAgICByZXByb2R1Y3Rpb24s\nIGFuZCBkaXN0cmlidXRpb24gb2YgdGhlIFdvcmsgb3RoZXJ3aXNlIGNvbXBs\naWVzIHdpdGgKICAgICAgdGhlIGNvbmRpdGlvbnMgc3RhdGVkIGluIHRoaXMg\nTGljZW5zZS4KCiAgIDUuIFN1Ym1pc3Npb24gb2YgQ29udHJpYnV0aW9ucy4g\nVW5sZXNzIFlvdSBleHBsaWNpdGx5IHN0YXRlIG90aGVyd2lzZSwKICAgICAg\nYW55IENvbnRyaWJ1dGlvbiBpbnRlbnRpb25hbGx5IHN1Ym1pdHRlZCBmb3Ig\naW5jbHVzaW9uIGluIHRoZSBXb3JrCiAgICAgIGJ5IFlvdSB0byB0aGUgTGlj\nZW5zb3Igc2hhbGwgYmUgdW5kZXIgdGhlIHRlcm1zIGFuZCBjb25kaXRpb25z\nIG9mCiAgICAgIHRoaXMgTGljZW5zZSwgd2l0aG91dCBhbnkgYWRkaXRpb25h\nbCB0ZXJtcyBvciBjb25kaXRpb25zLgogICAgICBOb3R3aXRoc3RhbmRpbmcg\ndGhlIGFib3ZlLCBub3RoaW5nIGhlcmVpbiBzaGFsbCBzdXBlcnNlZGUgb3Ig\nbW9kaWZ5CiAgICAgIHRoZSB0ZXJtcyBvZiBhbnkgc2VwYXJhdGUgbGljZW5z\nZSBhZ3JlZW1lbnQgeW91IG1heSBoYXZlIGV4ZWN1dGVkCiAgICAgIHdpdGgg\nTGljZW5zb3IgcmVnYXJkaW5nIHN1Y2ggQ29udHJpYnV0aW9ucy4KCiAgIDYu\nIFRyYWRlbWFya3MuIFRoaXMgTGljZW5zZSBkb2VzIG5vdCBncmFudCBwZXJt\naXNzaW9uIHRvIHVzZSB0aGUgdHJhZGUKICAgICAgbmFtZXMsIHRyYWRlbWFy\na3MsIHNlcnZpY2UgbWFya3MsIG9yIHByb2R1Y3QgbmFtZXMgb2YgdGhlIExp\nY2Vuc29yLAogICAgICBleGNlcHQgYXMgcmVxdWlyZWQgZm9yIHJlYXNvbmFi\nbGUgYW5kIGN1c3RvbWFyeSB1c2UgaW4gZGVzY3JpYmluZyB0aGUKICAgICAg\nb3JpZ2luIG9mIHRoZSBXb3JrIGFuZCByZXByb2R1Y2luZyB0aGUgY29udGVu\ndCBvZiB0aGUgTk9USUNFIGZpbGUuCgogICA3LiBEaXNjbGFpbWVyIG9mIFdh\ncnJhbnR5LiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IK\nICAgICAgYWdyZWVkIHRvIGluIHdyaXRpbmcsIExpY2Vuc29yIHByb3ZpZGVz\nIHRoZSBXb3JrIChhbmQgZWFjaAogICAgICBDb250cmlidXRvciBwcm92aWRl\ncyBpdHMgQ29udHJpYnV0aW9ucykgb24gYW4gIkFTIElTIiBCQVNJUywKICAg\nICAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJ\nTkQsIGVpdGhlciBleHByZXNzIG9yCiAgICAgIGltcGxpZWQsIGluY2x1ZGlu\nZywgd2l0aG91dCBsaW1pdGF0aW9uLCBhbnkgd2FycmFudGllcyBvciBjb25k\naXRpb25zCiAgICAgIG9mIFRJVExFLCBOT04tSU5GUklOR0VNRU5ULCBNRVJD\nSEFOVEFCSUxJVFksIG9yIEZJVE5FU1MgRk9SIEEKICAgICAgUEFSVElDVUxB\nUiBQVVJQT1NFLiBZb3UgYXJlIHNvbGVseSByZXNwb25zaWJsZSBmb3IgZGV0\nZXJtaW5pbmcgdGhlCiAgICAgIGFwcHJvcHJpYXRlbmVzcyBvZiB1c2luZyBv\nciByZWRpc3RyaWJ1dGluZyB0aGUgV29yayBhbmQgYXNzdW1lIGFueQogICAg\nICByaXNrcyBhc3NvY2lhdGVkIHdpdGggWW91ciBleGVyY2lzZSBvZiBwZXJt\naXNzaW9ucyB1bmRlciB0aGlzIExpY2Vuc2UuCgogICA4LiBMaW1pdGF0aW9u\nIG9mIExpYWJpbGl0eS4gSW4gbm8gZXZlbnQgYW5kIHVuZGVyIG5vIGxlZ2Fs\nIHRoZW9yeSwKICAgICAgd2hldGhlciBpbiB0b3J0IChpbmNsdWRpbmcgbmVn\nbGlnZW5jZSksIGNvbnRyYWN0LCBvciBvdGhlcndpc2UsCiAgICAgIHVubGVz\ncyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyAoc3VjaCBhcyBkZWxpYmVy\nYXRlIGFuZCBncm9zc2x5CiAgICAgIG5lZ2xpZ2VudCBhY3RzKSBvciBhZ3Jl\nZWQgdG8gaW4gd3JpdGluZywgc2hhbGwgYW55IENvbnRyaWJ1dG9yIGJlCiAg\nICAgIGxpYWJsZSB0byBZb3UgZm9yIGRhbWFnZXMsIGluY2x1ZGluZyBhbnkg\nZGlyZWN0LCBpbmRpcmVjdCwgc3BlY2lhbCwKICAgICAgaW5jaWRlbnRhbCwg\nb3IgY29uc2VxdWVudGlhbCBkYW1hZ2VzIG9mIGFueSBjaGFyYWN0ZXIgYXJp\nc2luZyBhcyBhCiAgICAgIHJlc3VsdCBvZiB0aGlzIExpY2Vuc2Ugb3Igb3V0\nIG9mIHRoZSB1c2Ugb3IgaW5hYmlsaXR5IHRvIHVzZSB0aGUKICAgICAgV29y\nayAoaW5jbHVkaW5nIGJ1dCBub3QgbGltaXRlZCB0byBkYW1hZ2VzIGZvciBs\nb3NzIG9mIGdvb2R3aWxsLAogICAgICB3b3JrIHN0b3BwYWdlLCBjb21wdXRl\nciBmYWlsdXJlIG9yIG1hbGZ1bmN0aW9uLCBvciBhbnkgYW5kIGFsbAogICAg\nICBvdGhlciBjb21tZXJjaWFsIGRhbWFnZXMgb3IgbG9zc2VzKSwgZXZlbiBp\nZiBzdWNoIENvbnRyaWJ1dG9yCiAgICAgIGhhcyBiZWVuIGFkdmlzZWQgb2Yg\ndGhlIHBvc3NpYmlsaXR5IG9mIHN1Y2ggZGFtYWdlcy4KCiAgIDkuIEFjY2Vw\ndGluZyBXYXJyYW50eSBvciBBZGRpdGlvbmFsIExpYWJpbGl0eS4gV2hpbGUg\ncmVkaXN0cmlidXRpbmcKICAgICAgdGhlIFdvcmsgb3IgRGVyaXZhdGl2ZSBX\nb3JrcyB0aGVyZW9mLCBZb3UgbWF5IGNob29zZSB0byBvZmZlciwKICAgICAg\nYW5kIGNoYXJnZSBhIGZlZSBmb3IsIGFjY2VwdGFuY2Ugb2Ygc3VwcG9ydCwg\nd2FycmFudHksIGluZGVtbml0eSwKICAgICAgb3Igb3RoZXIgbGlhYmlsaXR5\nIG9ibGlnYXRpb25zIGFuZC9vciByaWdodHMgY29uc2lzdGVudCB3aXRoIHRo\naXMKICAgICAgTGljZW5zZS4gSG93ZXZlciwgaW4gYWNjZXB0aW5nIHN1Y2gg\nb2JsaWdhdGlvbnMsIFlvdSBtYXkgYWN0IG9ubHkKICAgICAgb24gWW91ciBv\nd24gYmVoYWxmIGFuZCBvbiBZb3VyIHNvbGUgcmVzcG9uc2liaWxpdHksIG5v\ndCBvbiBiZWhhbGYKICAgICAgb2YgYW55IG90aGVyIENvbnRyaWJ1dG9yLCBh\nbmQgb25seSBpZiBZb3UgYWdyZWUgdG8gaW5kZW1uaWZ5LAogICAgICBkZWZl\nbmQsIGFuZCBob2xkIGVhY2ggQ29udHJpYnV0b3IgaGFybWxlc3MgZm9yIGFu\neSBsaWFiaWxpdHkKICAgICAgaW5jdXJyZWQgYnksIG9yIGNsYWltcyBhc3Nl\ncnRlZCBhZ2FpbnN0LCBzdWNoIENvbnRyaWJ1dG9yIGJ5IHJlYXNvbgogICAg\nICBvZiB5b3VyIGFjY2VwdGluZyBhbnkgc3VjaCB3YXJyYW50eSBvciBhZGRp\ndGlvbmFsIGxpYWJpbGl0eS4KCiAgIEVORCBPRiBURVJNUyBBTkQgQ09ORElU\nSU9OUwoKICAgQ29weXJpZ2h0IFRoZSBjb250YWluZXJkIEF1dGhvcnMKCiAg\nIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAy\nLjAgKHRoZSAiTGljZW5zZSIpOwogICB5b3UgbWF5IG5vdCB1c2UgdGhpcyBm\naWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAg\nIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAoKICAg\nICAgIGh0dHBzOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0y\nLjAKCiAgIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBh\nZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICAgZGlzdHJpYnV0ZWQg\ndW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElT\nIiBCQVNJUywKICAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMg\nT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAgIFNl\nZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVy\nbmluZyBwZXJtaXNzaW9ucyBhbmQKICAgbGltaXRhdGlvbnMgdW5kZXIgdGhl\nIExpY2Vuc2UuCg==\n',
                 license_recognized_at='...something...',
                 license_recognizer_name='MappedToGitHubRecognizer')))
     self.assertTrue(
         _matches(
             self.entries[6],
             LicenseReportEntry(
                 package='myserver2.com/backoff',
                 license_name='MIT License',
                 license_url=
                 'https://raw.githubusercontent.com/cenkalti/backoff/v3/LICENSE',
                 license_encoded=
                 'VGhlIE1JVCBMaWNlbnNlIChNSVQpCgpDb3B5cmlnaHQgKGMpIDIwMTQgQ2Vu\nayBBbHTEsQoKUGVybWlzc2lvbiBpcyBoZXJlYnkgZ3JhbnRlZCwgZnJlZSBv\nZiBjaGFyZ2UsIHRvIGFueSBwZXJzb24gb2J0YWluaW5nIGEgY29weSBvZgp0\naGlzIHNvZnR3YXJlIGFuZCBhc3NvY2lhdGVkIGRvY3VtZW50YXRpb24gZmls\nZXMgKHRoZSAiU29mdHdhcmUiKSwgdG8gZGVhbCBpbgp0aGUgU29mdHdhcmUg\nd2l0aG91dCByZXN0cmljdGlvbiwgaW5jbHVkaW5nIHdpdGhvdXQgbGltaXRh\ndGlvbiB0aGUgcmlnaHRzIHRvCnVzZSwgY29weSwgbW9kaWZ5LCBtZXJnZSwg\ncHVibGlzaCwgZGlzdHJpYnV0ZSwgc3VibGljZW5zZSwgYW5kL29yIHNlbGwg\nY29waWVzIG9mCnRoZSBTb2Z0d2FyZSwgYW5kIHRvIHBlcm1pdCBwZXJzb25z\nIHRvIHdob20gdGhlIFNvZnR3YXJlIGlzIGZ1cm5pc2hlZCB0byBkbyBzbywK\nc3ViamVjdCB0byB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnM6CgpUaGUgYWJv\ndmUgY29weXJpZ2h0IG5vdGljZSBhbmQgdGhpcyBwZXJtaXNzaW9uIG5vdGlj\nZSBzaGFsbCBiZSBpbmNsdWRlZCBpbiBhbGwKY29waWVzIG9yIHN1YnN0YW50\naWFsIHBvcnRpb25zIG9mIHRoZSBTb2Z0d2FyZS4KClRIRSBTT0ZUV0FSRSBJ\nUyBQUk9WSURFRCAiQVMgSVMiLCBXSVRIT1VUIFdBUlJBTlRZIE9GIEFOWSBL\nSU5ELCBFWFBSRVNTIE9SCklNUExJRUQsIElOQ0xVRElORyBCVVQgTk9UIExJ\nTUlURUQgVE8gVEhFIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZLCBG\nSVRORVNTCkZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBTkQgTk9OSU5GUklO\nR0VNRU5ULiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVVUSE9SUyBPUgpDT1BZ\nUklHSFQgSE9MREVSUyBCRSBMSUFCTEUgRk9SIEFOWSBDTEFJTSwgREFNQUdF\nUyBPUiBPVEhFUiBMSUFCSUxJVFksIFdIRVRIRVIKSU4gQU4gQUNUSU9OIE9G\nIENPTlRSQUNULCBUT1JUIE9SIE9USEVSV0lTRSwgQVJJU0lORyBGUk9NLCBP\nVVQgT0YgT1IgSU4KQ09OTkVDVElPTiBXSVRIIFRIRSBTT0ZUV0FSRSBPUiBU\nSEUgVVNFIE9SIE9USEVSIERFQUxJTkdTIElOIFRIRSBTT0ZUV0FSRS4K\n',
                 license_recognized_at='...something...',
                 license_recognizer_name='MappedToGitHubRecognizer')))
def _setup_file(filename: str):
    ch = JsonFileLicenseCache(filename)
    ch.write(LicenseReportEntry(package="one"))
    ch.write(LicenseReportEntry(package="two"))
    ch.update_cache_file()