Coder Social home page Coder Social logo

nktest's Introduction

About

Package nktest provides a Nakama test runner that makes it easy to build and test Nakama module plugins with complex or advanced game logic using nothing but go test.

See also github.com/ascii8/nakama-go package for a web/realtime Nakama Go client.

Tests Go Report Card [![Reference](https://pkg.go.dev/badge/github.com/ascii8/nktest Releases

Overview

This package uses Podman to create "rootless" containers (specifically, docker.io/heroiclabs/nakama-pluginbuilder and docker.io/heroiclabs/nakama) to build Nakama's Go plugins and launch the necessary server components (PostgreSQL and Nakama).

Provides a stable, repeatable, and quick mechanism for launching testable end-to-end Nakama servers for game modules (Go, Lua, or Javascript).

Provides additional transport and logger types for use with Go clients to readily aid in debugging Nakama's API calls.

Quickstart

Add to package/module:

go get github.com/ascii8/nktest

From Go's TestMain, use nktest.Main to build Go modules, and to setup/teardown PostgreSQL and Nakama server containers:

import "github.com/ascii8/nktest"

// TestMain handles setting up and tearing down the postgres and nakama
// containers.
func TestMain(m *testing.M) {
	ctx := context.Background()
	ctx = nktest.WithAlwaysPullFromEnv(ctx, "PULL")
	ctx = nktest.WithHostPortMap(ctx)
	nktest.Main(ctx, m,
		nktest.WithDir("./testdata"),
		nktest.WithBuildConfig("./nksample", nktest.WithDefaultGoEnv(), nktest.WithDefaultGoVolumes()),
	)
}

Then, from within a Test* func, create a cancelable test context, and a proxy:

import "github.com/ascii8/nktest"

func TestNakamaHealthcheck(t *testing.T) {
	ctx, cancel, nk := nktest.WithCancel(context.Background(), t)
	defer cancel()
	urlstr, err := nktest.RunProxy(ctx)
	if err != nil {
		t.Fatalf("expected no error, got: %v", err)
	}
	t.Logf("proxy: %s", urlstr)
	req, err := http.NewRequestWithContext(ctx, "GET", urlstr+"/healthcheck", nil)
	if err != nil {
		t.Fatalf("expected no error, got: %v", err)
	}
	// create a client with compression disabled (makes debugging the API
	// requests/responses easier)
	cl := &http.Client{
		Transport: &http.Transport{
			DisableCompression: true,
		},
	}
	// execute the request
	res, err := cl.Do(req)
	if err != nil {
		t.Fatalf("expected no error, got: %v", err)
	}
	defer res.Body.Close()
	// check response
	if res.StatusCode != http.StatusOK {
		t.Errorf("expected %d, got: %d", http.StatusOK, res.StatusCode)
	}
	t.Logf("healthcheck status: %d", res.StatusCode)
	// display connection information
	t.Logf("grpc: %s", nk.GrpcLocal())
	t.Logf("http: %s", nk.HttpLocal())
	t.Logf("console: %s", nk.ConsoleLocal())
	t.Logf("http_key: %s", nk.HttpKey())
	t.Logf("server_key: %s", nk.ServerKey())
}

Use the WithHostPortMap() option, to publish the Postgres and Nakama server's default ports on the host, and making it easy to write Example* tests.

For more advanced testing scenarios, see the github.com/ascii8/nakama-go package for a full featured Go Nakama client.

Examples

See the Go package documentation for package level examples.

Why

While Nakama provides a number of different languages with which to build out game modules, building large-scale, complex logic for Nakama is best done using Go. For experienced (and even inexperienced!) Go developers, the go test command is simple, efficient and well understood, and works across platforms.

And, for fully automated deployments of Nakama and game modules, a large amount of quick and reliable testing is needed to ensure rapid application development, and continuous integration/deployment (CI/CD).

As such, there was clear motivation to make it easy and repeatable to test entirely from go test,

Why Podman

The first version of nktest used Docker, but builds and tests were slow as it was not possible to mount the user's Go build/mod cache directories without stomping on the local UID/GID and subsequently affecting the read/write permissions. Thus the change to Podman, which is able to run containers without root permissions, and can keep user UID/GID's on files.

Notes

macOS:

# update homebrew formulas and upgrade packages
brew update && brew upgrade

# install podman
brew install podman

# install gpgme (needed for podman's Go binding dependenices)
brew install gpgme

# if unable to do `go test -v` out of the box, re-init the podman machine
podman machine stop podman-machine-default
podman machine rm podman-machine-default
podman machine init -v $HOME:$HOME
podman machine start

# if receiving a "too many open files" error on M1 macs, try:
podman machine stop && ulimit -n unlimited && podman machine start

nktest's People

Contributors

ascii8 avatar

Watchers

 avatar

nktest's Issues

Podman on mac not connecting.

This is a cool approach - thanks for putting this up.

i did the setup on Mac...

sw_vers
ProductName:	macOS
ProductVersion:	11.7.4
BuildVersion:	20G1120

brew install podman
brew install gpgme

podman --version
podman version 4.4.4

podman machine init -v $HOME:$HOME
podman machine start

apple@x-MacBook-Pro-2 nktest % podman machine list
NAME                     VM TYPE     CREATED         LAST UP            CPUS        MEMORY      DISK SIZE
podman-machine-default*  qemu        15 minutes ago  Currently running  1           2.147GB     107.4GB
apple@x-MacBook-Pro-2 nktest % podman machine start
Error: cannot start VM podman-machine-default: VM already running or starting

But cant connect. I am new to Podman :)

nktest % ls
LICENSE  README.md  config.yml.tpl  ctx.go  docker.go  example_test.go	go.mod	go.sum	log.go	nksample  nktest.go  nktest_test.go  podman.go	proxy.go  runner.go
apple@x-MacBook-Pro-2 nktest % DEBUG=1 go test -v
go: downloading golang.org/x/term v0.2.0
go: downloading github.com/moby/term v0.0.0-20210619224110-3f7ff695adc6
go: downloading golang.org/x/crypto v0.0.0-20220919173607-35f4265a4bc0
go: downloading golang.org/x/net v0.2.0
go: downloading google.golang.org/grpc v1.49.0
go: downloading google.golang.org/genproto v0.0.0-20220720214146-176da50484ac
error: unable to create podman client: unable to open podman connection: unable to connect to Podman socket: Get "http://d/v4.3.1/libpod/_ping": dial unix /var/run/podman/podman.sock: connect: no such file or directory
exit status 1
FAIL	github.com/ascii8/nktest	0.891s
apple@x-MacBook-Pro-2 nktest % 

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.