fn: add tester image (#609)

* fn: add fn-test-utils image

New tester image that uses go-fdk for advanced test scenarios.
Right now, this is an enhanced 'hello/sleeper' rolled into one
that echos the received headers/env to allow writing test cases.
This commit is contained in:
Tolga Ceylan
2017-12-19 15:06:16 -08:00
committed by GitHub
parent 1f3091f5d7
commit b3f7c7fc7f
9 changed files with 162 additions and 1 deletions

1
images/fn-test-utils/.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
vendor

View File

@@ -0,0 +1,16 @@
# build stage
FROM golang:1.9-alpine AS build-env
RUN apk --no-cache add build-base git bzr mercurial gcc
ENV D=/go/src/github.com/fnproject/fn/images/fn-test-utils
RUN go get -u github.com/golang/dep/cmd/dep
ADD Gopkg.* $D/
RUN cd $D && dep ensure --vendor-only
ADD . $D
RUN cd $D && go build -o fn-test-utils && cp fn-test-utils /tmp/
# final stage
FROM alpine
WORKDIR /function
COPY --from=build-env /tmp/fn-test-utils /function
ENTRYPOINT ["./fn-test-utils"]

15
images/fn-test-utils/Gopkg.lock generated Normal file
View File

@@ -0,0 +1,15 @@
# This file is autogenerated, do not edit; changes may be undone by the next 'dep ensure'.
[[projects]]
branch = "master"
name = "github.com/fnproject/fdk-go"
packages = ["."]
revision = "ce12b15e559bb56980c4134cbeadb99db9cd563a"
[solve-meta]
analyzer-name = "dep"
analyzer-version = 1
inputs-digest = "c55f0d3da5ec2e9e5c9a7c563702e4cf28513fa1aaea1c18664ca2cb7d726f89"
solver-name = "gps-cdcl"
solver-version = 1

View File

@@ -0,0 +1,25 @@
# Gopkg.toml example
#
# Refer to https://github.com/golang/dep/blob/master/docs/Gopkg.toml.md
# for detailed Gopkg.toml documentation.
#
# required = ["github.com/user/thing/cmd/thing"]
# ignored = ["github.com/user/project/pkgX", "bitbucket.org/user/project/pkgA/pkgY"]
#
# [[constraint]]
# name = "github.com/user/project"
# version = "1.0.0"
#
# [[constraint]]
# name = "github.com/user/project2"
# branch = "dev"
# source = "github.com/myfork/project2"
#
# [[override]]
# name = "github.com/x/y"
# version = "2.4.0"
[[constraint]]
branch = "master"
name = "github.com/fnproject/fdk-go"

2
images/fn-test-utils/build.sh Executable file
View File

@@ -0,0 +1,2 @@
set -e
docker build -t fnproject/fn-test-utils:latest .

View File

@@ -0,0 +1,92 @@
package main
import (
"context"
"encoding/json"
"io"
"log"
"time"
fdk "github.com/fnproject/fdk-go"
"net/http"
)
type AppRequest struct {
// if specified we 'sleep' the specified msecs
SleepTime int `json:"sleepTime,omitempty"`
// if specified, this is our response http status code
ResponseCode int `json:"responseCode,omitempty"`
// if specified, this is our response content-type
ResponseContentType string `json:"responseContentType,omitempty"`
// if specified, this is echoed back to client
EchoContent string `json:"echoContent,omitempty"`
// verbose mode
IsDebug bool `json:"isDebug,omitempty"`
// simulate crash
IsCrash bool `json:"isCrash,omitempty"`
// TODO: simulate slow read/slow write
// TODO: simulate partial write/read
// TODO: simulate mem leak
// TODO: simulate high cpu usage
// TODO: simulate high mem usage
// TODO: simulate large body upload/download
}
type AppResponse struct {
Request AppRequest `json:"request"`
Headers http.Header `json:"header"`
Config map[string]string `json:"config"`
}
func AppHandler(ctx context.Context, in io.Reader, out io.Writer) {
fnctx := fdk.Context(ctx)
var request AppRequest
json.NewDecoder(in).Decode(&request)
if request.IsDebug {
log.Printf("Received request %v", request)
log.Printf("Received headers %v", fnctx.Header)
log.Printf("Received config %v", fnctx.Config)
}
// simulate load if requested
if request.SleepTime > 0 {
if request.IsDebug {
log.Printf("Sleeping %d", request.SleepTime)
}
time.Sleep(time.Duration(request.SleepTime) * time.Millisecond)
}
// simulate crash
if request.IsCrash {
panic("Crash requested")
}
// custom response code
if request.ResponseCode != 0 {
fdk.WriteStatus(out, request.ResponseCode)
} else {
fdk.WriteStatus(out, 200)
}
// custom content type
if request.ResponseContentType != "" {
fdk.SetHeader(out, "Content-Type", request.ResponseContentType)
} else {
fdk.SetHeader(out, "Content-Type", "application/json")
}
resp := AppResponse{
Request: request,
Headers: fnctx.Header,
Config: fnctx.Config,
}
json.NewEncoder(out).Encode(&resp)
}
func main() {
fdk.Handle(fdk.HandlerFunc(AppHandler))
}

View File

@@ -0,0 +1,4 @@
set -e
./build.sh
docker push fnproject/fn-test-utils:latest

View File

@@ -45,6 +45,9 @@ docker tag $user/$image:latest $user/$image_deprecated:latest
docker push $user/$image_deprecated:$version docker push $user/$image_deprecated:$version
docker push $user/$image_deprecated:latest docker push $user/$image_deprecated:latest
# release test utils docker image
(cd images/fn-test-utils && ./release.sh)
cd fnlb cd fnlb
./release.sh ./release.sh
cd .. cd ..

View File

@@ -29,6 +29,9 @@ docker run --name func-mysql-test -p 3306:3306 -e MYSQL_DATABASE=funcs -e MYSQL_
docker rm -fv func-minio-test || echo No prev minio test container docker rm -fv func-minio-test || echo No prev minio test container
docker run -d -p 9000:9000 --name func-minio-test -e "MINIO_ACCESS_KEY=admin" -e "MINIO_SECRET_KEY=password" minio/minio server /data docker run -d -p 9000:9000 --name func-minio-test -e "MINIO_ACCESS_KEY=admin" -e "MINIO_SECRET_KEY=password" minio/minio server /data
# build test image locally first
(cd images/fn-test-utils && ./build.sh)
# pull all images used in tests so that tests don't time out and fail spuriously # pull all images used in tests so that tests don't time out and fail spuriously
docker pull fnproject/sleeper docker pull fnproject/sleeper
docker pull fnproject/error docker pull fnproject/error
@@ -47,7 +50,7 @@ export POSTGRES_URL="postgres://postgres:root@${POSTGRES_HOST}:${POSTGRES_PORT}/
export MYSQL_URL="mysql://root:root@tcp(${MYSQL_HOST}:${MYSQL_PORT})/funcs" export MYSQL_URL="mysql://root:root@tcp(${MYSQL_HOST}:${MYSQL_PORT})/funcs"
export MINIO_URL="s3://admin:password@${MINIO_HOST}:${MINIO_PORT}/us-east-1/fnlogs" export MINIO_URL="s3://admin:password@${MINIO_HOST}:${MINIO_PORT}/us-east-1/fnlogs"
go test -v $(go list ./... | grep -v vendor | grep -v examples | grep -v test/fn-api-tests) go test -v $(go list ./... | grep -v vendor | grep -v examples | grep -v test/fn-api-tests | grep -v images/fn-test-utils)
go vet $(go list ./... | grep -v vendor) go vet $(go list ./... | grep -v vendor)
docker rm --force func-postgres-test docker rm --force func-postgres-test
docker rm --force func-mysql-test docker rm --force func-mysql-test