Net-Async-Kubernetes

 view release on metacpan or  search on metacpan

t/10-dual-crud.t  view on Meta::CPAN

    is($patched->metadata->labels->{patched_by}, 'perl', 'label applied');

    unless (is_live()) {
        my $req = MockTransport::last_request();
        is($req->{method}, 'PATCH', 'used PATCH method');
        like($req->{headers}{'Content-Type'}, qr{strategic-merge-patch},
             'strategic merge patch content type');
    }
};

subtest 'patch Deployment with merge type' => sub {
    unless (is_live()) {
        MockTransport::mock_response('PATCH',
            "/apis/apps/v1/namespaces/$NS/deployments/demo-nginx", {
            kind => 'Deployment', apiVersion => 'apps/v1',
            metadata => { name => 'demo-nginx', namespace => $NS,
                          uid => 'dep-uid-001', resourceVersion => '103',
                          labels => { app => 'demo-app', patched_by => 'perl' },
                          annotations => { 'demo.perl/patched' => 'true' } },
            spec => {
                replicas => 3,
                selector => { matchLabels => { app => 'demo-app' } },
                template => {
                    metadata => { labels => { app => 'demo-app' } },
                    spec => { containers => [{ name => 'nginx', image => 'nginx:1.27-alpine' }] },
                },
            },
            status => {},
        });
    }
    my $patched = $kube->patch('Deployment', 'demo-nginx',
        namespace => $NS,
        type      => 'merge',
        patch     => {
            metadata => { annotations => { 'demo.perl/patched' => 'true' } },
        },
    )->get;
    ok($patched, 'merge patch returned object');
    is($patched->metadata->annotations->{'demo.perl/patched'}, 'true', 'annotation applied');

    unless (is_live()) {
        my $req = MockTransport::last_request();
        like($req->{headers}{'Content-Type'}, qr{merge-patch},
             'merge patch content type');
    }
};

# ============================================================================
# Create Job + CronJob
# ============================================================================

subtest 'create Job' => sub {
    unless (is_live()) {
        MockTransport::mock_response('POST',
            "/apis/batch/v1/namespaces/$NS/jobs", {
            kind => 'Job', apiVersion => 'batch/v1',
            metadata => { name => 'demo-job', namespace => $NS,
                          uid => 'job-uid-001', creationTimestamp => '2025-01-01T00:00:00Z' },
            spec => { backoffLimit => 2,
                      template => { spec => { restartPolicy => 'Never',
                        containers => [{ name => 'worker', image => 'busybox:latest' }] } } },
            status => {},
        });
    }
    my $job = $kube->_rest->new_object(Job =>
        metadata => { name => 'demo-job', namespace => $NS },
        spec => { backoffLimit => 2,
                  template => { spec => { restartPolicy => 'Never',
                    containers => [{ name => 'worker', image => 'busybox:latest',
                                     command => ['echo', 'hello'] }] } } },
    );
    my $created = $kube->create($job)->get;
    ok($created, 'Job created');
    is($created->metadata->name, 'demo-job', 'name matches');
};

subtest 'create CronJob' => sub {
    unless (is_live()) {
        MockTransport::mock_response('POST',
            "/apis/batch/v1/namespaces/$NS/cronjobs", {
            kind => 'CronJob', apiVersion => 'batch/v1',
            metadata => { name => 'demo-cronjob', namespace => $NS,
                          uid => 'cj-uid-001', creationTimestamp => '2025-01-01T00:00:00Z' },
            spec => { schedule => '*/5 * * * *',
                      jobTemplate => { spec => { template => { spec => {
                        restartPolicy => 'OnFailure',
                        containers => [{ name => 'cron', image => 'busybox:latest' }] } } } } },
        });
    }
    my $cj = $kube->_rest->new_object(CronJob =>
        metadata => { name => 'demo-cronjob', namespace => $NS },
        spec => { schedule => '*/5 * * * *',
                  jobTemplate => { spec => { template => { spec => {
                    restartPolicy => 'OnFailure',
                    containers => [{ name => 'cron', image => 'busybox:latest',
                                     command => ['echo', 'tick'] }] } } } } },
    );
    my $created = $kube->create($cj)->get;
    ok($created, 'CronJob created');
    is($created->metadata->name, 'demo-cronjob', 'name matches');
};

# ============================================================================
# List resources
# ============================================================================

subtest 'list ConfigMaps in namespace' => sub {
    unless (is_live()) {
        MockTransport::mock_response('GET',
            "/api/v1/namespaces/$NS/configmaps", {
            kind => 'ConfigMapList', apiVersion => 'v1',
            items => [
                { kind => 'ConfigMap', apiVersion => 'v1',
                  metadata => { name => 'app-config', namespace => $NS },
                  data => { 'app.env' => 'staging' } },
            ],
        });
    }
    my $list = $kube->list('ConfigMap', namespace => $NS)->get;
    isa_ok($list, 'IO::K8s::List');
    ok(scalar @{$list->items} >= 1, 'got at least 1 configmap');
    my @names = map { $_->metadata->name } @{$list->items};
    ok(grep({ $_ eq 'app-config' } @names), 'app-config in list');
};

subtest 'list Deployments in namespace' => sub {
    unless (is_live()) {
        MockTransport::mock_response('GET',
            "/apis/apps/v1/namespaces/$NS/deployments", {
            kind => 'DeploymentList', apiVersion => 'apps/v1',
            items => [
                { kind => 'Deployment', apiVersion => 'apps/v1',
                  metadata => { name => 'demo-nginx', namespace => $NS },
                  spec => { replicas => 3,
                            selector => { matchLabels => { app => 'demo-app' } },
                            template => { metadata => { labels => { app => 'demo-app' } },
                                          spec => { containers => [{ name => 'nginx', image => 'nginx' }] } } },
                  status => {} },
            ],
        });
    }
    my $list = $kube->list('Deployment', namespace => $NS)->get;
    ok(scalar @{$list->items} >= 1, 'got at least 1 deployment');
    my @names = map { $_->metadata->name } @{$list->items};
    ok(grep({ $_ eq 'demo-nginx' } @names), 'demo-nginx in list');
};

# ============================================================================
# Serialization roundtrip
# ============================================================================

subtest 'serialization roundtrip' => sub {
    unless (is_live()) {
        MockTransport::mock_response('GET',
            "/apis/apps/v1/namespaces/$NS/deployments/demo-nginx", {



( run in 1.006 second using v1.01-cache-2.11-cpan-f4a522933cf )