SEBA-902 mock testing of redfish importer;
Remove hardcoded addresses and replace with config file / cmdline;
Support hostnames in importer as alternative to ip addresses;
Treat response 204 as success
Change-Id: I17e8e585e388c501c02867ce952bbe1fa9b09668
diff --git a/demo_test/Dockerfile b/demo_test/Dockerfile
new file mode 100644
index 0000000..efd6ce9
--- /dev/null
+++ b/demo_test/Dockerfile
@@ -0,0 +1,62 @@
+# copyright 2018-present Open Networking Foundation
+#
+# 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.
+
+FROM golang:1.12 AS build-env
+SHELL ["/bin/bash", "-o", "pipefail", "-c"]
+RUN /bin/true | cat
+RUN apt-get update && apt-get install --no-install-recommends -y --allow-downgrades \
+ git=1:2.20.1-2+deb10u1 \
+ gcc=4:8.3.0-1 \
+ curl=7.64.0-4 \
+ unzip=6.0-23+deb10u1
+# Install these prereqs now so they get built into a container layer and cached
+# TODO: Revisit once demo-test implements mod=vendor
+RUN go get -v google.golang.org/grpc \
+ && go get -v github.com/grpc-ecosystem/grpc-gateway/protoc-gen-grpc-gateway \
+ && go get -v github.com/golang/protobuf/protoc-gen-go \
+ && go get github.com/sirupsen/logrus \
+ && go get github.com/Shopify/sarama
+# Install protoc, same steps as in main importer dockerfile
+ENV PROTOC_VERSION="3.7.0"
+ENV PROTOC_SHA256SUM="a1b8ed22d6dc53c5b8680a6f1760a305b33ef471bece482e92728f00ba2a2969"
+RUN curl -L -o /tmp/protoc-${PROTOC_VERSION}-linux-x86_64.zip https://github.com/google/protobuf/releases/download/v${PROTOC_VERSION}/protoc-${PROTOC_VERSION}-linux-x86_64.zip \
+ && mkdir /tmp/protoc3 \
+ && echo "$PROTOC_SHA256SUM /tmp/protoc-${PROTOC_VERSION}-linux-x86_64.zip" | sha256sum -c - \
+ && unzip /tmp/protoc-${PROTOC_VERSION}-linux-x86_64.zip -d /tmp/protoc3 \
+ && mv /tmp/protoc3/bin/* /usr/local/bin/ \
+ && mv /tmp/protoc3/include/* /usr/local/include/
+RUN mkdir /app
+COPY . /app/
+WORKDIR /app
+ENV GO111MODULE=on
+ENV PROTOC_VERSION="3.7.0"
+ENV PROTOC_SHA256SUM="a1b8ed22d6dc53c5b8680a6f1760a305b33ef471bece482e92728f00ba2a2969"
+
+WORKDIR /app/demo_test
+RUN make prereq
+RUN make proto/importer.pb.go
+# Note: "make demotest" produces an executable that throws "No such file" errors. Investigate.
+RUN GO111MODULE=on CGO_ENABLED=0 GOOS=linux go build -o demotest .
+
+# Also build the client, as having it inside the container may facilitate testing without
+# having to setup port forwardin
+WORKDIR /app/demo_test/functional_test
+RUN GO111MODULE=on CGO_ENABLED=0 GOOS=linux go build -o dm .
+
+FROM alpine:3.9.4
+WORKDIR /app/demo_test
+COPY --from=build-env /app/demo_test/demotest .
+COPY --from=build-env /app/demo_test/functional_test/dm .
+ENTRYPOINT ["./demotest"]
+
diff --git a/demo_test/Makefile b/demo_test/Makefile
index 4296147..4ceae91 100644
--- a/demo_test/Makefile
+++ b/demo_test/Makefile
@@ -12,6 +12,26 @@
# See the License for the specific language governing permissions and
# limitations under the License.
+# Configure shell
+SHELL = bash -eu -o pipefail
+
+# Variables
+VERSION ?= $(shell cat ../VERSION)
+CONTAINER_NAME ?= redfish-importer-demotest
+
+## Docker related
+DOCKER_REGISTRY ?=
+DOCKER_REPOSITORY ?=
+DOCKER_BUILD_ARGS ?=
+DOCKER_TAG ?= ${VERSION}
+DOCKER_IMAGENAME := ${DOCKER_REGISTRY}${DOCKER_REPOSITORY}${CONTAINER_NAME}:${DOCKER_TAG}
+
+## Docker labels. Only set ref and commit date if committed
+DOCKER_LABEL_VCS_URL ?= $(shell git remote get-url $(shell git remote))
+DOCKER_LABEL_VCS_REF ?= $(shell git diff-index --quiet HEAD -- && git rev-parse HEAD || echo "unknown")
+DOCKER_LABEL_COMMIT_DATE ?= $(shell git diff-index --quiet HEAD -- && git show -s --format=%cd --date=iso-strict HEAD || echo "unknown" )
+DOCKER_LABEL_BUILD_DATE ?= $(shell date -u "+%Y-%m-%dT%H:%M:%SZ")
+
prereq:
go get -v google.golang.org/grpc
go get -v github.com/grpc-ecosystem/grpc-gateway/protoc-gen-grpc-gateway
@@ -22,10 +42,22 @@
demotest: prereq proto/importer.pb.go
go build -i -v -o $@
-
proto/importer.pb.go: ../proto/importer.proto
mkdir -p proto
protoc --proto_path=../proto \
-I${GOPATH}/src/github.com/grpc-ecosystem/grpc-gateway/third_party/googleapis \
--go_out=plugins=grpc:proto/ \
../proto/importer.proto
+
+docker-build:
+ docker build $(DOCKER_BUILD_ARGS) \
+ -t ${DOCKER_IMAGENAME} \
+ --build-arg org_label_schema_version="${VERSION}" \
+ --build-arg org_label_schema_vcs_url="${DOCKER_LABEL_VCS_URL}" \
+ --build-arg org_label_schema_vcs_ref="${DOCKER_LABEL_VCS_REF}" \
+ --build-arg org_label_schema_build_date="${DOCKER_LABEL_BUILD_DATE}" \
+ --build-arg org_opencord_vcs_commit_date="${DOCKER_LABEL_COMMIT_DATE}" \
+ -f Dockerfile ..
+
+docker-push:
+ docker push ${DOCKER_IMAGENAME}
diff --git a/demo_test/config.go b/demo_test/config.go
new file mode 100644
index 0000000..e8bd589
--- /dev/null
+++ b/demo_test/config.go
@@ -0,0 +1,126 @@
+/*
+ * Copyright 2018-present Open Networking Foundation
+ *
+ * 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.
+ */
+
+// Implements global configuration for demotest
+package main
+
+import (
+ "fmt"
+ flags "github.com/jessevdk/go-flags"
+ "gopkg.in/yaml.v2"
+ "io/ioutil"
+ "log"
+ "os"
+ "path"
+ "path/filepath"
+ "strings"
+)
+
+type OutputType uint8
+
+type GlobalConfigSpec struct {
+ Kafka string `yaml:"kafka"`
+ Local string `yaml:"local"`
+ Importer string `yaml:"importer"`
+}
+
+var (
+ CharReplacer = strings.NewReplacer("\\t", "\t", "\\n", "\n")
+
+ GlobalConfig = GlobalConfigSpec{
+ Kafka: "kafka_ip.sh",
+ Local: ":9999",
+ Importer: "localhost:31085",
+ }
+
+ GlobalCommandOptions = make(map[string]map[string]string)
+
+ GlobalOptions struct {
+ Config string `short:"c" long:"config" env:"PROXYCONFIG" value-name:"FILE" default:"" description:"Location of proxy config file"`
+ Kafka string `short:"k" long:"kafka" default:"" value-name:"SERVER:PORT" description:"IP/Host and port of Kafka"`
+ Importer string `short:"i" long:"importer" default:"" value-name:"SERVER:PORT" description:"IP/Host and port of Importer"`
+ Local string `short:"l" long:"local" default:"" value-name:"SERVER:PORT" description:"IP/Host and port to listen on"`
+ }
+
+ Debug = log.New(os.Stdout, "DEBUG: ", 0)
+ Info = log.New(os.Stdout, "INFO: ", 0)
+ Warn = log.New(os.Stderr, "WARN: ", 0)
+ Error = log.New(os.Stderr, "ERROR: ", 0)
+)
+
+func ParseCommandLine() {
+ parser := flags.NewNamedParser(path.Base(os.Args[0]),
+ flags.HelpFlag|flags.PassDoubleDash|flags.PassAfterNonOption)
+ _, err := parser.AddGroup("Global Options", "", &GlobalOptions)
+ if err != nil {
+ panic(err)
+ }
+
+ _, err = parser.ParseArgs(os.Args[1:])
+ if err != nil {
+ _, ok := err.(*flags.Error)
+ if ok {
+ real := err.(*flags.Error)
+ if real.Type == flags.ErrHelp {
+ os.Stdout.WriteString(err.Error() + "\n")
+ os.Exit(0)
+ }
+ }
+
+ fmt.Fprintf(os.Stderr, "%s: %s\n", os.Args[0], err.Error())
+
+ os.Exit(1)
+ }
+}
+
+func ProcessGlobalOptions() {
+ if len(GlobalOptions.Config) == 0 {
+ home, err := os.UserHomeDir()
+ if err != nil {
+ Warn.Printf("Unable to discover the user's home directory: %s", err)
+ home = "~"
+ }
+ GlobalOptions.Config = filepath.Join(home, ".redfish-importer", "demotest-config")
+ }
+
+ if info, err := os.Stat(GlobalOptions.Config); err == nil && !info.IsDir() {
+ configFile, err := ioutil.ReadFile(GlobalOptions.Config)
+ if err != nil {
+ Error.Fatalf("Unable to read the configuration file '%s': %s",
+ GlobalOptions.Config, err.Error())
+ }
+ if err = yaml.Unmarshal(configFile, &GlobalConfig); err != nil {
+ Error.Fatalf("Unable to parse the configuration file '%s': %s",
+ GlobalOptions.Config, err.Error())
+ }
+ }
+
+ if GlobalOptions.Kafka != "" {
+ GlobalConfig.Kafka = GlobalOptions.Kafka
+ }
+ if GlobalOptions.Local != "" {
+ GlobalConfig.Local = GlobalOptions.Local
+ }
+ if GlobalOptions.Importer != "" {
+ GlobalConfig.Importer = GlobalOptions.Importer
+ }
+}
+
+func ShowGlobalOptions() {
+ log.Printf("Configuration:")
+ log.Printf(" Kafka: %v", GlobalConfig.Kafka)
+ log.Printf(" Listen Address: %v", GlobalConfig.Local)
+}
diff --git a/demo_test/functional_test/test_cli.go b/demo_test/functional_test/test_cli.go
index 3a1bc95..81cfe07 100644
--- a/demo_test/functional_test/test_cli.go
+++ b/demo_test/functional_test/test_cli.go
@@ -19,16 +19,32 @@
import "bufio"
import "os"
import "strings"
+import "log"
func main() {
+ if len(os.Args) <= 1 {
+ log.Printf("Syntax: ./dm <arguments>")
+ os.Exit(-1)
+ }
+
// connect to this socket
cmdstr := strings.Join(os.Args[1:], " ")
- conn, _ := net.Dial("tcp", "127.0.0.1:9999")
+ conn, err := net.Dial("tcp", "127.0.0.1:9999")
+ if err != nil {
+ log.Printf("Error opening connection: %v", err)
+ os.Exit(-1)
+ }
+
// send to socket
fmt.Fprintf(conn, cmdstr+"\n")
// listen for reply
- message, _ := bufio.NewReader(conn).ReadString(';')
+ message, err := bufio.NewReader(conn).ReadString(';')
+ if err != nil {
+ log.Printf("Error reading result: %v", err)
+ os.Exit(-1)
+ }
+
message = strings.TrimSuffix(message, ";")
fmt.Print(message)
}
diff --git a/demo_test/test.go b/demo_test/test.go
index 438ae74..8d929a0 100644
--- a/demo_test/test.go
+++ b/demo_test/test.go
@@ -41,7 +41,6 @@
"alert": "Alert",
"update": "Update"}
-var default_address string = "localhost:31085"
var importerTopic = "importer"
var DataConsumer sarama.Consumer
@@ -95,20 +94,24 @@
}
func kafkainit() {
- cmd := exec.Command("/bin/sh", "kafka_ip.sh")
var kafkaIP string
- var out bytes.Buffer
- cmd.Stdout = &out
- err := cmd.Run()
- if err != nil {
- logrus.Info(err)
- os.Exit(1)
+ if GlobalConfig.Kafka == "kafka_ip.sh" {
+ cmd := exec.Command("/bin/sh", "kafka_ip.sh")
+ var out bytes.Buffer
+ cmd.Stdout = &out
+ err := cmd.Run()
+ if err != nil {
+ logrus.Info(err)
+ os.Exit(1)
+ }
+ kafkaIP = out.String()
+ kafkaIP = strings.TrimSuffix(kafkaIP, "\n")
+ kafkaIP = kafkaIP + ":9092"
+ logrus.Infof("IP address of kafka-cord-0:%s", kafkaIP)
+ } else {
+ kafkaIP = GlobalConfig.Kafka
}
- kafkaIP = out.String()
- kafkaIP = strings.TrimSuffix(kafkaIP, "\n")
- kafkaIP = kafkaIP + ":9092"
- logrus.Infof("IP address of kafka-cord-0:%s", kafkaIP)
config := sarama.NewConfig()
config.Consumer.Return.Errors = true
master, err := sarama.NewConsumer([]string{kafkaIP}, config)
@@ -119,20 +122,25 @@
go topicListener(&importerTopic, master)
}
+
func main() {
+ ParseCommandLine()
+ ProcessGlobalOptions()
+ ShowGlobalOptions()
+
http.DefaultTransport.(*http.Transport).TLSClientConfig = &tls.Config{InsecureSkipVerify: true}
logrus.Info("Launching server...")
logrus.Info("kafkaInit starting")
kafkainit()
- ln, err := net.Listen("tcp", ":9999")
+ ln, err := net.Listen("tcp", GlobalConfig.Local)
if err != nil {
fmt.Println("could not listen")
logrus.Fatalf("did not listen: %v", err)
}
defer ln.Close()
- conn, err = grpc.Dial(default_address, grpc.WithInsecure())
+ conn, err = grpc.Dial(GlobalConfig.Importer, grpc.WithInsecure())
if err != nil {
logrus.Fatalf("did not connect: %v", err)
}