Exemplo n.º 1
0
    def test_primes(self):
        """Test a bunch of different distributions."""
        projects = [
            data_types.OssFuzzProject(name='proj1', cpu_weight=2.0),
            data_types.OssFuzzProject(name='proj2', cpu_weight=3.0),
            data_types.OssFuzzProject(name='proj3', cpu_weight=5.0),
            data_types.OssFuzzProject(name='proj4', cpu_weight=7.0),
            data_types.OssFuzzProject(name='proj5', cpu_weight=11.0),
        ]

        result = manage_vms.OssFuzzClustersManager(
            'clusterfuzz-external').distribute_cpus(projects, 101)
        self.assertListEqual([7, 10, 18, 26, 40], result)
        self.assertEqual(101, sum(result))

        result = manage_vms.OssFuzzClustersManager(
            'clusterfuzz-external').distribute_cpus(projects, 887)
        self.assertListEqual([63, 95, 158, 222, 349], result)
        self.assertEqual(887, sum(result))

        result = manage_vms.OssFuzzClustersManager(
            'clusterfuzz-external').distribute_cpus(projects, 2741)
        self.assertListEqual([214, 313, 509, 705, 1000], result)
        self.assertEqual(2741, sum(result))

        result = manage_vms.OssFuzzClustersManager(
            'clusterfuzz-external').distribute_cpus(projects, 3571)
        self.assertListEqual([356, 483, 738, 994, 1000], result)
        self.assertEqual(3571, sum(result))
    def test_reminder(self):
        """Test reminders."""
        # Return the same status for all build types.
        self.mock.get.return_value = MockResponse(
            json.dumps({
                'projects': [
                    {
                        'history': [{
                            'finish_time': '2018-02-01T00:00:00.000000Z',
                            'build_id': 'proj0-id',
                            'success': False
                        }],
                        'name':
                        'proj0',
                    },
                    {
                        'history': [{
                            'finish_time': '2018-02-01T00:00:00.000000Z',
                            'build_id': 'proj0-id',
                            'success': False
                        }],
                        'name':
                        'proj1',
                    },
                ]
            }))

        data_types.OssFuzzProject(id='proj0', name='proj0',
                                  ccs=['*****@*****.**']).put()
        data_types.OssFuzzBuildFailure(
            id='proj0',
            project_name='proj0',
            last_checked_timestamp=datetime.datetime(2018, 1, 31),
            issue_id='1',
            consecutive_failures=7,
            build_type='fuzzing').put()
        data_types.OssFuzzProject(id='proj1', name='proj1',
                                  ccs=['*****@*****.**']).put()
        data_types.OssFuzzBuildFailure(
            id='proj1',
            project_name='proj1',
            last_checked_timestamp=datetime.datetime(2018, 1, 31),
            issue_id='2',
            consecutive_failures=3,
            build_type='fuzzing').put()

        self.itm.issues[1] = Issue()
        self.itm.issues[2] = Issue()

        self.app.get('/build-status')
        self.assertEqual(
            'Friendly reminder that the the build is still failing.\n'
            'Please try to fix this failure to ensure that fuzzing remains '
            'productive.\n'
            'Latest build log: https://oss-fuzz-build-logs.storage.googleapis.com/'
            'log-proj0-id.txt\n', self.itm.issues[1].comment)
        self.assertEqual('', self.itm.issues[2].comment)
Exemplo n.º 3
0
    def test_equal(self):
        """Tests for each project receiving equal share."""
        projects = [
            data_types.OssFuzzProject(name='proj1', cpu_weight=1.0),
            data_types.OssFuzzProject(name='proj2', cpu_weight=1.0),
            data_types.OssFuzzProject(name='proj3', cpu_weight=1.0),
        ]

        result = manage_vms.OssFuzzClustersManager(
            'clusterfuzz-external').distribute_cpus(projects, 30)
        self.assertListEqual([10, 10, 10], result)
Exemplo n.º 4
0
    def test_maximum(self):
        """Tests that projects are capped at the maximum share."""
        projects = [
            data_types.OssFuzzProject(name='proj1', cpu_weight=1.0),
            data_types.OssFuzzProject(name='proj2', cpu_weight=1.0),
            data_types.OssFuzzProject(name='proj3', cpu_weight=1.0),
        ]

        result = manage_vms.OssFuzzClustersManager(
            'clusterfuzz-external').distribute_cpus(projects, 10000)
        self.assertListEqual([1000, 1000, 1000], result)
