diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 000000000..2f93a0507 --- /dev/null +++ b/.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 diff --git a/ci/Dockerfile b/ci/Dockerfile new file mode 100644 index 000000000..30d9d9d19 --- /dev/null +++ b/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 diff --git a/ci/README.md b/ci/README.md new file mode 100644 index 000000000..d0ab97f37 --- /dev/null +++ b/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 diff --git a/ci/build-and-test.sh b/ci/build-and-test.sh new file mode 100755 index 000000000..ddfc3f453 --- /dev/null +++ b/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 diff --git a/ci/run-tests-in-docker.sh b/ci/run-tests-in-docker.sh new file mode 100755 index 000000000..5db61969e --- /dev/null +++ b/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" + +# 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 diff --git a/ci/test-neo-cli.expect b/ci/test-neo-cli.expect new file mode 100755 index 000000000..4580cd661 --- /dev/null +++ b/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