Skip to content
This repository has been archived by the owner on Dec 7, 2023. It is now read-only.

Initial continuous integration with Travis CI #77

Merged
merged 2 commits into from Jan 2, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
8 changes: 8 additions & 0 deletions .travis.yml
@@ -0,0 +1,8 @@
sudo: required

services:
- docker

script:
- docker build -f ci/Dockerfile -t neo-cli-ci .
- docker run neo-cli-ci /opt/ci/run-tests-in-docker.sh
30 changes: 30 additions & 0 deletions ci/Dockerfile
@@ -0,0 +1,30 @@
FROM microsoft/dotnet:2.0-sdk

# Install dependencies:
RUN apt-get update && apt-get install -y \
libleveldb-dev \
sqlite3 \
libsqlite3-dev \
libunwind8-dev \
wget \
expect \
screen \
zip

# APT cleanup to reduce image size
RUN rm -rf /var/lib/apt/lists/*

WORKDIR /opt

# Get code to test
ADD neo-cli /opt/neo-cli-github
ADD ci /opt/ci

WORKDIR /opt/neo-cli-github

# Build the project
RUN dotnet restore
RUN dotnet publish -c Release
RUN mv bin/Release/netcoreapp2.0/publish /opt/neo-cli

WORKDIR /opt
14 changes: 14 additions & 0 deletions ci/README.md
@@ -0,0 +1,14 @@
These are files for the continuous integration with Travis CI.

On each code push, the following tasks are executed:

* Build the latest code
* Verify the basic neo-cli functionality using [expect](https://linux.die.net/man/1/expect)
* Verify JSON-RPC functionality with curl

The CI integration consists of the following parts:

* `Dockerfile`: the system to build neo-cli and to run the tests
* `build-and-test.sh`: this builds the Docker image, starts it and runs the tests inside. This is useful for testing the CI run on a local dev machine.
* `run-tests-in-docker.sh`: is run inside the Docker container and executes the tests
* `test-neo-cli.expect`: [expect](https://linux.die.net/man/1/expect) script which verifies neo-cli functionality
28 changes: 28 additions & 0 deletions ci/build-and-test.sh
@@ -0,0 +1,28 @@
#!/bin/bash
#
# This script builds neo-cli with dotnet 2.0, and runs the tests.
#
CONTAINER_NAME="neo-cli-ci"

# Get absolute path of code and ci folder. This allows to run this script from
# anywhere, whether from inside this directory or outside.
DIR_CI="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
DIR_BASE="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && cd .. && pwd )"
# echo "CI directory: $DIR_CI"
# echo "Base directory: $DIR_BASE"

# Build the Docker image (includes building the current neo-cli code)
# docker build --no-cache -f $DIR_CI/Dockerfile -t $CONTAINER_NAME $DIR_BASE
docker build -f $DIR_CI/Dockerfile -t $CONTAINER_NAME $DIR_BASE

# Stop already running containers
CONTAINER=$(docker ps -aqf name=$CONTAINER_NAME)
if [ -n "$CONTAINER" ]; then
echo "Stopping container named $CONTAINER_NAME"
docker stop $CONTAINER_NAME 1>/dev/null
echo "Removing container named $CONTAINER_NAME"
docker rm -f $CONTAINER_NAME 1>/dev/null
fi

# Start a new test container
docker run --name $CONTAINER_NAME $CONTAINER_NAME /opt/ci/run-tests-in-docker.sh
43 changes: 43 additions & 0 deletions ci/run-tests-in-docker.sh
@@ -0,0 +1,43 @@
#!/bin/bash
#
# This script is run inside the Docker container and tests neo-cli
#
set -e

cd /opt/neo-cli

# Run tests with expect
expect /opt/ci/test-neo-cli.expect

# Start neo-cli in background for additional JSON-RPC tests
screen -dmS node1 bash -c "dotnet neo-cli.dll --rpc"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should make sure this screen is closed after tests have run

Copy link
Contributor Author

@metachris metachris Dec 28, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The Docker container is killed after the tests, so it wouldn't matter. Edit: For reusability and flexibility it could still be good to kill it though.

Edit2: I'll think about this a bit more. This would make things more complex because the grep commands for the JSON-API response will exit the script with an error exit code at that point. So we would need to wrap the JSON-RPC tests in another script, check the exit codes, kill the screen session, and then exit with the exit code of the JSON-RPC tests. Not sure about the benefit and if this is worth the added complexity.


# Wait a little bit
sleep 3

# Test a RPX smart contract query
JSONRPC_RES=$( curl --silent \
--request POST \
--url localhost:10332/ \
--header 'accept: application/json' \
--header 'content-type: application/json' \
--data '{
"jsonrpc": "2.0",
"method": "invokefunction",
"params": [
"ecc6b20d3ccac1ee9ef109af5a7cdb85706b1df9",
"totalSupply"
],
"id": 3
}' )

echo "JSON-RPC response: $JSONRPC_RES"

# Make sure we get a valid response
echo ${JSONRPC_RES} | grep --quiet "00c10b746f74616c537570706c7967f91d6b7085db7c5aaf09f19eeec1ca3c0db2c6ec"

# Make sure the response doesn't include "error"
if echo ${JSONRPC_RES} | grep --quiet "\"error\""; then
echo "Error: \"error\" found in json-rpc response"
exit 1
fi
68 changes: 68 additions & 0 deletions ci/test-neo-cli.expect
@@ -0,0 +1,68 @@
#!/usr/bin/expect -f
#
# This script uses expect to test neo-cli
#
set timeout 2

# Start neo-cli
spawn dotnet neo-cli.dll --rpc

# Expect the main input prompt
expect {
"neo> " { }
"error" { exit 2 }
timeout { exit 1 }
}

#
# Test 'create wallet'
#
send "create wallet test-wallet.json\n"
expect {
"password:" { send "asd\n" }
"error" { exit 2 }
timeout { exit 1 }
}

expect {
"password:" { send "asd\n" }
"error" { exit 2 }
timeout { exit 1 }
}

# Wallet creation requires a higher timeout
set timeout 10

expect {
"address:" { }
"error" { exit 2 }
timeout { exit 1 }
}

# Set timeout back to default
set timeout 2

#
# Test 'list address'
#
send "list address\n"

expect {
-re "A.*" { }
"error" { exit 2 }
timeout { exit 1 }
}

#
# Test 'create address'
#
send "create address\n"

expect {
"export addresses" { }
"neo> " { }
"error" { exit 2 }
timeout { exit 1 }
}

exit 0