Skip to content

Commit

Permalink
Merge pull request #58 from hyperledger-labs/fix/godog
Browse files Browse the repository at this point in the history
Fix godog tests
  • Loading branch information
samuelvenzi authored Feb 5, 2024
2 parents 489725d + 63bffc2 commit c26deec
Show file tree
Hide file tree
Showing 18 changed files with 118 additions and 45 deletions.
7 changes: 5 additions & 2 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,5 +24,8 @@ jobs:
- name: Build
run: go build -v github.com/hyperledger-labs/cc-tools-demo/chaincode

- name: Test
run: go test github.com/hyperledger-labs/cc-tools-demo/chaincode -coverpkg=./... -v
- name: Unit tests
run: go test github.com/hyperledger-labs/cc-tools-demo/chaincode -coverpkg=./... -v

- name: Integration tests
run: go test -v ./tests
5 changes: 2 additions & 3 deletions ccapi/chaincode/invoke.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,9 @@ func Invoke(channelName, ccName, txName string, txArgs [][]byte, transientReques
}

res, err := fabMngr.Client.Execute(rq, channel.WithRetry(retry.DefaultChannelOpts))

if err != nil {
return nil, http.StatusInternalServerError, err
return nil, extractStatusCode(err.Error()), err
}

return &res, http.StatusInternalServerError, nil
return &res, http.StatusOK, nil
}
6 changes: 3 additions & 3 deletions ccapi/chaincode/query.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,10 @@ func Query(channelName, ccName, txName string, txArgs [][]byte) (*channel.Respon
}

res, err := fabMngr.Client.Query(rq, channel.WithRetry(retry.DefaultChannelOpts))

if err != nil {
return nil, http.StatusInternalServerError, err
status := extractStatusCode(err.Error())
return nil, status, err
}

return &res, http.StatusInternalServerError, nil
return &res, http.StatusOK, nil
}
26 changes: 26 additions & 0 deletions ccapi/chaincode/utils.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package chaincode

import (
"fmt"
"net/http"
"regexp"
"strconv"
)

