Skip to content

Latest commit

 

History

History
186 lines (138 loc) · 4.81 KB

README.md

File metadata and controls

186 lines (138 loc) · 4.81 KB

k8test

Run docker images using k8s in tests

Table of Contents

  1. Install
  2. Introduction
  3. Setup
  4. Api
  5. Supported OS
  6. Run your tests in CI
  7. Questions & Debugging & Advanced Operations
  8. Development & contributing

Install

yarn add --dev k8test

Introduction

Use all k8s features to deploy and expose images during tests ✔️

Benefits

  • Faster tests - deploying an image is slow. k8test deployments added a scope property to the game:
    • a single deployment at most in a namespace (cluster),
    • in the next test run, there will be new deployment
    • each subscription will create new deployment
  • [wip] Monitoring tests resources - you can safely stop/cancel/shutdown the tests when/how ever you want and eventually all the resources will be deleted.
  • There is no need to learn k8s. There are very good defaults.

No Surprises

  • 🏄 No external synchronization is used (your file-system/network/...)
  • 🚀 No pulling: Event based implementation: kubernetes-client/javascript

Setup

Fast setup to deploy redis in your tests:

{
  "name": "your-project",
  "scripts": {
    "pretest": "k8test start-monitoring",
    "test": "jest"
  },
  "devDependencies": {
    "k8test": "^1.0.0"
  }
}
  • note: k8test start-monitoring - after the first run, it will take up to 1-2 seconds
// jest.config.js
const k8test = require('k8test')

module.exports = {
  globals: {
    // to differentiate k8s resources between different runs
    APP_ID: k8test.randomAppId(),
  },
})
// __tests__/test.spec.ts

import Redis from 'ioredis'
import { Subscription } from 'k8test'
import { subscribe } from './utils'
import { subscribe, Subscribe } from 'k8test'

describe('simple use-case', () => {
  let exposedRedisInfo: Subscription

  beforeEach(async () => {
    exposedRedisInfo = await subscribe({
      imageName: 'redis',
      imagePort: 6379,
    })
  })

  afterEach(async () => {
    await exposedRedisInfo.unsubscribe() // redis will not be reachable after this line
  })

  test('ensure redis is alive', async () => {
    const redis = new Redis({
      host: exposedRedisInfo.deployedImageIp,
      port: exposedRedisInfo.deployedImagePort,
      connectTimeout: 1000,
    })
    await expect(redis.ping()).resolves.toEqual('PONG')
    redis.disconnect()
  })
})

Api

import { subscribe } from 'k8test'
import * as k8s from '@kubernetes/client-node' // you don't need to install it

export enum SingletonStrategy {
  manyInAppId = 'many-in-app-id',
  oneInNamespace = 'one-in-namespace',
  oneInAppId = 'one-in-app-id',
}

export type ContainerOptions = Omit<k8s.V1Container, 'name' | 'image' | 'ports'>

await subscribe({
  imageName: string
  postfix?: string
  appId?: string
  singletonStrategy?: SingletonStrategy
  imagePort: number
  containerOptions?: ContainerOptions  // for mounting and any other options
  namespaceName?: string
  isReadyPredicate?: (
    deployedImageUrl: string,
    deployedImageIp: string,
    deployedImagePort: number,
  ) => Promise<unknown>
})

Run your tests in CI

You should have k8s internal api exposed in your CI. it's very simple to set it up in Github-Actions: Example:

- name: install k8s
  uses: engineerd/setup-kind@v0.4.0
- run: yarn run your-tests

Thats it.

  • I have a more advanced setup to test docker-images of other sub-packages of this repository.

Supported OS

I'm developing on macOS Mojave and in CI we are running on linux debian

Questions & Debugging & Advanced Operations

How do I manually remove all the tests and k8test resources from my k8s cluster?

yarn k8test delete-k8test-resources

How do I listen to stdout & stderr of a specific image?

work in progress. hold on. for now, you can manually search the container you need to attach to using kubectl cli, the app-id and namespace (which is k8test).

Development & contributing

Run the following command in the root folder of the repository

yarn install && yarn build && yarn build:dockers

this library is in a early stage but it is functional. I don't have a draft for a better api to the end-users. Feel free to drastically change the api.

Keep in mind that tests are the first priority. production code can use this library but it has a lower level of priority.

PRs about Api/ speed improvement are welcome.

Internal Tools

  • yarn
  • node 12+
  • docker (deamon + cli)
  • minikube
  • secrethub (only for publishing artifacts - npm/docker to registries)