Skip to content

Commit

Permalink
Merge pull request #177 from arangodb/test/duration
Browse files Browse the repository at this point in the history
Added duration test app
  • Loading branch information
ewoutp authored Jun 15, 2018
2 parents 91e4475 + c7e0eb3 commit b5a732a
Show file tree
Hide file tree
Showing 21 changed files with 2,070 additions and 0 deletions.
28 changes: 28 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ PULSAR := $(GOBUILDDIR)/bin/pulsar$(shell go env GOEXE)

DOCKERFILE := Dockerfile
DOCKERTESTFILE := Dockerfile.test
DOCKERDURATIONTESTFILE := tests/duration/Dockerfile

ifndef LOCALONLY
PUSHIMAGES := 1
Expand Down Expand Up @@ -63,6 +64,9 @@ endif
ifndef TESTIMAGE
TESTIMAGE := $(DOCKERNAMESPACE)/kube-arangodb-test$(IMAGESUFFIX)
endif
ifndef DURATIONTESTIMAGE
DURATIONTESTIMAGE := $(DOCKERNAMESPACE)/kube-arangodb-durationtest$(IMAGESUFFIX)
endif
ifndef ENTERPRISEIMAGE
ENTERPRISEIMAGE := $(DEFAULTENTERPRISEIMAGE)
endif
Expand All @@ -75,6 +79,8 @@ BINNAME := $(PROJECT)
BIN := $(BINDIR)/$(BINNAME)
TESTBINNAME := $(PROJECT)_test
TESTBIN := $(BINDIR)/$(TESTBINNAME)
DURATIONTESTBINNAME := $(PROJECT)_duration_test
DURATIONTESTBIN := $(BINDIR)/$(DURATIONTESTBINNAME)
RELEASE := $(GOBUILDDIR)/bin/release
GHRELEASE := $(GOBUILDDIR)/bin/github-release

Expand Down Expand Up @@ -278,6 +284,28 @@ endif
$(ROOTDIR)/scripts/kube_create_storage.sh $(DEPLOYMENTNAMESPACE)
$(ROOTDIR)/scripts/kube_run_tests.sh $(DEPLOYMENTNAMESPACE) $(TESTIMAGE) "$(ENTERPRISEIMAGE)" $(TESTTIMEOUT) $(TESTLENGTHOPTIONS)

$(DURATIONTESTBIN): $(GOBUILDDIR) $(SOURCES)
@mkdir -p $(BINDIR)
docker run \
--rm \
-v $(SRCDIR):/usr/code \
-v $(CACHEVOL):/usr/gocache \
-e GOCACHE=/usr/gocache \
-e GOPATH=/usr/code/.gobuild \
-e GOOS=linux \
-e GOARCH=amd64 \
-e CGO_ENABLED=0 \
-w /usr/code/ \
golang:$(GOVERSION) \
go build -installsuffix cgo -ldflags "-X main.projectVersion=$(VERSION) -X main.projectBuild=$(COMMIT)" -o /usr/code/bin/$(DURATIONTESTBINNAME) $(REPOPATH)/tests/duration

.PHONY: docker-duration-test
docker-duration-test: $(DURATIONTESTBIN)
docker build --quiet -f $(DOCKERDURATIONTESTFILE) -t $(DURATIONTESTIMAGE) .
ifdef PUSHIMAGES
docker push $(DURATIONTESTIMAGE)
endif

.PHONY: cleanup-tests
cleanup-tests:
ifneq ($(DEPLOYMENTNAMESPACE), default)
Expand Down
5 changes: 5 additions & 0 deletions tests/duration/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
FROM scratch

ADD bin/arangodb_operator_duration_test /usr/bin/

ENTRYPOINT [ "/usr/bin/arangodb_operator_duration_test" ]
32 changes: 32 additions & 0 deletions tests/duration/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# Kube-ArangoDB duration test

This test is a simple application that keeps accessing the database with various requests.

## Building

In root of kube-arangodb repository, run:

```bash
make docker-duration-test
```

## Running

Start an ArangoDB `Cluster` deployment.

Run:

```bash
kubectl run \
--image=${DOCKERNAMESPACE}/kube-arangodb-durationtest:dev \
--image-pull-policy=Always duration-test \
-- \
--cluster=https://<deployment-name>.<namespace>.svc:8529 \
--username=root
```

To remove the test, run:

```bash
kubectl delete -n <namespace> deployment/duration-test
```
132 changes: 132 additions & 0 deletions tests/duration/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
//
// DISCLAIMER
//
// Copyright 2018 ArangoDB GmbH, Cologne, Germany
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// Copyright holder is ArangoDB GmbH, Cologne, Germany
//
// Author Ewout Prangsma
//

