Skip to content

Commit

Permalink
Use translib's new api-tests app in REST gotest (#52)
Browse files Browse the repository at this point in the history
 Why I did it

REST go tests were failing due to failures in ACL request.

- How I did it

1) Modified ProcessXXX testcases to use new api-tests app instead of ACL
app. This allows running end-to-end positive and negative tests without
depending on db state and ACL logic. Added few more test cases.
Depends on sonic-net/sonic-mgmt-common#13.

2) Added few more negative test cases to test translib integration.

3) Added a new tool rest-gotest.sh to run REST server tests from source
or already built test binary. Can be used with tparse or gotestsum too.

rest-gotest.sh               /* run all tests from source */
rest-gotest.sh -bin          /* run already built test binary */
rest-gotest.sh -run Process  /* run only ProcessXXX tests */
rest-gotest.sh -bin -json | tparse
gotestsum -f testname --raw-command -- rest-gotest.sh -json
- How to verify it

REST server gotest

- Description for the changelog

Use translib's new api-tests app in REST gotest
  • Loading branch information
sachinholla committed Jul 15, 2020
1 parent 3c3384c commit b4cafc9
Show file tree
Hide file tree
Showing 3 changed files with 140 additions and 14 deletions.
4 changes: 2 additions & 2 deletions rest/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,8 @@ else
endif

# Gotest binary for REST Server
$(REST_TEST_BIN): $(REST_TEST_SRCS) $(REST_GO_SRCS) | $(REST_BUILD_DIR)/
$(GO) test -mod=vendor -cover -c ../rest/server -o $@
$(REST_TEST_BIN): $(REST_TEST_SRCS) $(REST_SRCS) | $(REST_BUILD_DIR)/
$(GO) test -mod=vendor -tags test -cover -c ../rest/server -o $@

# Compile certificate generator from standard crypto/tls/generate_cert.go.
# Source file will be available in GOROOT/src.
Expand Down
68 changes: 56 additions & 12 deletions rest/server/handler_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
package server

