how to test nodejs application which is deployed as a pod on kubernetes cluster?

6/15/2018

I have developed a nodejs REST API, for which i have built a docker image and now deploying it as a pod on my kubernetes cluster.

Dockerfile

FROM mhart/alpine-node:8
WORKDIR /home/appHome/
COPY package*.json ./
RUN npm install
COPY . .
EXPOSE 3000
CMD [ "npm", "start" ]

however, i am passing npm start as my container start up command.

but how do i test my node js application with npm test and verify test results?

when i was doing it in my local system i used to run application in backend and used to run

npm test

in another window. how to achieve the same while deploying it on kubernetes cluster! and remove the test part once it is successfull!

below is my script of package.json,

"scripts": {
"test": "mocha ./test/scheduledTaskTest.js",
"start": "nodemon app.js --exec babel-node --presets es2015,stage-2",
"cmd": "set NODE_ENV=devConfig&& npm start"
},

Below are the deployment and job yaml files.

Deployment.yaml

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: scheduled-task-test
spec:
  replicas: 1
  selector:
    matchLabels:
      app: scheduled-task-test
  template:
    metadata:
      labels:
        app: scheduled-task-test
    spec:     # pod spec       
      containers:
      - name: st-c1
        image: 104466/st
        imagePullPolicy: Always
        env: 
        - name: NODE_ENV
          value: devConfig
      - name: st-c2
        image: 104466/st
        imagePullPolicy: Always
        command: [ 'sh','-c','npm test && sleep 3600']'

TestJob.yaml

apiVersion: batch/v1
kind: Job
metadata:
  name: scheduled-task-test-job
  labels:
    purpose: test
spec:
  template:
    spec:
      containers:
      - name: st-c1
        image: 104466/st
        imagePullPolicy: Always
        env: 
        - name: NODE_ENV
          value: devConfig
      - name: st-c2
        image: 104466/st
        imagePullPolicy: Always
        command: [ 'sh','-c','npm test && sleep 3600']
      restartPolicy: Never

Pod status

scheduled-task-test-7d86c87d44-q9zdv                              2/2       Running   1          8m        100.96.9.87   ip-172-20-34-139.us-west-2.compute.internal
scheduled-task-test-job-gt9hx                                     1/2       Error     0          7m        100.96.9.88   ip-172-20-34-139.us-west-2.compute.internal

Successfully executed test case pod log (deployment results)

kubectl logs scheduled-task-test-7d86c87d44-q9zdv -c st-c2

> ScheduledTask@1.0.0 test /home/appHome/ScheduledTask
> mocha ./test/scheduledTaskTest.js



  Testing listTask api
List all the Tasks (435ms)

  Testing addTask api
Add a new task  (438ms)

  Testing updateTask api
Update task

  Testing delete task api
Delete task  (434ms)


  4 passing (1s)

Test failed logs, (Executed containers as in job)

kubectl logs scheduled-task-test-job-gt9hx -c st-c2

> ScheduledTask@1.0.0 test /home/appHome/ScheduledTask
> mocha ./test/scheduledTaskTest.js



  Testing listTask api
    1) List all the Tasks

  Testing addTask api
    2)  Add a new task

  Testing updateTask api
    3)  Update task

  Testing delete task api
    4)  Delete task


  0 passing (61ms)
  4 failing

  1) Testing listTask api
       List all the Tasks:
     Uncaught TypeError: Cannot read property 'body' of undefined
      at Request._callback (test/scheduledTaskTest.js:24:29)
      at self.callback (node_modules/request/request.js:186:22)
      at Request.onRequestError (node_modules/request/request.js:878:8)
      at Socket.socketErrorListener (_http_client.js:387:9)
      at emitErrorNT (internal/streams/destroy.js:64:8)
      at _combinedTickCallback (internal/process/next_tick.js:138:11)
      at process._tickCallback (internal/process/next_tick.js:180:9)

  2) Testing addTask api
        Add a new task :
     Uncaught TypeError: Cannot read property 'body' of undefined
      at Request._callback (test/scheduledTaskTest.js:43:20)
      at self.callback (node_modules/request/request.js:186:22)
      at Request.onRequestError (node_modules/request/request.js:878:8)
      at Socket.socketErrorListener (_http_client.js:387:9)
      at emitErrorNT (internal/streams/destroy.js:64:8)
      at _combinedTickCallback (internal/process/next_tick.js:138:11)
      at process._tickCallback (internal/process/next_tick.js:180:9)

  3) Testing updateTask api
        Update task :
     Uncaught TypeError: Cannot read property 'body' of undefined
      at Request._callback (test/scheduledTaskTest.js:63:20)
      at self.callback (node_modules/request/request.js:186:22)
      at Request.onRequestError (node_modules/request/request.js:878:8)
      at Socket.socketErrorListener (_http_client.js:387:9)
      at emitErrorNT (internal/streams/destroy.js:64:8)
      at _combinedTickCallback (internal/process/next_tick.js:138:11)
      at process._tickCallback (internal/process/next_tick.js:180:9)

  4) Testing delete task api
        Delete task :
     Uncaught TypeError: Cannot read property 'body' of undefined
      at Request._callback (test/scheduledTaskTest.js:83:20)
      at self.callback (node_modules/request/request.js:186:22)
      at Request.onRequestError (node_modules/request/request.js:878:8)
      at Socket.socketErrorListener (_http_client.js:387:9)
      at emitErrorNT (internal/streams/destroy.js:64:8)
      at _combinedTickCallback (internal/process/next_tick.js:138:11)
      at process._tickCallback (internal/process/next_tick.js:180:9)