package main

import (
"context"
"crypto/tls"
"flag"
"fmt"
"log"
"os"
"os/signal"
"strings"
"syscall"
"time"

driver "github.com/arangodb/go-driver"
"github.com/arangodb/go-driver/http"
"github.com/pkg/errors"

"github.com/arangodb/kube-arangodb/pkg/util/retry"
)

const (
defaultTestDuration = time.Hour * 24 * 7 // 7 days
)

var (
maskAny = errors.WithStack
userName string
password string
clusterEndpoints string
testDuration time.Duration
)

func init() {
flag.StringVar(&userName, "username", "", "Authenticating username")
flag.StringVar(&password, "password", "", "Authenticating password")
flag.StringVar(&clusterEndpoints, "cluster", "", "Endpoints for database cluster")
flag.DurationVar(&testDuration, "duration", defaultTestDuration, "Duration of the test")
}

func main() {
flag.Parse()

// Create clients & wait for cluster available
client, err := createClusterClient(clusterEndpoints, userName, password)
if err != nil {
log.Fatalf("Failed to create cluster client: %#v\n", err)
}
if err := waitUntilClusterUp(client); err != nil {
log.Fatalf("Failed to reach cluster: %#v\n", err)
}

// Start running tests
ctx, cancel := context.WithCancel(context.Background())
sigChannel := make(chan os.Signal)
signal.Notify(sigChannel, os.Interrupt, syscall.SIGTERM)
go handleSignal(sigChannel, cancel)
runTestLoop(ctx, client, testDuration)
}

// createClusterClient creates a configuration, connection and client for
// one of the two ArangoDB clusters in the test. It uses the go-driver.
// It needs a list of endpoints.
func createClusterClient(endpoints string, user string, password string) (driver.Client, error) {
// This will always use HTTP, and user and password authentication
config := http.ConnectionConfig{
Endpoints: strings.Split(endpoints, ","),
TLSConfig: &tls.Config{InsecureSkipVerify: true},
}
connection, err := http.NewConnection(config)
if err != nil {
return nil, maskAny(err)
}
clientCfg := driver.ClientConfig{
Connection: connection,
Authentication: driver.BasicAuthentication(user, password),
}
client, err := driver.NewClient(clientCfg)
if err != nil {
return nil, maskAny(err)
}
return client, nil
}

func waitUntilClusterUp(c driver.Client) error {
op := func() error {
ctx := context.Background()
if _, err := c.Version(ctx); err != nil {
return maskAny(err)
}
return nil
}
if err := retry.Retry(op, time.Minute); err != nil {
return maskAny(err)
}
return nil
}

// handleSignal listens for termination signals and stops this process on termination.
func handleSignal(sigChannel chan os.Signal, cancel context.CancelFunc) {
signalCount := 0
for s := range sigChannel {
signalCount++
fmt.Println("Received signal:", s)
if signalCount > 1 {
os.Exit(1)
}
cancel()
}
}
50 changes: 50 additions & 0 deletions tests/duration/simple/check.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
//
// DISCLAIMER
//
// Copyright 2018 ArangoDB GmbH, Cologne, Germany
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// Copyright holder is ArangoDB GmbH, Cologne, Germany
//
// Author Ewout Prangsma
//

package simple

import "context"

// isDocumentEqualTo reads an existing document and checks that it is equal to the given document.
// Returns: (isEqual,currentRevision,error)
func (t *simpleTest) isDocumentEqualTo(c *collection, key string, expected UserDocument) (bool, string, error) {
ctx := context.Background()
var result UserDocument
t.log.Info().Msgf("Checking existing document '%s' from '%s'...", key, c.name)
col, err := t.db.Collection(ctx, c.name)
if err != nil {
return false, "", maskAny(err)
}
m, err := col.ReadDocument(ctx, key, &result)
if err != nil {
// This is a failure
t.log.Error().Msgf("Failed to read document '%s' from '%s': %v", key, c.name, err)
return false, "", maskAny(err)
}
// Compare document against expected document
if result.Equals(expected) {
// Found an exact match
return true, m.Rev, nil
}
t.log.Info().Msgf("Document '%s' in '%s' returned different values: got %q expected %q", key, c.name, result, expected)
return false, m.Rev, nil
}
31 changes: 31 additions & 0 deletions tests/duration/simple/error.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
//
// DISCLAIMER
//
// Copyright 2018 ArangoDB GmbH, Cologne, Germany
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// Copyright holder is ArangoDB GmbH, Cologne, Germany
//
// Author Ewout Prangsma
//

package simple

import (
"github.com/pkg/errors"
)

var (
maskAny = errors.WithStack
)
Loading

0 comments on commit b5a732a

Please sign in to comment.