Ejemplo n.º 1
0
def test_delete_cluster_with_cleanup_disk_left(gke_mock, mocker):
    """Test that disk is deleted even if k8s did not delete it"""
    def mocked_get_disks(cfg, dry_run):
        """Mocked getting GCP disks"""
        return GCP_DISKS

    def mocked_delete_disk(name, cfg):
        """Mocked GCP disk deletion"""
        pass

    def mocked_delete_cluster(cfg):
        """Mocked deletion of GKE cluster"""
        return GKE_CLUSTERS[0]

    def mocked_get_persistent_disks(dry_run):
        """Mocked listing of kubernets persistent disks"""
        # persistent disk to delete
        return [GCP_DISKS[0]]

    mocker.patch('elb.gcp.get_disks', side_effect=mocked_get_disks)
    mocker.patch('elb.gcp.delete_disk', side_effect=mocked_delete_disk)
    mocker.patch('elb.gcp.delete_cluster', side_effect=mocked_delete_cluster)
    mocker.patch('elb.kubernetes.get_persistent_disks',
                 side_effect=mocked_get_persistent_disks)

    cfg = get_mocked_config()
    gcp.delete_cluster_with_cleanup(cfg)
    gcp.safe_exec.assert_called()
    kubernetes.get_persistent_disks.assert_called()
    # test that GCP disk deletion was called for the appropriate disk
    gcp.delete_disk.assert_called_with(GCP_DISKS[0], cfg)
    # test that cluster deletion was called
    gcp.delete_cluster.assert_called_with(cfg)
Ejemplo n.º 2
0
def test_delete_cluster_with_cleanup_cluster_reconciling(gke_mock, mocker):
    """Test that cluster status RECONCILING is handled when deleting the
    cluster. The code should wait until cluster status is RUNNING and delete
    it then."""
    class GKEStatusMock:
        """Class to mock changin GKE cluster status"""
        def __init__(self):
            self.status = 'RECONCILING'

        def mocked_check_cluster(self, cfg):
            """Mocked check cluster status. Returns RECONCILING the first time
            and RUNNING after that"""
            if self.status == 'RECONCILING':
                self.status = 'RUNNING'
                return 'RECONCILING'
            return self.status

    def mocked_delete_cluster(cfg):
        """Mocked cluster deletion"""
        return cfg.cluster.name

    mocked_cluster = GKEStatusMock()
    mocker.patch('elb.gcp.check_cluster',
                 side_effect=mocked_cluster.mocked_check_cluster)
    mocker.patch('elb.gcp.delete_cluster', side_effect=mocked_delete_cluster)

    cfg = get_mocked_config()
    gcp.delete_cluster_with_cleanup(cfg)
    # test that gcp.check_cluster was called more than once
    assert gcp.check_cluster.call_count > 1
    # test that cluster deletion was called
    gcp.delete_cluster.assert_called()
Ejemplo n.º 3
0
def test_delete_cluster_with_cleanup_no_cluster(gke_mock):
    """Test deleting GKE cluster with cleanup when no cluster is present"""
    # no cluster found in GKE
    gke_mock.set_options(['no-cluster'])

    cfg = get_mocked_config()
    with pytest.raises(SafeExecError):
        gcp.delete_cluster_with_cleanup(cfg)
    gcp.safe_exec.assert_called()
Ejemplo n.º 4
0
def test_get_gke_clusters_empty(mocker):
    """Test listing GKE clusters for an empty list"""
    def safe_exec_empty(cmd):
        """Mocked safe_exec returning an emty JSON list"""
        return MockedCompletedProcess('[]')

    mocker.patch('elb.gcp.safe_exec', side_effect=safe_exec_empty)
    cfg = get_mocked_config()
    assert len(gcp.get_gke_clusters(cfg)) == 0
    gcp.safe_exec.assert_called()
