def _coverage_information(summary_path, name, report_info):
    """Returns a CoverageInformation entity with coverage stats populated."""
    date = datetime.datetime.strptime(
        report_info['report_date'],
        data_types.COVERAGE_INFORMATION_DATE_FORMAT).date()

    # |name| can be either a project qualified fuzz target name or a project name.
    cov_info = data_handler.get_coverage_information(name,
                                                     date,
                                                     create_if_needed=True)
    cov_info.fuzzer = name
    cov_info.date = date

    # Link to a per project report as long as we don't have per fuzzer reports.
    cov_info.html_report_url = report_info['html_report_url']

    summary = _read_json(summary_path)
    if not summary:
        # We can encounter empty JSON files for broken fuzz targets.
        return cov_info

    total_stats = summary['data'][0]['totals']
    cov_info.functions_covered = total_stats['functions']['covered']
    cov_info.functions_total = total_stats['functions']['count']
    cov_info.edges_covered = total_stats['regions']['covered']
    cov_info.edges_total = total_stats['regions']['count']

    return cov_info
    def test_prune(self):
        """Basic pruning test."""
        corpus_pruning_task.execute_task('libFuzzer_test_fuzzer',
                                         'libfuzzer_asan_job')

        quarantined = os.listdir(self.quarantine_dir)
        self.assertEqual(1, len(quarantined))
        self.assertEqual(quarantined[0],
                         'crash-7acd6a2b3fe3c5ec97fa37e5a980c106367491fa')

        corpus = os.listdir(self.corpus_dir)
        self.assertEqual(4, len(corpus))
        six.assertCountEqual(self, [
            '39e0574a4abfd646565a3e436c548eeb1684fb57',
            '7d157d7c000ae27db146575c08ce30df893d3a64',
            '31836aeaab22dc49555a97edb4c753881432e01d',
            '6fa8c57336628a7d733f684dc9404fbd09020543',
        ], corpus)

        testcases = list(data_types.Testcase.query())
        self.assertEqual(1, len(testcases))
        self.assertEqual('Null-dereference WRITE', testcases[0].crash_type)
        self.assertEqual('Foo\ntest_fuzzer.cc\n', testcases[0].crash_state)
        self.assertEqual(1337, testcases[0].crash_revision)
        self.assertEqual('test_fuzzer',
                         testcases[0].get_metadata('fuzzer_binary_name'))
        self.assertEqual('label1,label2',
                         testcases[0].get_metadata('issue_labels'))

        today = datetime.datetime.utcnow().date()
        # get_coverage_information on test_fuzzer rather than libFuzzer_test_fuzzer
        # since the libfuzzer_ prefix is removed when saving coverage info.
        coverage_info = data_handler.get_coverage_information(
            'test_fuzzer', today)

        self.assertDictEqual(
            {
                'corpus_backup_location': u'backup_link',
                'corpus_location': u'gs://bucket/libFuzzer/test_fuzzer/',
                'corpus_size_bytes': 8,
                'corpus_size_units': 4,
                'date': today,
                # Coverage numbers are expected to be None as they come from fuzzer
                # coverage cron task (see src/go/server/cron/coverage.go).
                'edges_covered': None,
                'edges_total': None,
                'functions_covered': None,
                'functions_total': None,
                'fuzzer': u'test_fuzzer',
                'html_report_url': None,
                'quarantine_location':
                u'gs://bucket-quarantine/libFuzzer/test_fuzzer/',
                'quarantine_size_bytes': 2,
                'quarantine_size_units': 1,
            },
            coverage_info.to_dict())

        self.assertEqual(self.mock.unpack_seed_corpus_if_needed.call_count, 1)