npm ERR! Test failed.  See above for more details.

Describe logs of Pod( of containers deployed as job)

kubectl describe pod scheduled-task-test-job-gt9hx
Name:           scheduled-task-test-job-gt9hx
Namespace:      default
Node:           ip-172-20-34-139.us-west-2.compute.internal/172.20.34.139
Start Time:     Tue, 19 Jun 2018 16:28:06 +0000
Labels:         controller-uid=bf5569e5-73dd-11e8-8ede-02924b27b126
                job-name=scheduled-task-test-job
Annotations:    kubernetes.io/created-by={"kind":"SerializedReference","apiVersion":"v1","reference":{"kind":"Job","namespace":"default","name":"scheduled-task-test-job","uid":"bf5569e5-73dd-11e8-8ede-02924b27b126","...
                kubernetes.io/limit-ranger=LimitRanger plugin set: cpu request for container st-c1; cpu request for container st-c2
Status:         Running
IP:             100.96.9.88
Created By:     Job/scheduled-task-test-job
Controlled By:  Job/scheduled-task-test-job
Containers:
  st-c1:
    Container ID:   docker://7fc17e717921020cec074774ccb87956979712e7de55480be6e6bd586b28ce6d
    Image:          104466/st
    Image ID:       docker-pullable://104466/st@sha256:91414cc48e86975041c233329b1814d7c6d2b76bc839a24fa68e99f92750390f
    Port:           <none>
    State:          Running
      Started:      Tue, 19 Jun 2018 16:28:08 +0000
    Ready:          True
    Restart Count:  0
    Requests:
      cpu:  100m
    Environment:
      NODE_ENV:  devConfig
    Mounts:
      /var/run/secrets/kubernetes.io/serviceaccount from default-token-2tvsm (ro)
  st-c2:
    Container ID:  docker://95837799d34e1e14f7718acc1dc745042b94a33f115aab11a03a25ab4a569c18
    Image:         104466/st
    Image ID:      docker-pullable://104466/st@sha256:91414cc48e86975041c233329b1814d7c6d2b76bc839a24fa68e99f92750390f
    Port:          <none>
    Command:
      sh
      -c
      npm test && sleep 3600
    State:          Terminated
      Reason:       Error
      Exit Code:    1
      Started:      Tue, 19 Jun 2018 16:28:10 +0000
      Finished:     Tue, 19 Jun 2018 16:28:12 +0000
    Ready:          False
    Restart Count:  0
    Requests:
      cpu:        100m
    Environment:  <none>
    Mounts:
      /var/run/secrets/kubernetes.io/serviceaccount from default-token-2tvsm (ro)
Conditions:
  Type           Status
  Initialized    True
  Ready          False
  PodScheduled   True
Volumes:
  default-token-2tvsm:
    Type:        Secret (a volume populated by a Secret)
    SecretName:  default-token-2tvsm
    Optional:    false
QoS Class:       Burstable
Node-Selectors:  <none>
Tolerations:     node.alpha.kubernetes.io/notReady:NoExecute for 300s
                 node.alpha.kubernetes.io/unreachable:NoExecute for 300s
Events:          <none>
-- Shruthi Bhaskar
docker
dockerfile
kubernetes
node.js

2 Answers

6/15/2018

If you want to use Kubernetes only, then using Jobs would be the easiest way. A job creates one or more pods and ensures that a specified number of them successfully terminate. As pods successfully complete, the job tracks the successful completions. When a specified number of successful completions is reached, the job itself is complete.

Rough plan:

1. Create a Job for your application.
You can use the Deployment of your application as a template. You need to change kind: Job and add spec.containers.command: ["npm", "test"], the last one will replace CMD [ "npm", "start" ] defined in your Dockerfile. Here is an example:

apiVersion: batch/v1
kind: Job
metadata:
  name: npm-test-job
  labels:
    purpose: test
spec:
  template:
    spec:
      containers:
      - name: npm-test-job
        image: <your-image>
        command: ["npm", "test"]
      restartPolicy: Never

2. Run the Job
Run the Job and wait until it is complete:

kubectl create -f npm-test-job

3. Check the status of the Job
Check status of your Job, for example:

kubectl describe jobs kubectl describe jobs | grep "Pods Statuses"

4. Run the Deployment
If test finished successfully, you can start you deployment:

kubectl create -f npm-deployment

Of course, you need to automate this process. Therefore, you need to develop a script implementing this logic.


But my advice here: it is better to use CI tool, such as Jenkins. It integrates easily with Kubernetes and provides a vast amount of functionalities for such cases.

-- Artem Golenyaev
Source: StackOverflow

6/15/2018

Just specify 'command: [ "npm", "test" ]' in your container part of deployment.yaml will do that.

-- Kun Li
Source: StackOverflow