Ejemplo n.º 5
0
def test_get_disks_bad_output(mocker):
    """Test that gcp.get_disks raises RuntimeError for bad gcloud output"""
    def safe_exec_bad_gcloud(cmd):
        """Mocked util.safe_exec function that returns incorrect JSON"""
        if not cmd.startswith('gcloud compute disks list --format json'):
            raise ValueError(f'Bad gcloud command line: {cmd}')
        return MockedCompletedProcess('some-non-json-string')

    mocker.patch('elb.gcp.safe_exec', side_effect=safe_exec_bad_gcloud)
    cfg = get_mocked_config()
    with pytest.raises(RuntimeError):
        gcp.get_disks(cfg)
    gcp.safe_exec.assert_called()
Ejemplo n.º 6
0
def test_delete_cluster_with_cleanup_cluster_stopping(gke_mock, mocker):
    """Test deleting cluster with the cluster is beeing stopped. The code
    should raise RuntimeError"""
    def mocked_check_cluster(cfg):
        """Mocked check cluster status. STOPPING never changes to RUNNING."""
        return 'STOPPING'

    mocker.patch('elb.gcp.check_cluster', side_effect=mocked_check_cluster)
    cfg = get_mocked_config()
    with pytest.raises(UserReportError) as errinfo:
        gcp.delete_cluster_with_cleanup(cfg)

    # test return code and message in UserReportError
    assert errinfo.value.returncode == CLUSTER_ERROR
    assert GKE_CLUSTERS[0] in errinfo.value.message
    assert 'already being deleted' in errinfo.value.message
Ejemplo n.º 7
0
def test_delete_cluster_with_cleanup_failed_kubectl(gke_mock, mocker):
    """Test that cluster deletion is called when we cannot communicate with
    it with kubectl"""
    def mocked_delete_cluster(cfg):
        """Mocked cluster deletion"""
        return GKE_CLUSTERS[0]

    # any kubectl call fails
    gke_mock.set_options(['kubectl-error'])
    mocker.patch('elb.gcp.delete_cluster', side_effect=mocked_delete_cluster)

    cfg = get_mocked_config()
    gcp.delete_cluster_with_cleanup(cfg)
    kubernetes.safe_exec.assert_called()
    # test cluster deletion was called
    gcp.delete_cluster.assert_called_with(cfg)
Ejemplo n.º 8
0
def test_delete_nonexistent_disk(mocker):
    """Test that deleting a GCP disk that does not exits raises util.SafeExecError"""
    def fake_subprocess_run(cmd, check, stdout, stderr):
        """Fake subprocess.run function that raises exception and emulates
        command line returning with a non-zero exit code"""
        raise subprocess.CalledProcessError(returncode=1,
                                            cmd=cmd,
                                            output=b'',
                                            stderr=b'')

    mocker.patch('subprocess.run', side_effect=fake_subprocess_run)

    cfg = get_mocked_config()
    with pytest.raises(SafeExecError):
        gcp.delete_disk('some-disk', cfg)
    subprocess.run.assert_called()
Ejemplo n.º 9
0
def test_delete_cluster_with_cleanup_cluster_error(gke_mock, mocker):
    """Test deleting a cluster with ERROR status"""
    def mocked_check_cluster(cfg):
        """Mocked checking cluster status"""
        return 'ERROR'

    def mocked_delete_cluster(cfg):
        """Mocked cluster deletion only to verify that it was called"""
        return cfg.cluster.name

    mocker.patch('elb.gcp.check_cluster', side_effect=mocked_check_cluster)
    mocker.patch('elb.gcp.delete_cluster', side_effect=mocked_delete_cluster)
    cfg = get_mocked_config()
    gcp.delete_cluster_with_cleanup(cfg)
    gcp.check_cluster.assert_called()
    # cluster deletion must be called
    gcp.delete_cluster.assert_called()
