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

Add helpers #72

Merged
merged 20 commits into from
Oct 11, 2022
Merged
Show file tree
Hide file tree
Changes from 19 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
63 changes: 63 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ This API offers methods for creating, retrieving, listing and deleting resources
| | namespace |
| list | kind| returns a collection of resources of a given kind
| | namespace |
| update | spec object | updates an existing resource
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should apply simply perform either a create or update depending upon existence? Have explicit calls to create fail if a resource is already there.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Apply recieves a yaml. Update receives an object. These are two different operations.



The kinds of resources currently supported are:
Expand Down Expand Up @@ -154,6 +155,68 @@ export default function () {
}
```

## Helpers

The `xk6-kubernetes` extension offers helpers to facilitate common tasks when setting up a tests. All helper functions work in a namespace to facilitate the development of tests segregated by namespace. The helpers are accessed using the following method:

| Method | Parameters| Description |
| -------------| ---| ------ |
| helpers | namespace | returns helpers that operate in the given namespace. If none is specified, "default" is used |

The methods above return an object that implements the following helper functions:

| Method | Parameters| Description |
| ------------ | --------| ------ |
| getExternalIP | service | returns the external IP of a service if any is assigned before timeout expires|
| | timeout in seconds | |
| waitPodRunning | pod name | waits until the pod is in 'Running' state or the timeout expires. Returns a boolean indicating of the pod was ready or not. Throws an error if the pod is Failed. |
| | timeout in seconds | |
| waitServiceReady | service name | waits until the given service has at least one endpoint ready or the timeout expires |
| | timeout in seconds | |



### Examples

### Creating a pod in a random namespace and wait until it is running

```javascript
import { Kubernetes } from 'k6/x/kubernetes';

let podSpec = {
apiVersion: "v1",
kind: "Pod",
metadata: {
name: "busybox",
namespace: "default"
},
spec: {
containers: [
{
name: "busybox",
image: "busybox",
command: ["sh", "-c", "sleep 30"]
}
]
}
}

export default function () {
const kubernetes = new Kubernetes();

// create pod
kubernetes.create(pod)

// get helpers for test namespace
const helpers = kubernetes.helpers()

// wait for pod to be running
const timeout = 10
if (!helpers.waitPodRunning(pod.metadata.name, timeout)) {
console.log(`"pod ${pod.metadata.name} not ready after ${timeout} seconds`)
}
}

## Resource kind helpers

This API offers a helper for each kind of Kubernetes resources supported (Pods, Deployments, Secrets, et cetera). For each one, an interface for creating, getting, listing and deleting objects is offered.
Expand Down
40 changes: 40 additions & 0 deletions examples/wait_pod_running.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import { Kubernetes } from 'k6/x/kubernetes';

let pod = {
apiVersion: "v1",
kind: "Pod",
metadata: {
name: "busybox",
namespace: "default"
},
spec: {
containers: [
{
name: "busybox",
image: "busybox",
command: ["sh", "-c", "sleep 30"]
}
]
}
}

export default function () {
const kubernetes = new Kubernetes();

// create namespace with random name with prefix 'test-'
const ns = kubernetes.helpers().createRandomNamespace("test-")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Script needs to be updated for latest changes. The createRandomNamespace method is no longer valid.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch. Fixed

//const ns = "default"

// create pod in test namespace
pod.metadata.namespace = ns
kubernetes.create(pod)

// get helpers for test namespace
const helpers = kubernetes.namespacedHelpers(ns)

// wait for pod to be running
const timeout = 10
if (!helpers.waitPodRunning(pod.metadata.name, timeout)) {
console.log(`"pod ${pod.metadata.name} not ready after ${timeout} seconds`)
}
}
5 changes: 3 additions & 2 deletions internal/testutils/fake.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,12 @@ import (
)

// NewFakeDynamic creates a new instance of a fake dynamic client with a default scheme
func NewFakeDynamic() (*dynamicfake.FakeDynamicClient, error) {
func NewFakeDynamic(objs ...runtime.Object) (*dynamicfake.FakeDynamicClient, error) {
scheme := runtime.NewScheme()
err := fake.AddToScheme(scheme)
if err != nil {
return nil, err
}
return dynamicfake.NewSimpleDynamicClient(scheme), nil

return dynamicfake.NewSimpleDynamicClient(scheme, objs...), nil
}
44 changes: 44 additions & 0 deletions kubernetes_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -505,3 +505,47 @@ if (k8s.list(podSpec.kind, podSpec.metadata.namespace).length != 0) {
`)
require.NoError(t, err)
}

// TestHelpersAreScriptable runs helpers
func TestHelpersAreScriptable(t *testing.T) {
t.Parallel()

rt := setupTestEnv(t)

_, err := rt.RunString(`
const k8s = new Kubernetes()

let pod = {
apiVersion: "v1",
kind: "Pod",
metadata: {
name: "busybox",
namespace: "default"
},
spec: {
containers: [
{
name: "busybox",
image: "busybox",
command: ["sh", "-c", "sleep 30"]
}
]
},
status: {
phase: "Running"
}
}

// create pod in test namespace
k8s.create(pod)

// get helpers for test namespace
const helpers = k8s.helpers()

// wait for pod to be running
if (!helpers.waitPodRunning(pod.metadata.name, 5)) {
throw new Error("should not timeout")
}
`)
require.NoError(t, err)
}
Loading