import (
"encoding/json"
"encoding/xml"
"errors"
"fmt"
Expand Down Expand Up @@ -440,38 +441,62 @@ func testRespData(r *http.Request, rc *RequestContext, data []byte, expType stri

func TestProcessGET(t *testing.T) {
w := httptest.NewRecorder()
Process(w, prepareRequest(t, "GET", "/test", ""))
verifyResponse(t, w, 500)
Process(w, prepareRequest(t, "GET", "/api-tests:sample", ""))
verifyResponseData(t, w, 200, jsonObj{"path": "/api-tests:sample", "depth": 0})
}

func TestProcessGET_ACL(t *testing.T) {
func TestProcessGET_error(t *testing.T) {
w := httptest.NewRecorder()
Process(w, prepareRequest(t, "GET", "/openconfig-acl:acl", ""))
verifyResponse(t, w, 200)
Process(w, prepareRequest(t, "GET", "/api-tests:sample/error/not-found", ""))
verifyResponse(t, w, 404)
}

func TestProcessPUT(t *testing.T) {
w := httptest.NewRecorder()
Process(w, prepareRequest(t, "PUT", "/test", "{}"))
verifyResponse(t, w, 500)
Process(w, prepareRequest(t, "PUT", "/api-tests:sample", "{}"))
verifyResponse(t, w, 204)
}

func TestProcessPUT_error(t *testing.T) {
w := httptest.NewRecorder()
Process(w, prepareRequest(t, "PUT", "/api-tests:sample/error/not-supported", "{}"))
verifyResponse(t, w, 405)
}

func TestProcessPOST(t *testing.T) {
w := httptest.NewRecorder()
Process(w, prepareRequest(t, "POST", "/test", "{}"))
verifyResponse(t, w, 500)
Process(w, prepareRequest(t, "POST", "/api-tests:sample", "{}"))
verifyResponse(t, w, 201)
}

func TestProcessPOST_error(t *testing.T) {
w := httptest.NewRecorder()
Process(w, prepareRequest(t, "POST", "/api-tests:sample/error/invalid-args", "{}"))
verifyResponse(t, w, 400)
}

func TestProcessPATCH(t *testing.T) {
w := httptest.NewRecorder()
Process(w, prepareRequest(t, "PATCH", "/test", "{}"))
Process(w, prepareRequest(t, "PATCH", "/api-tests:sample", "{}"))
verifyResponse(t, w, 204)
}

func TestProcessPATCH_error(t *testing.T) {
w := httptest.NewRecorder()
Process(w, prepareRequest(t, "PATCH", "/api-tests:sample/error/unknown", "{}"))
verifyResponse(t, w, 500)
}

func TestProcessDELETE(t *testing.T) {
w := httptest.NewRecorder()
Process(w, prepareRequest(t, "DELETE", "/test", "{}"))
verifyResponse(t, w, 500)
Process(w, prepareRequest(t, "DELETE", "/api-tests:sample", "{}"))
verifyResponse(t, w, 204)
}

func TestProcessDELETE_error(t *testing.T) {
w := httptest.NewRecorder()
Process(w, prepareRequest(t, "DELETE", "/api-tests:sample/error/not-found", ""))
verifyResponse(t, w, 404)
}

func TestProcessBadMethod(t *testing.T) {
Expand Down Expand Up @@ -522,3 +547,22 @@ func verifyResponse(t *testing.T, w *httptest.ResponseRecorder, expCode int) {
t.Fatalf("Expecting response status %d; got %d", expCode, w.Code)
}
}

type jsonObj map[string]interface{}

func verifyResponseData(t *testing.T, w *httptest.ResponseRecorder,
expCode int, expData jsonObj) {
verifyResponse(t, w, expCode)

data := make(jsonObj)
err := json.Unmarshal(w.Body.Bytes(), &data)
if err != nil {
t.Fatalf("Unmarshal error: %v", err)
}

for k, v := range expData {
if fmt.Sprintf("%v", v) != fmt.Sprintf("%v", data[k]) {
t.Fatalf("Data mismatch for key '%s'; exp='%v', found='%v'", k, v, data[k])
}
}
}
82 changes: 82 additions & 0 deletions tools/test/rest-gotest.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
#!/usr/bin/env bash
################################################################################
# #
# Copyright 2020 Broadcom. The term Broadcom refers to Broadcom Inc. and/or #
# its subsidiaries. #
# #
# 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. #
# #
################################################################################

set -e

[[ -z ${TOPDIR} ]] && TOPDIR=$(git rev-parse --show-toplevel) || true
[[ -z ${GO} ]] && GO=go || true

TESTARGS=()

while [[ $# -gt 0 ]]; do
case "$1" in
-h|-help|--help)
echo "usage: $(basename $0) [-bin] [-json] [-run NAME] [-auth] [ARGS...]"
echo ""
echo " -bin Run test binary {TOPDIR}/build/tests/rest/server.test"
echo " -json Prints output in json format"
echo " -run NAME Run specific test cases."
echo " -auth Run auth tests; shorthand for '-run Auth -authtest local'"
echo " ARGS... Arguments to test program (log level, auth test arguments etc)"
exit 0 ;;
-bin)
TESTBIN=${TOPDIR}/build/tests/rest/server.test
shift ;;
-json)
JSON=1
shift ;;
-run)
TESTCASE="$2"
shift 2 ;;
-auth)
TESTCASE="Auth"
TESTARGS+=("-authtest" "local")
shift ;;
*)
TESTARGS+=("$1")
shift;;
esac
done

MGMT_COMMON_DIR=$(realpath ${TOPDIR}/../sonic-mgmt-common)

export CVL_SCHEMA_PATH=${MGMT_COMMON_DIR}/build/cvl/schema

PKG="github.com/Azure/sonic-mgmt-framework/rest/server"
DIR="${PWD}"

if [[ -z ${TESTBIN} ]]; then
# run "go test" from source
CMD=( ${GO} test "${PKG}" -mod=vendor -v -cover -tags test )
[[ -z ${JSON} ]] || CMD+=( -json )
[[ -z ${TESTCASE} ]] || CMD+=( -run "${TESTCASE}" )
CMD+=( -args ) #keep it last
else
# run compiled test binary
DIR="$(dirname ${TESTBIN})"
CMD=( ./$(basename ${TESTBIN}) -test.v )
[[ -z ${JSON} ]] || CMD=( ${GO} tool test2json -p "${PKG}" -t "${CMD[@]}" )
[[ -z ${TESTCASE} ]] || CMD+=( -test.run "${TESTCASE}" )
fi

[[ "${TESTARGS[@]}" =~ -(also)?logtostderr ]] || TESTARGS+=( -logtostderr )

(cd "${DIR}" && "${CMD[@]}" "${TESTARGS[@]}")

0 comments on commit b4cafc9

Please sign in to comment.