Exemplo n.º 5
0
    def test_minimum(self):
        """Tests that projects are given a minimum share."""
        projects = [
            data_types.OssFuzzProject(name='proj1', cpu_weight=0.0),
            data_types.OssFuzzProject(name='proj2', cpu_weight=0.0),
            data_types.OssFuzzProject(name='proj3', cpu_weight=0.0),
        ]

        result = manage_vms.OssFuzzClustersManager(
            'clusterfuzz-external').distribute_cpus(projects, 3)
        self.assertListEqual([1, 1, 1], result)

        result = manage_vms.OssFuzzClustersManager(
            'clusterfuzz-external').distribute_cpus(projects, 10)
        self.assertListEqual([4, 3, 3], result)
Exemplo n.º 6
0
    def test_not_enough(self):
        """Tests allocation with not enough CPUs."""
        projects = [
            data_types.OssFuzzProject(name='proj1', cpu_weight=1.0),
            data_types.OssFuzzProject(name='proj2', cpu_weight=1.0),
            data_types.OssFuzzProject(name='proj3', cpu_weight=1.0),
        ]

        result = manage_vms.OssFuzzClustersManager(
            'clusterfuzz-external').distribute_cpus(projects, 1)
        self.assertListEqual([1, 0, 0], result)

        result = manage_vms.OssFuzzClustersManager(
            'clusterfuzz-external').distribute_cpus(projects, 2)
        self.assertListEqual([1, 1, 0], result)
Exemplo n.º 7
0
def create_project_settings(project, info, service_account):
    """Setup settings for ClusterFuzz (such as CPU distribution)."""
    key = ndb.Key(data_types.OssFuzzProject, project)
    oss_fuzz_project = key.get()

    # Expecting to run a blackbox fuzzer, so use high end hosts.
    is_high_end = info.get('blackbox', False)

    ccs = ccs_from_info(info)
    language = info.get('language')

    if oss_fuzz_project:
        if oss_fuzz_project.service_account != service_account['email']:
            oss_fuzz_project.service_account = service_account['email']
            oss_fuzz_project.put()

        if oss_fuzz_project.high_end != is_high_end:
            oss_fuzz_project.high_end = is_high_end
            oss_fuzz_project.put()

        if oss_fuzz_project.ccs != ccs:
            oss_fuzz_project.ccs = ccs
            oss_fuzz_project.put()
    else:
        if language in MEMORY_SAFE_LANGUAGES:
            cpu_weight = OSS_FUZZ_MEMORY_SAFE_LANGUAGE_PROJECT_WEIGHT
        else:
            cpu_weight = OSS_FUZZ_DEFAULT_PROJECT_CPU_WEIGHT

        data_types.OssFuzzProject(id=project,
                                  name=project,
                                  high_end=is_high_end,
                                  cpu_weight=cpu_weight,
                                  service_account=service_account['email'],
                                  ccs=ccs).put()
Exemplo n.º 8
0
    def test_weight_preference(self):
        """Tests that remainders are given to projects with higher weights

    first.
    """
        projects = [
            data_types.OssFuzzProject(name='proj1', cpu_weight=1.0),
            data_types.OssFuzzProject(name='proj2', cpu_weight=1.01),
            data_types.OssFuzzProject(name='proj3', cpu_weight=1.1),
        ]

        result = manage_vms.OssFuzzClustersManager(
            'clusterfuzz-external').distribute_cpus(projects, 4)
        self.assertListEqual([1, 1, 2], result)

        result = manage_vms.OssFuzzClustersManager(
            'clusterfuzz-external').distribute_cpus(projects, 5)
        self.assertListEqual([1, 2, 2], result)
  def setUp(self):
    test_helpers.patch_environ(self)
    test_helpers.patch(self, [
        'handlers.base_handler.Handler.is_cron',
    ])

    self.mock.is_cron.return_value = True
    flaskapp = flask.Flask('testflask')
    flaskapp.add_url_rule(
        '/generate-certs',
        view_func=oss_fuzz_generate_certs.Handler.as_view('/generate-certs'))
    self.app = webtest.TestApp(flaskapp)

    data_types.OssFuzzProject(name='project1').put()
    data_types.OssFuzzProject(name='project2').put()

    data_types.WorkerTlsCert(
        id='project2',
        project_name='project2',
        cert_contents=b'cert_contents',
        key_contents=b'key_contents').put()
