Beispiel #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)
Beispiel #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)
Beispiel #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)
Beispiel #5
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)
Beispiel #6
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)
Beispiel #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('fuzzing_engines') == ['none']

  ccs = ccs_from_info(info)

  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:
    data_types.OssFuzzProject(
        id=project,
        name=project,
        high_end=is_high_end,
        service_account=service_account['email'],
        ccs=ccs).put()
Beispiel #8
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('fuzzing_engines') == ['none']

    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()
Beispiel #9
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)
Beispiel #10
0
    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
        self.app = webtest.TestApp(
            webapp2.WSGIApplication([('/generate-certs',
                                      oss_fuzz_generate_certs.Handler)]))

        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()
    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()
    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({
                        'successes': [
                            # Both fuzzing and coverage build types are successful.
                            {
                                'name': 'proj0',
                                'finish_time': '2018-02-01T00:00:00.000000Z',
                                'build_id': 'proj0-id-f',
                            },

                            # Only coverage build type is broken for a while.
                            {
                                'name': 'proj5',
                                'finish_time': '2018-02-01T00:00:00.000000Z',
                                'build_id': 'proj5-id-f',
                            },

                            # Only coverage build type broken.
                            {
                                'name': 'proj6',
                                'finish_time': '2018-02-01T00:00:00.000000Z',
                                'build_id': 'proj6-id-f',
                            },
                        ],
                        'failures': [
                            # New failure (first 1).
                            {
                                'name': 'proj1',
                                'finish_time':
                                '2018-02-01T00:00:00.000000000Z',
                                'build_id': 'proj1-id-f',
                            },

                            # Seen failure (second consecutive).
                            {
                                'name': 'proj2',
                                'finish_time': '2018-02-01T00:00:00.000000Z',
                                'build_id': 'proj2-id-f',
                            },

                            # Seen failure (not updated).
                            {
                                'name': 'proj3',
                                'finish_time': '2018-01-31T00:00:00.000000Z',
                                'build_id': 'proj3-id-f',
                            },

                            # Seen failure (third consecutive, bug already filed).
                            {
                                'name': 'proj4',
                                'finish_time': '2018-02-01T00:00:00.000000Z',
                                'build_id': 'proj4-id-f',
                            },
                        ],
                    }))

            assert url == oss_fuzz_build_status.COVERAGE_STATUS_URL
            return MockResponse(
                json.dumps({
                    'successes': [
                        # Both fuzzing and coverage build types are successful.
                        {
                            'name': 'proj0',
                            'finish_time': '2018-02-01T00:00:00.000000Z',
                            'build_id': 'proj0-id-c',
                        },
                    ],
                    'failures': [
                        # New failure (first 1).
                        {
                            'name': 'proj1',
                            'finish_time': '2018-02-01T00:00:00.000000000Z',
                            'build_id': 'proj1-id-c',
                        },

                        # Seen failure (second consecutive).
                        {
                            'name': 'proj2',
                            'finish_time': '2018-02-01T00:00:00.000000Z',
                            'build_id': 'proj2-id-c',
                        },

                        # Seen failure (not updated).
                        {
                            'name': 'proj3',
                            'finish_time': '2018-01-31T00:00:00.000000Z',
                            'build_id': 'proj3-id-c',
                        },

                        # Seen failure (third consecutive, bug already filed).
                        {
                            'name': 'proj4',
                            'finish_time': '2018-02-01T00:00:00.000000Z',
                            'build_id': 'proj4-id-c',
                        },

                        # Coverage build type is broken for a while.
                        {
                            'name': 'proj5',
                            'finish_time': '2018-02-01T00:00:00.000000Z',
                            'build_id': 'proj5-id-c',
                        },

                        # Only coverage build type broken (second consecutive).
                        {
                            'name': 'proj6',
                            'finish_time': '2018-02-01T00:00:00.000000Z',
                            'build_id': 'proj6-id-c',
                        },
                    ],
                }))

        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')
        self.assertItemsEqual([
            {
                '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]
        self.assertItemsEqual(['*****@*****.**'], issue.cc)
        self.assertEqual('New', issue.status)
        self.assertEqual('proj2: 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://github.com/google/oss-fuzz/'
            'blob/master/docs/reproducing.md#reproducing-build-failures\n\n'
            'If you have any questions, please file a bug on '
            '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]
        self.assertItemsEqual(['*****@*****.**'], issue.cc)
        self.assertEqual('New', issue.status)
        self.assertEqual('proj6: 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://github.com/google/oss-fuzz/'
            'blob/master/docs/reproducing.md#reproducing-build-failures\n\n'
            'If you have any questions, please file a bug on '
            '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'))
Beispiel #13
0
  def setUp(self):
    test_helpers.patch_environ(self)
    test_helpers.patch(self, [
        'base.utils.is_oss_fuzz',
        'handlers.cron.helpers.bot_manager.BotManager',
        'system.environment.is_running_on_app_engine',
        'google.appengine.api.app_identity.get_application_id',
        '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.get_application_id.return_value = 'clusterfuzz-external'
    self.mock.load_project.return_value = compute_engine_projects.Project(
        project_id='clusterfuzz-external',
        clusters=[
            compute_engine_projects.Cluster(
                name='oss-fuzz-linux-zone2-pre',
                gce_zone='us-east2-a',
                instance_count=997,
                instance_template='external-pre-zone2',
                distribute=True,
                worker=False,
                high_end=False),
            compute_engine_projects.Cluster(
                name='oss-fuzz-linux-zone3-host',
                gce_zone='us-central1-d',
                instance_count=2,
                instance_template='host-zone3',
                distribute=False,
                worker=False,
                high_end=False),
            compute_engine_projects.Cluster(
                name='oss-fuzz-linux-zone3-worker',
                gce_zone='us-central1-d',
                instance_count=16,
                instance_template='worker-zone3',
                distribute=True,
                worker=True,
                high_end=False),
            compute_engine_projects.Cluster(
                name='oss-fuzz-linux-zone3-host-high-end',
                gce_zone='us-central1-d',
                instance_count=1,
                instance_template='host-high-end-zone3',
                distribute=False,
                worker=False,
                high_end=True),
            compute_engine_projects.Cluster(
                name='oss-fuzz-linux-zone3-worker-high-end',
                gce_zone='us-central1-d',
                instance_count=2,
                instance_template='worker-zone3',
                distribute=True,
                worker=True,
                high_end=True),
        ],
        instance_templates=[
            {
                'name': 'external-pre-zone2',
                'description': '{"version": 1}',
                'properties': {
                    'metadata': {
                        'items': [],
                    },
                    'disks': [{
                        'initializeParams': {
                            'diskSizeGb': 30,
                        },
                    }],
                    'serviceAccounts': [{
                        'email':
                            'email',
                        'scopes': [
                            'https://www.googleapis.com/auth/'
                            'devstorage.full_control',
                            'https://www.googleapis.com/auth/logging.write',
                            'https://www.googleapis.com/auth/userinfo.email',
                            'https://www.googleapis.com/auth/appengine.apis',
                            'https://www.googleapis.com/auth/prodxmon',
                            'https://www.googleapis.com/auth/bigquery',
                        ]
                    }],
                }
            },
            {
                'name': 'host-zone3',
                'description': '{"version": 1}',
                'properties': {
                    'metadata': {
                        'items': [],
                    },
                    'disks': [{
                        'initializeParams': {
                            'diskSizeGb': 30,
                        },
                    }],
                    'serviceAccounts': [{
                        'email':
                            'email',
                        'scopes': [
                            'https://www.googleapis.com/auth/'
                            'devstorage.full_control',
                            'https://www.googleapis.com/auth/logging.write',
                            'https://www.googleapis.com/auth/userinfo.email',
                            'https://www.googleapis.com/auth/appengine.apis',
                            'https://www.googleapis.com/auth/prodxmon',
                            'https://www.googleapis.com/auth/bigquery',
                        ]
                    }],
                }
            },
            {
                'name': 'worker-zone3',
                'description': '{"version": 1}',
                'properties': {
                    'metadata': {
                        'items': [],
                    },
                    'disks': [{
                        'initializeParams': {
                            'diskSizeGb': 30,
                        },
                    }],
                    'serviceAccounts': [{
                        'email':
                            'email',
                        'scopes': [
                            'https://www.googleapis.com/auth/'
                            'devstorage.full_control',
                            'https://www.googleapis.com/auth/logging.write',
                            'https://www.googleapis.com/auth/userinfo.email',
                            'https://www.googleapis.com/auth/prodxmon',
                        ]
                    }],
                }
            },
            {
                'name': 'host-high-end-zone3',
                'description': '{"version": 1}',
                'properties': {
                    'metadata': {
                        'items': [],
                    },
                    'disks': [{
                        'initializeParams': {
                            'diskSizeGb': 100,
                        },
                    }],
                    'serviceAccounts': [{
                        'email':
                            'email',
                        'scopes': [
                            'https://www.googleapis.com/auth/'
                            'devstorage.full_control',
                            'https://www.googleapis.com/auth/logging.write',
                            'https://www.googleapis.com/auth/userinfo.email',
                            'https://www.googleapis.com/auth/prodxmon',
                        ]
                    }],
                }
            },
        ],
        host_worker_assignments=[
            compute_engine_projects.HostWorkerAssignment(
                host='oss-fuzz-linux-zone3-host',
                worker='oss-fuzz-linux-zone3-worker',
                workers_per_host=8),
            compute_engine_projects.HostWorkerAssignment(
                host='oss-fuzz-linux-zone3-host-high-end',
                worker='oss-fuzz-linux-zone3-worker-high-end',
                workers_per_host=2),
        ])

    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 + '_cert',
          key_contents=project_name + '_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 setUp(self):
    self.app = webtest.TestApp(
        webapp2.WSGIApplication([('/setup', oss_fuzz_setup.Handler)]))

    helpers.patch_environ(self)
    data_types.Config(
        revision_vars_url=('libfuzzer_asan_lib2;url\n'
                           'blah;url2\n')).put()

    data_types.Job(
        name='libfuzzer_asan_old_job',
        environment_string=('MANAGED = True\n'
                            'PROJECT_NAME = old\n')).put()
    data_types.Job(
        name='libfuzzer_msan_old_job',
        environment_string=('MANAGED = True\n'
                            'PROJECT_NAME = old\n')).put()
    data_types.Job(name='unmanaged_job', environment_string='').put()

    # Will be removed.
    data_types.ExternalUserPermission(
        entity_kind=data_types.PermissionEntityKind.JOB,
        is_prefix=False,
        auto_cc=data_types.AutoCCType.ALL,
        entity_name='libfuzzer_asan_lib1',
        email='*****@*****.**').put()

    # Existing CC. Makes sure no duplicates are created.
    data_types.ExternalUserPermission(
        entity_kind=data_types.PermissionEntityKind.JOB,
        is_prefix=False,
        auto_cc=data_types.AutoCCType.ALL,
        entity_name='libfuzzer_asan_lib1',
        email='*****@*****.**').put()

    # Existing project settings. Should not get modified.
    data_types.OssFuzzProject(id='lib1', name='lib1', cpu_weight=1.5).put()

    # Should get deleted.
    data_types.OssFuzzProject(id='old_lib', name='old_lib').put()

    self.libfuzzer = data_types.Fuzzer(name='libFuzzer', jobs=[])
    self.libfuzzer.data_bundle_name = 'global'
    self.libfuzzer.jobs = ['libfuzzer_asan_old_job', 'libfuzzer_msan_old_job']
    self.libfuzzer.put()

    self.afl = data_types.Fuzzer(name='afl', jobs=[])
    self.afl.data_bundle_name = 'global'
    self.afl.jobs = ['afl_asan_old_job', 'afl_msan_old_job']
    self.afl.put()

    helpers.patch(self, [
        'base.utils.is_oss_fuzz',
        ('get_application_id_1',
         'google.appengine.api.app_identity.get_application_id'),
        ('get_application_id_2', 'base.utils.get_application_id'),
        'google_cloud_utils.storage.build',
        'time.sleep',
        'handlers.base_handler.Handler.is_cron',
        'handlers.cron.oss_fuzz_setup.get_projects',
        'handlers.cron.service_accounts.get_or_create_service_account',
        'handlers.cron.service_accounts.set_service_account_roles',
    ])

    self.mock.get_or_create_service_account.side_effect = (
        _mock_get_or_create_service_account)

    self.mock.is_oss_fuzz.return_value = True