diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 06ed596f..f51a1381 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -18,3 +18,26 @@ jobs: - name: Test run: npm test + + e2e-tests: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v3 + + - name: Use Node 18.x + uses: actions/setup-node@v3 + with: + node-version: 18 + + - name: Install dependencies + run: npm ci + + - name: Setup starship + run: npm run e2e:setup + + - name: Start starship + run: make start + + - name: Run e2e tests + run: npm run e2e:test diff --git a/Makefile b/Makefile new file mode 100644 index 00000000..4cca893b --- /dev/null +++ b/Makefile @@ -0,0 +1,82 @@ +HELM_NAME = skip-router +HELM_FILE = starship.yaml +HELM_REPO = starship +HELM_CHART = devnet +HELM_VERSION = 0.1.38 + +############################################################################### +### All commands ### +############################################################################### + +.PHONY: setup +setup: check setup-helm + +.PHONY: start +start: install port-forward + +.PHONY: test +test: + npm run e2e:test + +.PHONY: stop +stop: stop-forward delete + +.PHONY: clean +clean: stop clean-kind + +############################################################################### +### Helm commands ### +############################################################################### + +.PHONY: setup-helm +setup-helm: + helm repo add $(HELM_REPO) https://cosmology-tech.github.io/starship/ + helm repo update + helm search repo $(HELM_REPO)/$(HELM_CHART) --version $(HELM_VERSION) + +.PHONY: install +install: + @echo "Installing the helm chart. This is going to take a while....." + @echo "You can check the status with \"kubectl get pods\", run in another terminal please" + helm install -f $(HELM_FILE) $(HELM_NAME) $(HELM_REPO)/$(HELM_CHART) --version $(HELM_VERSION) --wait --timeout 20m + +.PHONY: upgrade +upgrade: + helm upgrade --debug -f $(HELM_FILE) $(HELM_NAME) $(HELM_REPO)/$(HELM_CHART) --version $(HELM_VERSION) + +.PHONY: debug +debug: + helm install --dry-run --debug -f $(HELM_FILE) $(HELM_NAME) $(HELM_REPO)/$(HELM_CHART) + +.PHONY: delete +delete: + -helm delete $(HELM_NAME) + +############################################################################### +### Port forward ### +############################################################################### + +.PHONY: port-forward +port-forward: + bash $(CURDIR)/scripts/port-forward.sh --config=$(HELM_FILE) + +.PHONY: stop-forward +stop-forward: + -pkill -f "port-forward" + +############################################################################### +### Local Kind Setup ### +############################################################################### +KIND_CLUSTER=starship + +.PHONY: check +check: + bash $(CURDIR)/scripts/dev-setup.sh + +.PHONY: setup-kind +setup-kind: + kind create cluster --name $(KIND_CLUSTER) + +.PHONY: clean-kind +clean-kind: + kind delete cluster --name $(KIND_CLUSTER) \ No newline at end of file diff --git a/README.md b/README.md index ab31ecbc..44f98019 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ WIP SDK for the Skip API. Not ready for use. -## Running Tests +## Running Unit Tests To run tests simply run: @@ -22,23 +22,30 @@ Get Coverage: npm run test -- --coverage ``` -## Endpoints +## Running e2e Tests -**Info:** +e2e tests depend on [Starship](https://starship.cosmology.tech/) to test interactions with various blockchains. -- [x] `/info/chains` +Setup and install Starship dependencies: -**Fungible:** +```bash +npm run e2e:setup +``` + +Start the Starship devnets: -- [x] `/fungible/venues` -- [x] `/fungible/assets` -- [x] `/fungible/assets_from_source` -- [x] `/fungible/route` -- [x] `/fungible/msgs` -- [x] `/fungible/recommend_assets` +```bash +npm run e2e:start +``` -**Transaction:** +Run the e2e tests: -- [x] `/tx/submit` -- [x] `/tx/track` -- [x] `/tx/status` +```bash +npm run e2e:test # or npm run e2e:test -- --watch +``` + +Stop the Starship devnets: + +```bash +npm run e2e:stop +``` diff --git a/package.json b/package.json index 7ad9807d..90f3c5d2 100644 --- a/package.json +++ b/package.json @@ -5,8 +5,13 @@ "main": "index.js", "scripts": { "build": "tsc -p tsconfig.json --outDir dist --module commonjs || true", - "test": "jest", - "prepare": "husky install" + "test": "jest --testPathPattern=src/", + "prepare": "husky install", + "e2e:start": "make start", + "e2e:setup": "make setup && make setup-kind", + "e2e:stop": "make stop", + "e2e:clean": "make stop clean", + "e2e:test": "jest --testPathPattern=tests/ --runInBand --verbose --bail" }, "author": "", "license": "ISC", diff --git a/scripts/dev-setup.sh b/scripts/dev-setup.sh new file mode 100755 index 00000000..8b94b7ca --- /dev/null +++ b/scripts/dev-setup.sh @@ -0,0 +1,68 @@ +#!/bin/bash + +set -euo pipefail + +function color() { + local color=$1 + shift + local black=30 red=31 green=32 yellow=33 blue=34 magenta=35 cyan=36 white=37 + local color_code=${!color:-$green} + printf "\033[%sm%s\033[0m\n" "$color_code" "$*" +} + +# Define a function to install a binary on macOS +install_macos() { + case $1 in + docker) color red "Please install docker. Follow: https://docs.docker.com/desktop/install/mac-install/" ;; + kubectl) brew install kubectl ;; + helm) brew install helm ;; + yq) brew install yq ;; + kind) brew install kind ;; + esac +} + +# Define a function to install a binary on Linux +install_linux() { + color green "Installing $1 at ~/.local/bin, please add it to PATH" + mkdir -p ~/.local/bin + case $1 in + docker) color red "Please install docker. Follow: https://docs.docker.com/engine/install/ubuntu/" ;; + kubectl) curl -Lks "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl" > ~/.local/bin/kubectl && chmod +x ~/.local/bin/kubectl ;; + helm) curl https://raw.githubusercontent.com/helm/helm/master/scripts/get-helm-3 | bash ;; + yq) curl -Lks "https://github.com/mikefarah/yq/releases/download/v4.33.3/yq_linux_amd64" > ~/.local/bin/yq && chmod +x ~/.local/bin/yq ;; + kind) curl -Lks https://kind.sigs.k8s.io/dl/v0.18.0/kind-linux-amd64 > ~/.local/bin/kind && chmod +x ~/.local/bin/kind ;; + esac +} + +# Define a function to install a binary +install_binary() { + if [[ $(uname -s) == "Darwin" ]]; then + install_macos $1 + else + install_linux $1 + fi +} + +# Define a function to check for the presence of a binary +check_binary() { + if ! command -v $1 &> /dev/null + then + echo "$1 is not installed" + install_binary $1 + if ! command -v $1 &> /dev/null + then + color red "Installation of $1 failed, exiting..." + color red "Please install $1 manually, then run me again to verify the installation" + exit 1 + fi + fi +} + +# Check the binaries +check_binary kubectl +check_binary helm +check_binary yq +check_binary kind +check_binary docker + +color green "All binaries are installed" \ No newline at end of file diff --git a/scripts/port-forward.sh b/scripts/port-forward.sh new file mode 100755 index 00000000..9da980a3 --- /dev/null +++ b/scripts/port-forward.sh @@ -0,0 +1,84 @@ +#!/bin/bash + +set -euo pipefail + +function color() { + local color=$1 + shift + local black=30 red=31 green=32 yellow=33 blue=34 magenta=35 cyan=36 white=37 + local color_code=${!color:-$green} + printf "\033[%sm%s\033[0m\n" "$color_code" "$*" +} + +function stop_port_forward() { + color green "Trying to stop all port-forward, if any...." + PIDS=$(ps -ef | grep -i -e 'kubectl port-forward' | grep -v 'grep' | cat | awk '{print $2}') || true + for p in $PIDS; do + kill -15 $p + done + sleep 2 +} + +# Default values +CHAIN_RPC_PORT=26657 +CHAIN_LCD_PORT=1317 +CHAIN_EXPOSER_PORT=8081 +CHAIN_FAUCET_PORT=8000 +EXPLORER_LCD_PORT=8080 +REGISTRY_LCD_PORT=8080 +REGISTRY_GRPC_PORT=9090 + +for i in "$@"; do + case $i in + -c=*|--config=*) + CONFIGFILE="${i#*=}" + shift # past argument=value + ;; + -*|--*) + echo "Unknown option $i" + exit 1 + ;; + *) + ;; + esac +done + +stop_port_forward + +echo "Port forwarding for config ${CONFIGFILE}" +echo "Port forwarding all chains" +num_chains=$(yq -r ".chains | length - 1" ${CONFIGFILE}) +if [[ $num_chains -lt 0 ]]; then + echo "No chains to port-forward: num: $num_chains" + exit 1 +fi +for i in $(seq 0 $num_chains); do + chain=$(yq -r ".chains[$i].name" ${CONFIGFILE} ) + localrpc=$(yq -r ".chains[$i].ports.rpc" ${CONFIGFILE} ) + locallcd=$(yq -r ".chains[$i].ports.rest" ${CONFIGFILE} ) + localexp=$(yq -r ".chains[$i].ports.exposer" ${CONFIGFILE}) + localfaucet=$(yq -r ".chains[$i].ports.faucet" ${CONFIGFILE}) + [[ "$localrpc" != "null" ]] && kubectl port-forward pods/$chain-genesis-0 $localrpc:$CHAIN_RPC_PORT > /dev/null 2>&1 & + [[ "$locallcd" != "null" ]] && kubectl port-forward pods/$chain-genesis-0 $locallcd:$CHAIN_LCD_PORT > /dev/null 2>&1 & + [[ "$localexp" != "null" ]] && kubectl port-forward pods/$chain-genesis-0 $localexp:$CHAIN_EXPOSER_PORT > /dev/null 2>&1 & + [[ "$localfaucet" != "null" ]] && kubectl port-forward pods/$chain-genesis-0 $localfaucet:$CHAIN_FAUCET_PORT > /dev/null 2>&1 & + sleep 1 + color yellow "chains: forwarded $chain lcd to http://localhost:$locallcd, rpc to http://localhost:$localrpc, faucet to http://localhost:$localfaucet" +done + +echo "Port forward services" + +if [[ $(yq -r ".registry.enabled" $CONFIGFILE) == "true" ]]; +then + kubectl port-forward service/registry 8081:$REGISTRY_LCD_PORT > /dev/null 2>&1 & + kubectl port-forward service/registry 9091:$REGISTRY_GRPC_PORT > /dev/null 2>&1 & + sleep 1 + color yellow "registry: forwarded registry lcd to grpc http://localhost:8081, to http://localhost:9091" +fi + +if [[ $(yq -r ".explorer.enabled" $CONFIGFILE) == "true" ]]; +then + kubectl port-forward service/explorer 8080:$EXPLORER_LCD_PORT > /dev/null 2>&1 & + sleep 1 + color green "Open the explorer to get started.... http://localhost:8080" +fi \ No newline at end of file diff --git a/starship.yaml b/starship.yaml new file mode 100644 index 00000000..07bdce40 --- /dev/null +++ b/starship.yaml @@ -0,0 +1,53 @@ +chains: + - name: osmosis-1 + type: osmosis + numValidators: 1 + ports: + rest: 1313 + rpc: 26653 + resources: + cpu: "0.2" + memory: "200M" + + - name: gaia-1 + type: cosmos + numValidators: 1 + ports: + rest: 1317 + rpc: 26657 + resources: + cpu: "0.2" + memory: "200M" + +relayers: + - name: osmos-gaia + type: hermes + replicas: 1 + chains: + - osmosis-1 + - gaia-1 + resources: + cpu: "0.1" + memory: "100M" + +explorer: + enabled: false + +registry: + enabled: true + ports: + rest: 8081 + grpc: 9091 + resources: + cpu: "0.1" + memory: "100M" + +exposer: + resources: + cpu: "0.1" + memory: "100M" + +faucet: + resources: + cpu: "0.1" + memory: "100M" diff --git a/tests/basic.test.ts b/tests/basic.test.ts new file mode 100644 index 00000000..c61308cd --- /dev/null +++ b/tests/basic.test.ts @@ -0,0 +1,18 @@ +import axios from "axios"; + +import { COSMOSHUB_ENDPOINT, OSMOSIS_ENDPOINT } from "./utils"; + +// THESE ARE PLACEHOLDER TESTS +describe("basic e2e tests", () => { + it("can connect to cosmoshub devnet", async () => { + const response = await axios.get(`${COSMOSHUB_ENDPOINT}/status`); + + expect(response.data.result.node_info.network).toEqual("gaia-1"); + }); + + it("can connect to osmosis devnet", async () => { + const response = await axios.get(`${OSMOSIS_ENDPOINT}/status`); + + expect(response.data.result.node_info.network).toEqual("osmosis-1"); + }); +}); diff --git a/tests/utils.ts b/tests/utils.ts new file mode 100644 index 00000000..afba7578 --- /dev/null +++ b/tests/utils.ts @@ -0,0 +1,2 @@ +export const COSMOSHUB_ENDPOINT = "http://localhost:26657"; +export const OSMOSIS_ENDPOINT = "http://localhost:26653";