Exemplo n.º 10
0
    def setUp(self):
        test_helpers.patch_environ(self)
        test_helpers.patch(self, [
            'clusterfuzz._internal.base.utils.is_oss_fuzz',
            'handlers.cron.helpers.bot_manager.BotManager',
            'clusterfuzz._internal.system.environment.is_running_on_app_engine',
            'clusterfuzz._internal.google_cloud_utils.compute_engine_projects.load_project',
        ])

        self.mock.is_oss_fuzz.return_value = True
        self.mock.is_running_on_app_engine.return_value = True
        self.mock.load_project.return_value = OSS_FUZZ_CLUSTERS

        data_types.OssFuzzProject(
            id='proj1',
            name='proj1',
            cpu_weight=1.0,
            service_account='*****@*****.**').put()

        data_types.OssFuzzProject(
            id='proj2',
            name='proj2',
            cpu_weight=2.0,
            service_account='*****@*****.**').put()

        data_types.OssFuzzProject(
            id='proj3',
            name='proj3',
            cpu_weight=5.0,
            service_account='*****@*****.**').put()

        data_types.OssFuzzProject(
            id='proj4',
            name='proj4',
            cpu_weight=1.0,
            service_account='*****@*****.**').put()

        data_types.OssFuzzProject(id='proj5',
                                  name='proj5',
                                  cpu_weight=1.0,
                                  service_account='*****@*****.**',
                                  disk_size_gb=10).put()

        data_types.OssFuzzProject(id='proj6',
                                  name='proj6',
                                  cpu_weight=1.0,
                                  service_account='*****@*****.**',
                                  high_end=True).put()

        for j in range(1, 7):
            project_name = 'proj%d' % j
            data_types.WorkerTlsCert(
                id=project_name,
                project_name=project_name,
                cert_contents=project_name.encode() + b'_cert',
                key_contents=project_name.encode() + b'_key').put()

        data_types.OssFuzzProjectInfo(id='old_proj', name='old_proj').put()

        data_types.OssFuzzProjectInfo(
            id='proj2',
            name='proj2',
            clusters=[
                data_types.OssFuzzProjectInfo.ClusterInfo(
                    cluster='oss-fuzz-linux-zone2-pre',
                    gce_zone='us-east2-a',
                    cpu_count=1,
                ),
                data_types.OssFuzzProjectInfo.ClusterInfo(
                    cluster='old-cluster',
                    gce_zone='us-east2-a',
                    cpu_count=1,
                ),
            ]).put()

        data_types.OssFuzzProjectInfo(
            id='proj3',
            name='proj3',
            clusters=[
                data_types.OssFuzzProjectInfo.ClusterInfo(
                    cluster='oss-fuzz-linux-zone2-pre',
                    gce_zone='us-east2-a',
                    cpu_count=499,
                )
            ]).put()

        data_types.OssFuzzProjectInfo(
            id='proj4',
            name='proj4',
            clusters=[
                data_types.OssFuzzProjectInfo.ClusterInfo(
                    cluster='oss-fuzz-linux-zone2-pre',
                    gce_zone='us-east2-a',
                    cpu_count=99,
                )
            ]).put()

        data_types.OssFuzzProjectInfo(
            id='proj5',
            name='proj5',
            clusters=[
                data_types.OssFuzzProjectInfo.ClusterInfo(
                    cluster='oss-fuzz-linux-zone2-pre',
                    gce_zone='us-east2-a',
                    cpu_count=99,
                )
            ]).put()

        data_types.OssFuzzProjectInfo(
            id='old_proj',
            name='old_proj',
            clusters=[
                data_types.OssFuzzProjectInfo.ClusterInfo(
                    cluster='oss-fuzz-linux-zone2-pre',
                    gce_zone='us-east2-a',
                    cpu_count=5,
                )
            ]).put()

        data_types.HostWorkerAssignment(id='old-host-0',
                                        host_name='old-host',
                                        worker_name='worker',
                                        instance_num=0).put()

        instance_groups = {}
        instance_templates = {}
        self.mock.BotManager.side_effect = functools.partial(
            MockBotManager,
            instance_groups=instance_groups,
            instance_templates=instance_templates)
    def test_build_failures(self):
        """Test run with multiple build failures of different type."""
        def _mock_requests_get(url):
            """Mock requests.get."""
            if url == oss_fuzz_build_status.FUZZING_STATUS_URL:
                return MockResponse(
                    json.dumps({
                        'projects': [
                            # Both fuzzing and coverage build types are successful.
                            {
                                'history': [{
                                    'finish_time':
                                    '2018-02-01T00:00:00.000000Z',
                                    'build_id': 'proj0-id-f',
                                    'success': True
                                }],
                                'name':
                                'proj0',
                            },
                            # Only coverage build type is broken for a while.
                            {
                                'history': [{
                                    'finish_time':
                                    '2018-02-01T00:00:00.000000Z',
                                    'build_id': 'proj5-id-f',
                                    'success': True
                                }],
                                'name':
                                'proj5',
                            },
                            # Only coverage build type broken.
                            {
                                'history': [{
                                    'finish_time':
                                    '2018-02-01T00:00:00.000000Z',
                                    'build_id': 'proj6-id-f',
                                    'success': True
                                }],
                                'name':
                                'proj6',
                            },

                            # New failure (first 1).
                            {
                                'history': [{
                                    'finish_time':
                                    '2018-02-01T00:00:00.000000000Z',
                                    'build_id': 'proj1-id-f',
                                    'success': False
                                }],
                                'name':
                                'proj1',
                            },
                            # Seen failure (second consecutive).
                            {
                                'history': [{
                                    'finish_time':
                                    '2018-02-01T00:00:00.000000Z',
                                    'build_id': 'proj2-id-f',
                                    'success': False
                                }],
                                'name':
                                'proj2',
                            },
                            # Seen failure (not updated).
                            {
                                'history': [{
                                    'finish_time':
                                    '2018-01-31T00:00:00.000000Z',
                                    'build_id': 'proj3-id-f',
                                    'success': False
                                }],
                                'name':
                                'proj3',
                            },
                            # Seen failure (third consecutive, bug already filed).
                            {
                                'history': [{
                                    'finish_time':
                                    '2018-02-01T00:00:00.000000Z',
                                    'build_id': 'proj4-id-f',
                                    'success': False
                                }],
                                'name':
                                'proj4',
                            },
                        ]
                    }))

            assert url == oss_fuzz_build_status.COVERAGE_STATUS_URL
            return MockResponse(
                json.dumps({
                    'projects': [
                        # Both fuzzing and coverage build types are successful.
                        {
                            'history': [{
                                'finish_time': '2018-02-01T00:00:00.000000Z',
                                'build_id': 'proj0-id-c',
                                'success': True
                            }],
                            'name':
                            'proj0',
                        },

                        # New failure (first 1).
                        {
                            'history': [{
                                'finish_time':
                                '2018-02-01T00:00:00.000000000Z',
                                'build_id': 'proj1-id-c',
                                'success': False
                            }],
                            'name':
                            'proj1',
                        },
                        # Seen failure (second consecutive).
                        {
                            'history': [{
                                'name': 'proj2',
                                'finish_time': '2018-02-01T00:00:00.000000Z',
                                'success': False
                            }],
                            'name':
                            'proj2',
                        },
                        # Seen failure (not updated).
                        {
                            'history': [{
                                'finish_time': '2018-01-31T00:00:00.000000Z',
                                'build_id': 'proj3-id-c',
                                'success': False
                            }],
                            'name':
                            'proj3',
                        },
                        # Seen failure (third consecutive, bug already filed).
                        {
                            'history': [{
                                'finish_time': '2018-02-01T00:00:00.000000Z',
                                'build_id': 'proj4-id-c',
                                'success': False
                            }],
                            'name':
                            'proj4',
                        },
                        # Coverage build type is broken for a while.
                        {
                            'history': [{
                                'finish_time': '2018-02-01T00:00:00.000000Z',
                                'build_id': 'proj5-id-c',
                                'success': False
                            }],
                            'name':
                            'proj5',
                        },
                        # Only coverage build type broken (second consecutive).
                        {
                            'history': [{
                                'finish_time': '2018-02-01T00:00:00.000000Z',
                                'build_id': 'proj6-id-c',
                                'success': False
                            }],
                            'name':
                            'proj6',
                        },
                    ]
                }))

        self.mock.get.side_effect = _mock_requests_get

        data_types.OssFuzzBuildFailure(
            id='proj2',
            project_name='proj2',
            last_checked_timestamp=datetime.datetime(2018, 1, 31),
            consecutive_failures=1,
            build_type='fuzzing').put()

        data_types.OssFuzzBuildFailure(
            id='proj3',
            project_name='proj3',
            last_checked_timestamp=datetime.datetime(2018, 1, 31),
            consecutive_failures=1,
            build_type='fuzzing').put()

        data_types.OssFuzzBuildFailure(
            id='proj4',
            project_name='proj4',
            last_checked_timestamp=datetime.datetime(2018, 1, 31),
            issue_id='1337',
            consecutive_failures=2,
            build_type='fuzzing').put()

        data_types.OssFuzzBuildFailure(
            id='proj5-coverage',
            project_name='proj5',
            last_checked_timestamp=datetime.datetime(2018, 1, 31),
            issue_id='31337',
            consecutive_failures=5,
            build_type='coverage').put()

        data_types.OssFuzzBuildFailure(
            id='proj6-coverage',
            project_name='proj6',
            last_checked_timestamp=datetime.datetime(2018, 1, 31),
            issue_id=None,
            consecutive_failures=1,
            build_type='coverage').put()

        data_types.OssFuzzProject(id='proj2', name='proj2',
                                  ccs=['*****@*****.**']).put()
        data_types.OssFuzzProject(id='proj6', name='proj7',
                                  ccs=['*****@*****.**']).put()

        self.app.get('/build-status')
        six.assertCountEqual(self, [
            {
                'build_type': 'fuzzing',
                'consecutive_failures': 1,
                'issue_id': None,
                'last_checked_timestamp': datetime.datetime(2018, 2, 1, 0, 0),
                'project_name': u'proj1'
            },
            {
                'build_type': 'fuzzing',
                'consecutive_failures': 2,
                'issue_id': '1',
                'last_checked_timestamp': datetime.datetime(2018, 2, 1, 0, 0),
                'project_name': u'proj2'
            },
            {
                'build_type': 'fuzzing',
                'consecutive_failures': 1,
                'issue_id': None,
                'last_checked_timestamp': datetime.datetime(2018, 1, 31, 0, 0),
                'project_name': u'proj3'
            },
            {
                'build_type': 'fuzzing',
                'consecutive_failures': 3,
                'issue_id': '1337',
                'last_checked_timestamp': datetime.datetime(2018, 2, 1, 0, 0),
                'project_name': u'proj4'
            },
            {
                'build_type': 'coverage',
                'consecutive_failures': 6,
                'issue_id': '31337',
                'last_checked_timestamp': datetime.datetime(2018, 2, 1, 0, 0),
                'project_name': u'proj5'
            },
            {
                'build_type': 'coverage',
                'consecutive_failures': 2,
                'issue_id': '2',
                'last_checked_timestamp': datetime.datetime(2018, 2, 1, 0, 0),
                'project_name': u'proj6'
            },
        ], [
            failure.to_dict()
            for failure in data_types.OssFuzzBuildFailure.query()
        ])

        self.assertEqual(2, len(self.itm.issues))
        issue = self.itm.issues[1]
        six.assertCountEqual(self, ['*****@*****.**'], issue.cc)
        self.assertEqual('New', issue.status)
        self.assertEqual('proj2: Fuzzing build failure', issue.summary)
        self.assertEqual(
            'The last 2 builds for proj2 have been failing.\n'
            '<b>Build log:</b> '
            'https://oss-fuzz-build-logs.storage.googleapis.com/'
            'log-proj2-id-f.txt\n'
            'Build type: fuzzing\n\n'
            'To reproduce locally, please see: '
            'https://google.github.io/oss-fuzz/advanced-topics/reproducing'
            '#reproducing-build-failures\n\n'
            '<b>This bug tracker is not being monitored by OSS-Fuzz team.</b> '
            'If you have any questions, please create an issue at '
            'https://github.com/google/oss-fuzz/issues/new.\n\n'
            '**This bug will be automatically closed within a '
            'day once it is fixed.**', issue.body)

        self.assertTrue(issue.has_label('Proj-proj2'))
        self.assertTrue(issue.has_label('Type-Build-Failure'))

        issue = self.itm.issues[2]
        six.assertCountEqual(self, ['*****@*****.**'], issue.cc)
        self.assertEqual('New', issue.status)
        self.assertEqual('proj6: Coverage build failure', issue.summary)
        self.assertEqual(
            'The last 2 builds for proj6 have been failing.\n'
            '<b>Build log:</b> '
            'https://oss-fuzz-build-logs.storage.googleapis.com/'
            'log-proj6-id-c.txt\n'
            'Build type: coverage\n\n'
            'To reproduce locally, please see: '
            'https://google.github.io/oss-fuzz/advanced-topics/reproducing'
            '#reproducing-build-failures\n\n'
            '<b>This bug tracker is not being monitored by OSS-Fuzz team.</b> '
            'If you have any questions, please create an issue at '
            'https://github.com/google/oss-fuzz/issues/new.\n\n'
            '**This bug will be automatically closed within a '
            'day once it is fixed.**', issue.body)

        self.assertTrue(issue.has_label('Proj-proj6'))
        self.assertTrue(issue.has_label('Type-Build-Failure'))