Skip to content
This repository has been archived by the owner on Aug 24, 2023. It is now read-only.

Commit

Permalink
fix: add missing integration test files (#6)
Browse files Browse the repository at this point in the history
Because

- add missing integration-test files

This commit

- add missing integration-test files
  • Loading branch information
heiruwu committed Mar 31, 2023
1 parent 567aa0d commit bdb8eb7
Show file tree
Hide file tree
Showing 48 changed files with 6,377 additions and 8 deletions.
2 changes: 1 addition & 1 deletion .env
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ K6_VERSION=0.42.0

# service
SERVICE_NAME=controller
SERVICE_PORT=8085
SERVICE_PORT=3085

# socat
SOCAT_HOST=socat
Expand Down
1 change: 0 additions & 1 deletion .github/workflows/images.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ jobs:
uses: cardinalby/export-env-action@v2
with:
envFile: .env
expand: true

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
Expand Down
10 changes: 5 additions & 5 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -52,14 +52,14 @@ go-gen: ## Generate codes

.PHONY: unit-test
unit-test: ## Run unit test
@go test -v -race -coverpkg=./... -coverprofile=coverage.out ./...
@go tool cover -func=coverage.out
@go tool cover -html=coverage.out
@rm coverage.out
@go test -v -race -coverpkg=./... -coverprofile=/vdp/coverage.out ./...
@go tool cover -func=/vdp/coverage.out
@go tool cover -html=/vdp/coverage.out
@rm /vdp/coverage.out

.PHONY: integration-test
integration-test: ## Run integration test
@TEST_FOLDER_ABS_PATH=${PWD} k6 run -e MODE=$(MODE) integration-test/rest.js --no-usage-report --quiet
@TEST_FOLDER_ABS_PATH=${PWD} k6 run -e MODE=$(MODE) integration-test/grpc.js --no-usage-report --quiet

.PHONY: help
help: ## Show this help
Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
# controller
[![Integration Test](https://github.com/instill-ai/controller/actions/workflows/integration-test.yml/badge.svg)](https://github.com/instill-ai/controller/actions/workflows/integration-test.yml)

`controller` service monitors the state of other services and resources within [Versatile Data Pipeline (VDP)](https://github.com/instill-ai/vdp).

Expand Down
2 changes: 1 addition & 1 deletion config/config.yaml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
server:
port: 8085
port: 3085
https:
cert:
key:
Expand Down
72 changes: 72 additions & 0 deletions integration-test/const.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
let proto
let tHost, mgHost, pHost, cHost, mHost, ctHost
let tPublicPort, mgPublicPort, mgPrivatePort, pPublicPort, pPrivatePort, cPublicPort, cPrivatePort, mPublicPort, mPrivatePort, ctPrivatePort

if (__ENV.MODE == "api-gateway") {
// api-gateway mode
proto = "http"
pHost = cHost = mHost = tHost = mgHost = ctHost = "api-gateway"
pPrivatePort = 3081
cPrivatePort = 3082
mPrivatePort = 3083
mgPrivatePort = 3084
ctPrivatePort = 3085
tPublicPort = mgPublicPort = pPublicPort = cPublicPort = mPublicPort = 8080
} else if (__ENV.MODE == "localhost") {
// localhost mode for GitHub Actions
proto = "http"
pHost = cHost = mHost = tHost = mgHost = "localhost"
pPrivatePort = 3081
cPrivatePort = 3082
mPrivatePort = 3083
mgPrivatePort = 3084
ctPrivatePort = 3085
tPublicPort = mgPublicPort = pPublicPort = cPublicPort = mPublicPort = 8080
} else {
// direct microservice mode
proto = "http"
tHost = "triton-server"
mgHost = "mgmt-backend"
pHost = "pipeline-backend"
cHost = "connector-backend"
mHost = "model-backend"
ctHost = "controller"
pPrivatePort = 3081
cPrivatePort = 3082
mPrivatePort = 3083
mgPrivatePort = 3084
ctPrivatePort = 3085
tPublicPort = 8001
pPublicPort = 8081
cPublicPort = 8082
mPublicPort = 8083
mgPublicPort = 8084
}

export const connectorPublicHost = `${proto}://${cHost}:${cPublicPort}`;
export const connectorPrivateHost = `${proto}://${cHost}:${cPrivatePort}`;
export const pipelinePublicHost = `${proto}://${pHost}:${pPublicPort}`;
export const pipelinePrivateHost = `${proto}://${pHost}:${pPrivatePort}`;
export const modelPublicHost = `${proto}://${mHost}:${mPublicPort}`;
export const modelPrivateHost = `${proto}://${mHost}:${mPrivatePort}`;
export const mgmtPublicHost = `${proto}://${mgHost}:${mgPublicPort}`;
export const mgmtPricateHost = `${proto}://${mgHost}:${mgPrivatePort}`;
export const tritonPublicHost = `${proto}://${tHost}:${tPublicPort}`;
export const controllerPrivateHost = `${proto}://${ctHost}:${ctPrivatePort}`;

export const controllerGRPCPrivateHost = `${ctHost}:${ctPrivatePort}`;

export const modelResourceName = "resources/this-is-model-name/types/models"
export const modelName = "models/this-is/instances/model-name"

export const sourceConnectorResourceName = "resources/source-connector-name/types/source-connectors"
export const sourceConnectorName = "source-connectors/source-connector-name"

export const destinationConnectorResourceName = "resources/destination-connector-name/types/destination-connectors"
export const destinationConnectorName = "destination-connectors/destination-connector-name"

export const pipelineResourceName = "resources/pipeline-name/types/pipelines"
export const pipelineName = "pipelines/pipeline-name"

export const serviceResourceName = "resources/model-backend/types/services"
export const serviceName = "model-backend"
148 changes: 148 additions & 0 deletions integration-test/controller-private.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
import grpc from 'k6/net/grpc';
import {
check,
group
} from "k6";

import * as constant from "./const.js"

const clientPrivate = new grpc.Client();
clientPrivate.load(['proto/vdp/controller/v1alpha'], 'controller_service.proto');

export function CheckModelResource() {
var httpModelResource = {
"name": constant.modelResourceName,
"model_state": "STATE_ONLINE"
}

clientPrivate.connect(constant.controllerGRPCPrivateHost, {
plaintext: true
});

group("Controller API: Create model resource state in etcd", () => {
var resCreateModelHTTP = clientPrivate.invoke('vdp.controller.v1alpha.ControllerPrivateService/UpdateResource', {
resource: httpModelResource
})

check(resCreateModelHTTP, {
"vdp.controller.v1alpha.ControllerPrivateService/UpdateResource response StatusOK": (r) => r.status === grpc.StatusOK,
"vdp.controller.v1alpha.ControllerPrivateService/UpdateResource response modelResource name matched": (r) => r.message.resource.name == httpModelResource.name,
});
});

group("Controller API: Get model resource state in etcd", () => {
var resGetModelHTTP = clientPrivate.invoke(`vdp.controller.v1alpha.ControllerPrivateService/GetResource`, {
name: httpModelResource.name
})

check(resGetModelHTTP, {
[`vdp.controller.v1alpha.ControllerPrivateService/GetResource ${httpModelResource.name} response StatusOK`]: (r) => r.status === grpc.StatusOK,
[`vdp.controller.v1alpha.ControllerPrivateService/GetResource ${httpModelResource.name} response modelResource name matched`]: (r) => r.message.resource.name === httpModelResource.name,
[`vdp.controller.v1alpha.ControllerPrivateService/GetResource ${httpModelResource.name} response modelResource state matched STATE_ONLINE`]: (r) => r.message.resource.modelState == "STATE_ONLINE",
});
});
}

export function CheckSourceConnectorResource() {
var httpSourceConnectorResource = {
"name": constant.sourceConnectorResourceName,
"connector_state": "STATE_CONNECTED"
}

clientPrivate.connect(constant.controllerGRPCPrivateHost, {
plaintext: true
});

group("Controller API: Create source connector resource state in etcd", () => {
var resCreateSourceConnectorHTTP = clientPrivate.invoke('vdp.controller.v1alpha.ControllerPrivateService/UpdateResource', {
resource: httpSourceConnectorResource
})

check(resCreateSourceConnectorHTTP, {
"vdp.controller.v1alpha.ControllerPrivateService/UpdateResource response StatusOK": (r) => r.status === grpc.StatusOK,
"vdp.controller.v1alpha.ControllerPrivateService/UpdateResource response connectorResource name matched": (r) => r.message.resource.name == httpSourceConnectorResource.name,
});
});

group("Controller API: Get source connector resource state in etcd", () => {
var resGetSourceConnectorHTTP = clientPrivate.invoke(`vdp.controller.v1alpha.ControllerPrivateService/GetResource`, {
name: httpSourceConnectorResource.name
})

check(resGetSourceConnectorHTTP, {
[`vdp.controller.v1alpha.ControllerPrivateService/GetResource ${httpSourceConnectorResource.name} response StatusOK`]: (r) => r.status === grpc.StatusOK,
[`vdp.controller.v1alpha.ControllerPrivateService/GetResource ${httpSourceConnectorResource.name} response connectorResource name matched`]: (r) => r.message.resource.name === httpSourceConnectorResource.name,
[`vdp.controller.v1alpha.ControllerPrivateService/GetResource ${httpSourceConnectorResource.name} response connectorResource state matched STATE_CONNECTED`]: (r) => r.message.resource.connectorState == "STATE_CONNECTED",
});
});
}

export function CheckDestinationConnectorResource() {
var httpDestinationConnectorResource = {
"name": constant.destinationConnectorResourceName,
"connector_state": "STATE_CONNECTED"
}

clientPrivate.connect(constant.controllerGRPCPrivateHost, {
plaintext: true
});

group("Controller API: Create destination connector resource state in etcd", () => {
var resCreatpDestinationConnectorHTTP = clientPrivate.invoke('vdp.controller.v1alpha.ControllerPrivateService/UpdateResource', {
resource: httpDestinationConnectorResource
})

check(resCreatpDestinationConnectorHTTP, {
"vdp.controller.v1alpha.ControllerPrivateService/UpdateResource response StatusOK": (r) => r.status === grpc.StatusOK,
"vdp.controller.v1alpha.ControllerPrivateService/UpdateResource response connectorResource name matched": (r) => r.message.resource.name == httpDestinationConnectorResource.name,
});
});

group("Controller API: Get destination connector resource state in etcd", () => {
var resGetDestinationConnectorHTTP = clientPrivate.invoke(`vdp.controller.v1alpha.ControllerPrivateService/GetResource`, {
name: httpDestinationConnectorResource.name
})

check(resGetDestinationConnectorHTTP, {
[`vdp.controller.v1alpha.ControllerPrivateService/GetResource ${httpDestinationConnectorResource.name} response StatusOK`]: (r) => r.status === grpc.StatusOK,
[`vdp.controller.v1alpha.ControllerPrivateService/GetResource ${httpDestinationConnectorResource.name} response connectorResource name matched`]: (r) => r.message.resource.name === httpDestinationConnectorResource.name,
[`vdp.controller.v1alpha.ControllerPrivateService/GetResource ${httpDestinationConnectorResource.name} response connectorResource state matched STATE_CONNECTED`]: (r) => r.message.resource.connectorState == "STATE_CONNECTED",
});
});
}

export function CheckPipelineResource() {
var httpPipelineResource = {
"name": constant.pipelineResourceName,
"pipeline_state": "STATE_ACTIVE"
}

clientPrivate.connect(constant.controllerGRPCPrivateHost, {
plaintext: true
});

group("Controller API: Create pipeline resource state in etcd", () => {
var resCreatepipelineHTTP = clientPrivate.invoke('vdp.controller.v1alpha.ControllerPrivateService/UpdateResource', {
resource: httpPipelineResource
})

check(resCreatepipelineHTTP, {
"vdp.controller.v1alpha.ControllerPrivateService/UpdateResource response StatusOK": (r) => r.status === grpc.StatusOK,
"vdp.controller.v1alpha.ControllerPrivateService/UpdateResource response pipeline name matched": (r) => r.message.resource.name == httpPipelineResource.name,
});
});

group("Controller API: Get pipeline resource state in etcd", () => {
var resGetPipelineHTTP = clientPrivate.invoke(`vdp.controller.v1alpha.ControllerPrivateService/GetResource`, {
name: httpPipelineResource.name
})

console.log(resGetPipelineHTTP)

check(resGetPipelineHTTP, {
[`vdp.controller.v1alpha.ControllerPrivateService/GetResource ${httpPipelineResource.name} response StatusOK`]: (r) => r.status === grpc.StatusOK,
[`vdp.controller.v1alpha.ControllerPrivateService/GetResource ${httpPipelineResource.name} response pipeline name matched`]: (r) => r.message.resource.name === httpPipelineResource.name,
[`vdp.controller.v1alpha.ControllerPrivateService/GetResource ${httpPipelineResource.name} response pipeline state matched STATE_ACTIVE`]: (r) => r.message.resource.pipelineState == "STATE_ACTIVE",
});
});
}
90 changes: 90 additions & 0 deletions integration-test/grpc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
import grpc from 'k6/net/grpc';
import {
check,
group
} from 'k6';

import * as constant from "./const.js"
import * as controller_service from './controller-private.js';
const client = new grpc.Client();
client.load(['proto/vdp/controller/v1alpha'], 'controller_service.proto');

export let options = {
setupTimeout: '10s',
insecureSkipTLSVerify: true,
thresholds: {
checks: ["rate == 1.0"],
},
};

export default function (data) {

/*
* Controller API - API CALLS
*/

// Health check
group("Controller API: Health check", () => {
client.connect(constant.controllerGRPCPrivateHost, {
plaintext: true
});

check(client.invoke('vdp.controller.v1alpha.ControllerPrivateService/Liveness', {}), {
'Liveness Status is OK': (r) => r && r.status === grpc.StatusOK,
'Response status is SERVING_STATUS_SERVING': (r) => r && r.message.healthCheckResponse.status === "SERVING_STATUS_SERVING",
});

check(client.invoke('vdp.controller.v1alpha.ControllerPrivateService/Readiness', {}), {
'Readiness Status is OK': (r) => r && r.status === grpc.StatusOK,
'Response status is SERVING_STATUS_SERVING': (r) => r && r.message.healthCheckResponse.status === "SERVING_STATUS_SERVING",
});
client.close();
});

if (__ENV.MODE != "api-gateway" && __ENV.MODE != "localhost") {
controller_service.CheckModelResource()
controller_service.CheckSourceConnectorResource()
controller_service.CheckDestinationConnectorResource()
controller_service.CheckPipelineResource()

}
}

export function teardown(data) {
client.connect(constant.controllerGRPCPrivateHost, {
plaintext: true
});
group("Controller API: Delete all resources created by the test", () => {

check(client.invoke(`vdp.controller.v1alpha.ControllerPrivateService/DeleteResource`, {
name: constant.modelResourceName
}), {
[`vdp.controller.v1alpha.ControllerPrivateService/DeleteResource ${constant.modelResourceName} response StatusOK`]: (r) => r.status === grpc.StatusOK,
});

check(client.invoke(`vdp.controller.v1alpha.ControllerPrivateService/DeleteResource`, {
name: constant.sourceConnectorResourceName
}), {
[`vdp.controller.v1alpha.ControllerPrivateService/DeleteResource ${constant.sourceConnectorResourceName} response StatusOK`]: (r) => r.status === grpc.StatusOK,
});

check(client.invoke(`vdp.controller.v1alpha.ControllerPrivateService/DeleteResource`, {
name: constant.destinationConnectorResourceName
}), {
[`vdp.controller.v1alpha.ControllerPrivateService/DeleteResource ${constant.destinationConnectorResourceName} response StatusOK`]: (r) => r.status === grpc.StatusOK,
});

check(client.invoke(`vdp.controller.v1alpha.ControllerPrivateService/DeleteResource`, {
name: constant.pipelineResourceName
}), {
[`vdp.controller.v1alpha.ControllerPrivateService/DeleteResource ${constant.pipelineResourceName} response StatusOK`]: (r) => r.status === grpc.StatusOK,
});

check(client.invoke(`vdp.controller.v1alpha.ControllerPrivateService/DeleteResource`, {
name: constant.serviceResourceName
}), {
[`vdp.controller.v1alpha.ControllerPrivateService/DeleteResource ${constant.serviceResourceName} response StatusOK`]: (r) => r.status === grpc.StatusOK,
});
});
client.close();
}
Loading

0 comments on commit bdb8eb7

Please sign in to comment.