Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Migrate the implementation for pods.exec and jobs.wait to helpers #93

Merged
merged 1 commit into from
Apr 19, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 8 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -322,14 +322,14 @@ export default function () {

### (Deprecated) `Client.jobs`

| Method | Description | Example |
| ------------ | ------ | --------------------------------------- |
| apply | creates the Kubernetes resource given a YAML configuration ||
| create | creates the Kubernetes resource given an object configuration | [create-job-wait.js](./examples/create-job-wait.js) |
| delete | removes the named Job | |
| get | returns the named Jobs | |
| list | returns a collection of Jobs | |
| wait | wait for all Jobs to complete | [wait-job.js](./examples/wait-job.js) |
| Method | Description |
| ------------ | ------ |
| apply | creates the Kubernetes resource given a YAML configuration |
| create | creates the Kubernetes resource given an object configuration |
| delete | removes the named Job |
| get | returns the named Jobs |
| list | returns a collection of Jobs |
| wait | wait for all Jobs to complete |

```javascript
import { Kubernetes } from 'k6/x/kubernetes';
Expand Down
29 changes: 0 additions & 29 deletions examples/create-job-wait.js

This file was deleted.

42 changes: 0 additions & 42 deletions examples/exec-command.js

This file was deleted.

14 changes: 8 additions & 6 deletions examples/job_operations.js
Original file line number Diff line number Diff line change
Expand Up @@ -52,23 +52,25 @@ export default function () {
describe('JSON-based resources', () => {
const name = json.metadata.name
const ns = json.metadata.namespace
const helpers = kubernetes.helpers(ns)

let job

describe('Create our job using the JSON definition', () => {
describe('Create our job using the JSON definition and wait until completed', () => {
job = kubernetes.create(json)
expect(job.metadata, 'new job').to.have.property('uid')
})

describe('Retrieve all available jobs', () => {
expect(kubernetes.list("Job.batch", ns).length, 'total jobs').to.be.at.least(1)
})
let timeout = 10
expect(helpers.waitJobCompleted(name, timeout), `job completion within ${timeout}s`).to.be.true

describe('Retrieve our job by name and namespace', () => {
let fetched = kubernetes.get("Job.batch", name, ns)
expect(job.metadata.uid, 'created and fetched uids').to.equal(fetched.metadata.uid)
})

describe('Retrieve all available jobs', () => {
expect(kubernetes.list("Job.batch", ns).length, 'total jobs').to.be.at.least(1)
})

describe('Remove our jobs to cleanup', () => {
kubernetes.delete("Job.batch", name, ns)
})
Expand Down
14 changes: 13 additions & 1 deletion examples/pod_operations.js
Original file line number Diff line number Diff line change
Expand Up @@ -58,9 +58,21 @@ export default function () {
expect(kubernetes.list("Pod", ns).length, 'total pods').to.be.at.least(1)
})

describe('Retrieve our pod by name and namespace', () => {
describe('Retrieve our pod by name and namespace, then execute a command within the pod', () => {
let fetched = kubernetes.get("Pod", name, ns)
expect(pod.metadata.uid, 'created and fetched uids').to.equal(fetched.metadata.uid)

let greeting = 'hello xk6-kubernetes'
let exec = {
pod: name,
container: fetched.spec.containers[0].name,
command: ["echo", greeting]
}
let result = helpers.executeInPod(exec)
const stdout = String.fromCharCode(...result.stdout)
const stderr = String.fromCharCode(...result.stderr)
expect(stdout, 'execution result').to.contain(greeting)
expect(stderr, 'execution error').to.be.empty
})

describe('Remove our pods to cleanup', () => {
Expand Down
34 changes: 0 additions & 34 deletions examples/wait-job.js

This file was deleted.

6 changes: 6 additions & 0 deletions internal/testutils/fake.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package testutils

import (
"fmt"
k8s "k8s.io/client-go/kubernetes"

"k8s.io/apimachinery/pkg/api/meta"
"k8s.io/apimachinery/pkg/runtime"
Expand All @@ -10,6 +11,11 @@ import (
"k8s.io/client-go/kubernetes/fake"
)

// NewFakeClientset creates a new instance of a fake Kubernetes clientset
func NewFakeClientset(objs ...runtime.Object) k8s.Interface {
return fake.NewSimpleClientset(objs...)
}

// NewFakeDynamic creates a new instance of a fake dynamic client with a default scheme
func NewFakeDynamic(objs ...runtime.Object) (*dynamicfake.FakeDynamicClient, error) {
scheme := runtime.NewScheme()
Expand Down
12 changes: 7 additions & 5 deletions kubernetes.go
Original file line number Diff line number Diff line change
Expand Up @@ -135,8 +135,9 @@ func (mi *ModuleInstance) newClient(c goja.ConstructorCall) *goja.Object {
if mi.dynamic == nil {
k8s, err := api.NewFromConfig(
api.KubernetesConfig{
Config: config,
Context: ctx,
Clientset: obj.client,
Config: config,
Context: ctx,
},
)
if err != nil {
Expand All @@ -147,9 +148,10 @@ func (mi *ModuleInstance) newClient(c goja.ConstructorCall) *goja.Object {
// Pre-configured dynamic client and RESTMapper are injected for unit testing
k8s, err := api.NewFromConfig(
api.KubernetesConfig{
Client: mi.dynamic,
Mapper: mi.mapper,
Context: ctx,
Clientset: obj.client,
Client: mi.dynamic,
Mapper: mi.mapper,
Context: ctx,
},
)
if err != nil {
Expand Down
3 changes: 1 addition & 2 deletions kubernetes_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ import (
"go.k6.io/k6/lib/testutils"
"go.k6.io/k6/metrics"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/client-go/kubernetes/fake"
)

// setupTestEnv should be called from each test to build the execution environment for the test
Expand Down Expand Up @@ -49,7 +48,7 @@ func setupTestEnv(t *testing.T, objs ...runtime.Object) *goja.Runtime {
require.True(t, ok)
require.NoError(t, rt.Set("Kubernetes", m.Exports().Named["Kubernetes"]))

m.clientset = fake.NewSimpleClientset(objs...)
m.clientset = localutils.NewFakeClientset(objs...)

dynamic, err := localutils.NewFakeDynamic()
if err != nil {
Expand Down
15 changes: 12 additions & 3 deletions pkg/api/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ package api

import (
"context"
k8s "k8s.io/client-go/kubernetes"

"github.com/grafana/xk6-kubernetes/pkg/helpers"
"github.com/grafana/xk6-kubernetes/pkg/resources"
Expand All @@ -30,6 +31,8 @@ type KubernetesConfig struct {
Context context.Context
// kubernetes rest config
Config *rest.Config
// Clientset provides access to various API-specific clients
Clientset k8s.Interface
// Client is a pre-configured dynamic client. If provided, the rest config is not used
Client dynamic.Interface
// Mapper is a pre-configured RESTMapper. If provided, the rest config is not used
Expand All @@ -38,8 +41,10 @@ type KubernetesConfig struct {

// kubernetes holds references to implementation of the Kubernetes interface
type kubernetes struct {
ctx context.Context
ctx context.Context
Clientset k8s.Interface
*resources.Client
Config *rest.Config
*restmapper.DeferredDiscoveryRESTMapper
}

Expand Down Expand Up @@ -75,8 +80,10 @@ func NewFromConfig(c KubernetesConfig) (Kubernetes, error) {
}

return &kubernetes{
ctx: ctx,
Client: client,
ctx: ctx,
Clientset: c.Clientset,
Client: client,
Config: c.Config,
}, nil
}

Expand All @@ -86,7 +93,9 @@ func (k *kubernetes) Helpers(namespace string) helpers.Helpers {
}
return helpers.NewHelper(
k.ctx,
k.Clientset,
k.Client,
k.Config,
namespace,
)
}
11 changes: 9 additions & 2 deletions pkg/helpers/helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,27 +3,34 @@ package helpers

import (
"context"
k8s "k8s.io/client-go/kubernetes"

"github.com/grafana/xk6-kubernetes/pkg/resources"
"k8s.io/client-go/rest"
)

// Helpers offers Helper functions grouped by the objects they handle
type Helpers interface {
JobHelper
PodHelper
ServiceHelper
}

// helpers struct holds the data required by the helpers
type helpers struct {
client *resources.Client
clientset k8s.Interface
config *rest.Config
ctx context.Context
namespace string
}

// NewHelper creates a set of helper functions on the default namespace
func NewHelper(ctx context.Context, client *resources.Client, namespace string) Helpers {
// NewHelper creates a set of helper functions on the specified namespace
func NewHelper(ctx context.Context, clientset k8s.Interface, client *resources.Client, config *rest.Config, namespace string) Helpers {
return &helpers{
client: client,
clientset: clientset,
config: config,
ctx: ctx,
namespace: namespace,
}
Expand Down
Loading