Exemple #3
0
    def _try_save_coverage_information():
        """Implements save_coverage_information function."""
        coverage_info = data_handler.get_coverage_information(
            context.fuzz_target.project_qualified_name(),
            result.coverage_info.date,
            create_if_needed=True,
        )

        # Intentionally skip edge and function coverage values as those would come
        # from fuzzer coverage cron task (see src/go/server/cron/coverage.go).
        coverage_info.corpus_size_units = result.coverage_info.corpus_size_units
        coverage_info.corpus_size_bytes = result.coverage_info.corpus_size_bytes
        coverage_info.corpus_location = result.coverage_info.corpus_location
        coverage_info.corpus_backup_location = (
            result.coverage_info.corpus_backup_location)
        coverage_info.quarantine_size_units = result.coverage_info.quarantine_size_units
        coverage_info.quarantine_size_bytes = result.coverage_info.quarantine_size_bytes
        coverage_info.quarantine_location = result.coverage_info.quarantine_location
        coverage_info.put()
    def test_prune(self):
        """Test pruning."""
        self._setup_env(job_type='libfuzzer_asan_job')
        self.mock._record_cross_pollination_stats.side_effect = (
            self.get_mock_record_compare(project_qualified_name='test_fuzzer',
                                         method='random',
                                         sources='test2_fuzzer',
                                         tags='',
                                         initial_corpus_size=5,
                                         corpus_size=3,
                                         initial_edge_coverage=0,
                                         edge_coverage=0,
                                         initial_feature_coverage=0,
                                         feature_coverage=0))

        corpus_pruning_task.execute_task('libFuzzer_test_fuzzer',
                                         'libfuzzer_asan_job')

        corpus_dir = os.path.join(self.temp_dir, 'corpus')
        os.mkdir(corpus_dir)
        self.corpus.rsync_to_disk(corpus_dir)

        six.assertCountEqual(self, [
            '39e0574a4abfd646565a3e436c548eeb1684fb57',
            '7d157d7c000ae27db146575c08ce30df893d3a64',
            '31836aeaab22dc49555a97edb4c753881432e01d',
            '6fa8c57336628a7d733f684dc9404fbd09020543',
        ], os.listdir(corpus_dir))

        quarantine_dir = os.path.join(self.temp_dir, 'quarantine')
        os.mkdir(quarantine_dir)
        self.quarantine_corpus.rsync_to_disk(quarantine_dir)

        six.assertCountEqual(
            self, ['crash-7acd6a2b3fe3c5ec97fa37e5a980c106367491fa'],
            os.listdir(quarantine_dir))

        testcases = list(data_types.Testcase.query())
        self.assertEqual(1, len(testcases))
        self.assertEqual('Null-dereference WRITE', testcases[0].crash_type)
        self.assertEqual('Foo\ntest_fuzzer.cc\n', testcases[0].crash_state)
        self.assertEqual(1337, testcases[0].crash_revision)
        self.assertEqual('test_fuzzer',
                         testcases[0].get_metadata('fuzzer_binary_name'))

        self.mock.add_task.assert_has_calls([
            mock.call('minimize', testcases[0].key.id(),
                      u'libfuzzer_asan_job'),
        ])

        today = datetime.datetime.utcnow().date()
        coverage_info = data_handler.get_coverage_information(
            'test_fuzzer', today)
        coverage_info_without_backup = coverage_info.to_dict()
        del coverage_info_without_backup['corpus_backup_location']

        self.assertDictEqual(
            {
                'corpus_location':
                u'gs://{}/libFuzzer/test_fuzzer/'.format(self.corpus_bucket),
                'corpus_size_bytes':
                8,
                'corpus_size_units':
                4,
                'date':
                today,
                # Coverage numbers are expected to be None as they come from fuzzer
                # coverage cron task (see src/go/server/cron/coverage.go).
                'edges_covered':
                None,
                'edges_total':
                None,
                'functions_covered':
                None,
                'functions_total':
                None,
                'fuzzer':
                u'test_fuzzer',
                'html_report_url':
                None,
                'quarantine_location':
                u'gs://{}/libFuzzer/test_fuzzer/'.format(
                    self.quarantine_bucket),
                'quarantine_size_bytes':
                2,
                'quarantine_size_units':
                1,
            },
            coverage_info_without_backup)

        self.assertEqual(
            coverage_info.corpus_backup_location,
            'gs://{}/corpus/libFuzzer/test_fuzzer/'.format(
                self.backup_bucket) + '%s.zip' % today)
  def test_prune(self):
    """Test pruning."""
    self._setup_env(job_type="libfuzzer_asan_job")
    corpus_pruning_task.execute_task("libFuzzer_test_fuzzer",
                                     "libfuzzer_asan_job")

    corpus_dir = os.path.join(self.temp_dir, "corpus")
    os.mkdir(corpus_dir)
    self.corpus.rsync_to_disk(corpus_dir)

    self.assertItemsEqual(
        [
            "39e0574a4abfd646565a3e436c548eeb1684fb57",
            "7d157d7c000ae27db146575c08ce30df893d3a64",
            "31836aeaab22dc49555a97edb4c753881432e01d",
            "6fa8c57336628a7d733f684dc9404fbd09020543",
        ],
        os.listdir(corpus_dir),
    )

    quarantine_dir = os.path.join(self.temp_dir, "quarantine")
    os.mkdir(quarantine_dir)
    self.quarantine_corpus.rsync_to_disk(quarantine_dir)

    self.assertItemsEqual(
        ["crash-7acd6a2b3fe3c5ec97fa37e5a980c106367491fa"],
        os.listdir(quarantine_dir),
    )

    testcases = list(data_types.Testcase.query())
    self.assertEqual(1, len(testcases))
    self.assertEqual("Null-dereference WRITE", testcases[0].crash_type)
    self.assertEqual("Foo\ntest_fuzzer.cc\n", testcases[0].crash_state)
    self.assertEqual(1337, testcases[0].crash_revision)
    self.assertEqual("test_fuzzer",
                     testcases[0].get_metadata("fuzzer_binary_name"))

    self.mock.add_task.assert_has_calls(
        [mock.call("minimize", testcases[0].key.id(), u"libfuzzer_asan_job")])

    today = datetime.datetime.utcnow().date()
    coverage_info = data_handler.get_coverage_information("test_fuzzer", today)
    coverage_info_without_backup = coverage_info.to_dict()
    del coverage_info_without_backup["corpus_backup_location"]

    self.assertDictEqual(
        {
            "corpus_location":
                u"gs://{}/libFuzzer/test_fuzzer/".format(self.corpus_bucket),
            "corpus_size_bytes":
                8,
            "corpus_size_units":
                4,
            "date":
                today,
            # Coverage numbers are expected to be None as they come from fuzzer
            # coverage cron task (see src/go/server/cron/coverage.go).
            "edges_covered":
                None,
            "edges_total":
                None,
            "functions_covered":
                None,
            "functions_total":
                None,
            "fuzzer":
                u"test_fuzzer",
            "html_report_url":
                None,
            "quarantine_location":
                u"gs://{}/libFuzzer/test_fuzzer/".format(self.quarantine_bucket
                                                        ),
            "quarantine_size_bytes":
                2,
            "quarantine_size_units":
                1,
        },
        coverage_info_without_backup,
    )

    self.assertEqual(
        coverage_info.corpus_backup_location,
        "gs://{}/corpus/libFuzzer/test_fuzzer/".format(self.backup_bucket) +
        "%s.zip" % today,
    )
  def test_prune(self):
    """Basic pruning test."""
    corpus_pruning_task.execute_task("libFuzzer_test_fuzzer",
                                     "libfuzzer_asan_job")

    quarantined = os.listdir(self.quarantine_dir)
    self.assertEqual(1, len(quarantined))
    self.assertEqual(quarantined[0],
                     "crash-7acd6a2b3fe3c5ec97fa37e5a980c106367491fa")

    corpus = os.listdir(self.corpus_dir)
    self.assertEqual(4, len(corpus))
    self.assertItemsEqual(
        [
            "39e0574a4abfd646565a3e436c548eeb1684fb57",
            "7d157d7c000ae27db146575c08ce30df893d3a64",
            "31836aeaab22dc49555a97edb4c753881432e01d",
            "6fa8c57336628a7d733f684dc9404fbd09020543",
        ],
        corpus,
    )

    testcases = list(data_types.Testcase.query())
    self.assertEqual(1, len(testcases))
    self.assertEqual("Null-dereference WRITE", testcases[0].crash_type)
    self.assertEqual("Foo\ntest_fuzzer.cc\n", testcases[0].crash_state)
    self.assertEqual(1337, testcases[0].crash_revision)
    self.assertEqual("test_fuzzer",
                     testcases[0].get_metadata("fuzzer_binary_name"))
    self.assertEqual("label1,label2", testcases[0].get_metadata("issue_labels"))

    today = datetime.datetime.utcnow().date()
    # get_coverage_information on test_fuzzer rather than libFuzzer_test_fuzzer
    # since the libfuzzer_ prefix is removed when saving coverage info.
    coverage_info = data_handler.get_coverage_information("test_fuzzer", today)

    self.assertDictEqual(
        {
            "corpus_backup_location":
                u"backup_link",
            "corpus_location":
                u"gs://bucket/libFuzzer/test_fuzzer/",
            "corpus_size_bytes":
                8,
            "corpus_size_units":
                4,
            "date":
                today,
            # Coverage numbers are expected to be None as they come from fuzzer
            # coverage cron task (see src/go/server/cron/coverage.go).
            "edges_covered":
                None,
            "edges_total":
                None,
            "functions_covered":
                None,
            "functions_total":
                None,
            "fuzzer":
                u"test_fuzzer",
            "html_report_url":
                None,
            "quarantine_location":
                u"gs://bucket-quarantine/libFuzzer/test_fuzzer/",
            "quarantine_size_bytes":
                2,
            "quarantine_size_units":
                1,
        },
        coverage_info.to_dict(),
    )

    self.assertEqual(self.mock.unpack_seed_corpus_if_needed.call_count, 1)