func extractStatusCode(msg string) int {
re := regexp.MustCompile(`Code:\s*\((\d+)\)`)

matches := re.FindStringSubmatch(msg)
if len(matches) == 0 {
fmt.Println("No status code found in message")
return http.StatusInternalServerError
}

statusCode, err := strconv.Atoi(matches[1])
if err != nil {
fmt.Println("Failed to parse string to int when extracting status code")
return http.StatusInternalServerError
}

return statusCode
}
2 changes: 1 addition & 1 deletion ccapi/handlers/invoke.go
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ func Invoke(c *gin.Context) {

res, status, err := chaincode.Invoke(channelName, chaincodeName, txName, argList, transientMapByte)
if err != nil {
common.Abort(c, http.StatusInternalServerError, err)
common.Abort(c, status, err)
return
}

Expand Down
2 changes: 1 addition & 1 deletion ccapi/handlers/invokeV1.go
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ func InvokeV1(c *gin.Context) {

res, status, err := chaincode.Invoke(channelName, chaincodeName, txName, argList, transientMapByte)
if err != nil {
common.Abort(c, http.StatusInternalServerError, err)
common.Abort(c, status, err)
return
}

Expand Down
2 changes: 1 addition & 1 deletion ccapi/handlers/query.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ func Query(c *gin.Context) {

res, status, err := chaincode.Query(channelName, chaincodeName, txName, argList)
if err != nil {
common.Abort(c, http.StatusInternalServerError, err)
common.Abort(c, status, err)
return
}

Expand Down
2 changes: 1 addition & 1 deletion ccapi/handlers/queryV1.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ func QueryV1(c *gin.Context) {

res, status, err := chaincode.Query(channelName, chaincodeName, txName, argList)
if err != nil {
common.Abort(c, http.StatusInternalServerError, err)
common.Abort(c, status, err)
return
}

Expand Down
4 changes: 2 additions & 2 deletions chaincode/tests/features/createNewLibrary.feature
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ Feature: Create New Library

Scenario: Create a new library
Given there is a running "" test network from scratch
When I make a "POST" request to "/api/invoke/createNewLibrary" on port 880 with:
When I make a "POST" request to "/api/invoke/createNewLibrary" on port 80 with:
"""
{
"name": "Elizabeth's Library"
Expand All @@ -26,7 +26,7 @@ Feature: Create New Library
Scenario: Try to create a new library with a name that already exists
Given there is a running "" test network
Given there is a library with name "John's Library"
When I make a "POST" request to "/api/invoke/createNewLibrary" on port 880 with:
When I make a "POST" request to "/api/invoke/createNewLibrary" on port 80 with:
"""
{
"name": "John's Library"
Expand Down
6 changes: 3 additions & 3 deletions chaincode/tests/features/getBooksByAuthor.feature
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ Feature: Get Books By Author
Scenario: Request an author with multiple books
Given there is a running "" test network
And there are 3 books with prefix "book" by author "Jack"
When I make a "GET" request to "/api/query/getBooksByAuthor" on port 880 with:
When I make a "GET" request to "/api/query/getBooksByAuthor" on port 80 with:
"""
{
"authorName": "Jack"
Expand All @@ -18,7 +18,7 @@ Feature: Get Books By Author

Scenario: Request an author with no books
Given there is a running "" test network
When I make a "GET" request to "/api/query/getBooksByAuthor" on port 880 with:
When I make a "GET" request to "/api/query/getBooksByAuthor" on port 80 with:
"""
{
"authorName": "Mary"
Expand All @@ -31,7 +31,7 @@ Feature: Get Books By Author
Given there is a running "" test network
Given there are 1 books with prefix "fantasy" by author "Missy"
Given there are 2 books with prefix "cook" by author "John"
When I make a "GET" request to "/api/query/getBooksByAuthor" on port 880 with:
When I make a "GET" request to "/api/query/getBooksByAuthor" on port 80 with:
"""
{
"authorName": "John"
Expand Down
8 changes: 4 additions & 4 deletions chaincode/tests/features/getNumberOfBooksFromLibrary.feature
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ Feature: Get Number Of Books From Library

Scenario: Query Get Number Of Books From Library that Exists
Given there is a running "" test network
And I make a "POST" request to "/api/invoke/createAsset" on port 880 with:
And I make a "POST" request to "/api/invoke/createAsset" on port 80 with:
"""
{
"asset": [
Expand All @@ -17,7 +17,7 @@ Feature: Get Number Of Books From Library
]
}
"""
And I make a "POST" request to "/api/invoke/createAsset" on port 880 with:
And I make a "POST" request to "/api/invoke/createAsset" on port 80 with:
"""
{
"asset": [{
Expand All @@ -32,7 +32,7 @@ Feature: Get Number Of Books From Library
}]
}
"""
When I make a "GET" request to "/api/query/getNumberOfBooksFromLibrary" on port 880 with:
When I make a "GET" request to "/api/query/getNumberOfBooksFromLibrary" on port 80 with:
"""
{
"library": {
Expand All @@ -51,7 +51,7 @@ Feature: Get Number Of Books From Library

Scenario: Query Get Number Of Books From Library that Does Not Exists
Given there is a running "" test network
When I make a "GET" request to "/api/query/getNumberOfBooksFromLibrary" on port 880 with:
When I make a "GET" request to "/api/query/getNumberOfBooksFromLibrary" on port 80 with:
"""
{
"library": {
Expand Down
8 changes: 4 additions & 4 deletions chaincode/tests/features/updateBookTentant.feature
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ Feature: Update Book Tentant
Scenario: Update Book With A Existing Tentant
# The first 3 statements will be used by all scenarios on this feature
Given there is a running "" test network
And I make a "POST" request to "/api/invoke/createAsset" on port 880 with:
And I make a "POST" request to "/api/invoke/createAsset" on port 80 with:
"""
{
"asset": [{
Expand All @@ -16,7 +16,7 @@ Feature: Update Book Tentant
}]
}
"""
And I make a "POST" request to "/api/invoke/createAsset" on port 880 with:
And I make a "POST" request to "/api/invoke/createAsset" on port 80 with:
"""
{
"asset": [{
Expand All @@ -26,7 +26,7 @@ Feature: Update Book Tentant
}]
}
"""
When I make a "PUT" request to "/api/invoke/updateBookTenant" on port 880 with:
When I make a "PUT" request to "/api/invoke/updateBookTenant" on port 80 with:
"""
{
"book": {
Expand Down Expand Up @@ -55,7 +55,7 @@ Feature: Update Book Tentant

Scenario: Update Book With A Not Existing Tentant
Given there is a running "" test network
When I make a "PUT" request to "/api/invoke/updateBookTenant" on port 880 with:
When I make a "PUT" request to "/api/invoke/updateBookTenant" on port 80 with:
"""
{
"book": {
Expand Down
45 changes: 45 additions & 0 deletions chaincode/tests/main_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package tests

import (
"flag"
"os"
"testing"

"github.com/cucumber/godog"
"github.com/cucumber/godog/colors"
)

var opts = godog.Options{
Output: colors.Colored(os.Stdout),
Format: Format(),
StopOnFailure: true,
}

func init() {
godog.BindCommandLineFlags("godog.", &opts)
}

func TestMain(m *testing.M) {
flag.Parse()
opts.Paths = flag.Args()

status := godog.TestSuite{
Name: "cc-tools-demo cucumber tests",
TestSuiteInitializer: InitializeTestSuite,
ScenarioInitializer: InitializeScenario,
Options: &opts,
}.Run()

os.Exit(status)
}

func Format() string {
format := "progress"
for _, arg := range os.Args[1:] {
if arg == "-test.v=true" { // go test transforms -v option
format = "pretty"
break
}
}
return format
}
19 changes: 12 additions & 7 deletions chaincode/tests/request_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,7 @@ func thereAreBooksWithPrefixByAuthor(ctx context.Context, nBooks int, prefix str
}
dataAsBytes := bytes.NewBuffer([]byte(jsonStr))

if res, err = http.Post("http://localhost:880/api/invoke/createAsset", "application/json", dataAsBytes); err != nil {
if res, err = http.Post("http://localhost:80/api/invoke/createAsset", "application/json", dataAsBytes); err != nil {
return ctx, err
}

Expand Down Expand Up @@ -253,7 +253,7 @@ func thereIsALibraryWithName(ctx context.Context, name string) (context.Context,
}

// Create library if it doesnt exists
if len(received["result"].([]interface{})) == 0 {
if received["result"] == nil || len(received["result"].([]interface{})) == 0 {
requestJSON = map[string]interface{}{
"asset": []interface{}{
map[string]interface{}{
Expand All @@ -268,7 +268,7 @@ func thereIsALibraryWithName(ctx context.Context, name string) (context.Context,
}
dataAsBytes = bytes.NewBuffer([]byte(jsonStr))

if res, err = http.Post("http://localhost:880/api/invoke/createAsset", "application/json", dataAsBytes); err != nil {
if res, err = http.Post("http://localhost:80/api/invoke/createAsset", "application/json", dataAsBytes); err != nil {
return ctx, err
}

Expand All @@ -282,7 +282,8 @@ func thereIsALibraryWithName(ctx context.Context, name string) (context.Context,

func thereIsARunningTestNetworkFromScratch(arg1 string) error {
// Start test network with 1 org only
cmd := exec.Command("../../startDev.sh", "-n", "1")
cmd := exec.Command("./startDev.sh", "-n", "1")
cmd.Dir = "../../"

_, err := cmd.Output()

Expand All @@ -292,7 +293,7 @@ func thereIsARunningTestNetworkFromScratch(arg1 string) error {
}

// Wait for ccapi
err = waitForNetwork("880")
err = waitForNetwork("80")
if err != nil {
fmt.Println(err.Error())
return err
Expand All @@ -302,7 +303,7 @@ func thereIsARunningTestNetworkFromScratch(arg1 string) error {
}

func thereIsARunningTestNetwork(arg1 string) error {
if !verifyContainer("api.org.example.com", "3000") {
if !verifyContainer("ccapi.org.example.com", "80") {
// Start test network with 1 org only
cmd := exec.Command("../../startDev.sh", "-n", "1")

Expand All @@ -314,7 +315,7 @@ func thereIsARunningTestNetwork(arg1 string) error {
}

// Wait for ccapi
err = waitForNetwork("880")
err = waitForNetwork("80")
if err != nil {
fmt.Println(err.Error())
return err
Expand All @@ -323,6 +324,10 @@ func thereIsARunningTestNetwork(arg1 string) error {
return nil
}

func InitializeTestSuite(ctx *godog.TestSuiteContext) {
ctx.BeforeSuite(func() {})
}

func InitializeScenario(ctx *godog.ScenarioContext) {
ctx.Step(`^I make a "([^"]*)" request to "([^"]*)" on port (\d+) with:$`, iMakeARequestToOnPortWith)
ctx.Step(`^the response code should be (\d+)$`, theResponseCodeShouldBe)
Expand Down
2 changes: 1 addition & 1 deletion chaincode/txdefs/createNewLibrary.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ var CreateNewLibrary = tx.Transaction{
// Save the new library on channel
_, err = libraryAsset.PutNew(stub)
if err != nil {
return nil, errors.WrapError(err, "Error saving asset on blockchain")
return nil, errors.WrapErrorWithStatus(err, "Error saving asset on blockchain", err.Status())
}

// Marshal asset back to JSON format
Expand Down
2 changes: 1 addition & 1 deletion chaincode/txdefs/getNumberOfBooksFromLibrary.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ var GetNumberOfBooksFromLibrary = tx.Transaction{
// Returns Library from channel
libraryMap, err := libraryKey.GetMap(stub)
if err != nil {
return nil, errors.WrapError(err, "failed to get asset from the ledger")
return nil, errors.WrapErrorWithStatus(err, "failed to get asset from the ledger", err.Status())
}

numberOfBooks := 0
Expand Down
4 changes: 2 additions & 2 deletions chaincode/txdefs/updateBookTentant.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,14 +46,14 @@ var UpdateBookTenant = tx.Transaction{
// Returns Book from channel
bookAsset, err := bookKey.Get(stub)
if err != nil {
return nil, errors.WrapError(err, "failed to get asset from the ledger")
return nil, errors.WrapErrorWithStatus(err, "failed to get asset from the ledger", err.Status())
}
bookMap := (map[string]interface{})(*bookAsset)

// Returns person from channel
tenantAsset, err := tenantKey.Get(stub)
if err != nil {
return nil, errors.WrapError(err, "failed to get asset from the ledger")
return nil, errors.WrapErrorWithStatus(err, "failed to get asset from the ledger", err.Status())
}
tenantMap := (map[string]interface{})(*tenantAsset)

Expand Down
13 changes: 4 additions & 9 deletions godog.sh
Original file line number Diff line number Diff line change
@@ -1,13 +1,8 @@
#!/usr/bin/env bash

which godog
if [ "$?" -ne 0 ]; then
echo "ERROR: godog tool not found. Please install it to run godog tests."
echo " Read more about the tool on: https://github.com/cucumber/godog"
echo "exiting..."
exit 1
fi
echo "Starting development network ..."
# ./startDev.sh -n 1

echo "Running GoDog tests..."
echo "You may be prompted to insert system password for cert generation."
cd ./chaincode/tests; rm -rf ca channel-artifacts crypto-config; godog run;
echo "Tests may take a few minutes to complete..."
cd ./chaincode/tests; go test;

0 comments on commit c26deec

Please sign in to comment.