Ejemplo n.º 10
0
def test_delete_cluster_with_cleanup_failed_get_disks(gke_mock, mocker):
    """Test that cluster and disk deletion are called when getting a list of
    GCP disks failed"""
    def mocked_get_disks(cfg, dry_run):
        """Mocked listing of GCP disks"""
        mocked_get_disks.invocation_counter += 1
        if mocked_get_disks.invocation_counter == 1:
            raise RuntimeError('Mocked GCP listing error')
        pass

    mocked_get_disks.invocation_counter = 0

    def mocked_delete_cluster(cfg):
        """Mocked cluster deletion"""
        return GKE_CLUSTERS[0]

    def mocked_delete_disk(name, cfg):
        """Mocked disk deletion"""
        pass

    def mocked_get_persistent_disks(dry_run):
        """Mocked listing of GKE cluster persistent disks"""
        return [GCP_DISKS[0]]

    mocker.patch('elb.gcp.get_disks', side_effect=mocked_get_disks)
    mocker.patch('elb.gcp.delete_cluster', side_effect=mocked_delete_cluster)
    mocker.patch('elb.gcp.delete_disk', side_effect=mocked_delete_disk)
    mocker.patch('elb.kubernetes.get_persistent_disks',
                 side_effect=mocked_get_persistent_disks)

    cfg = get_mocked_config()
    gcp.delete_cluster_with_cleanup(cfg)
    gcp.safe_exec.assert_called()
    kubernetes.safe_exec.assert_called()
    # test cluster deletion was called
    gcp.delete_cluster.assert_called_with(cfg)
    # test that disk deletion was called
    gcp.delete_disk.assert_called_with(GCP_DISKS[0], cfg)
Ejemplo n.º 11
0
def test_delete_cluster_with_cleanup_disk_known(gke_mock, mocker):
    """Test deleting cluster and persistent disk when disk id is known"""
    def mocked_delete_cluster(cfg):
        """Mocked cluster deletion, to test that it was called"""
        pass

    def mocked_delete_disk(name, cfg):
        """Mocked disk deletion, to test that it was called"""
        pass

    def mocked_delete_all():
        """Mocked deletion of all kubernetes jobs and persistent disks"""
        raise RuntimeError('It should not have been called')

    mocker.patch('elb.gcp.delete_cluster', side_effect=mocked_delete_cluster)
    mocker.patch('elb.gcp.delete_disk', side_effect=mocked_delete_disk)
    mocker.patch('elb.kubernetes.delete_all', side_effect=mocked_delete_all)

    cfg = get_mocked_config()
    cfg.appstate.disk_id = GCP_DISKS[0]
    gcp.delete_cluster_with_cleanup(cfg)
    gcp.delete_cluster.assert_called()
    gcp.delete_disk.assert_called_with(cfg.appstate.disk_id, cfg)
Ejemplo n.º 12
0
def test_get_disks(gke_mock):
    """Test getting a list of GCP persistent disks"""
    cfg = get_mocked_config()
    disks = gcp.get_disks(cfg)
    assert sorted(disks) == sorted(GCP_DISKS)
    gcp.safe_exec.assert_called()
Ejemplo n.º 13
0
def test_delete_cluster_with_cleanup(gke_mock):
    """Test deleting GKE cluster and its persistent disks"""
    cfg = get_mocked_config()
    gcp.delete_cluster_with_cleanup(cfg)
    gcp.safe_exec.assert_called()
    kubernetes.safe_exec.assert_called()
Ejemplo n.º 14
0
def test_get_gke_clusters(gke_mock):
    """Test listing GKE clusters"""
    cfg = get_mocked_config()
    clusters = gcp.get_gke_clusters(cfg)
    assert sorted(clusters) == sorted(GKE_CLUSTERS)
    gcp.safe_exec.assert_called()
Ejemplo n.º 15
0
def test_delete_disk_empty_name():
    """Test that deleting disk with and empty name results in ValueError"""
    cfg = get_mocked_config()
    with pytest.raises(ValueError):
        gcp.delete_disk('', cfg)
Ejemplo n.º 16
0
def test_delete_disk(gke_mock):
    """Test deleting a GCP disk"""
    cfg = get_mocked_config()
    gcp.delete_disk(GCP_DISKS[0], cfg)
    gcp.safe_exec.assert_called()