consul/testutil
R.B. Boyer 82c17d94e1 testutil: Set the environment variable NOLOGBUFFER=1 to have test agent logs go straight to stdout
This is a followup to the testing feature added in #5304.

While it is very nice to have test agent logs to through testing.T.Logf
so that only logs from failed tests are emitted, if a test is hanging or
taking a long time those logs are delayed. In that case setting
NOLOGBUFFER=1 will temporarily redirect them to stdout so you can see
immediate feedback about hangs when running the tests in verbose mode.

One current example of a test where this can be relevant is:

    $ go test ./agent/consul -run 'TestCatalog_ListServices_Stale' -v
2019-02-13 13:13:10 -06:00
..
retry New ACLs (#4791) 2018-10-19 12:04:07 -04:00
README.md Add `AddAccessibleService` to testutil 2017-05-01 13:56:48 -07:00
io.go testutil: If testing.T is nil panic with error (#4725) 2018-10-26 12:13:40 -07:00
server.go A few misc fixes found by go vet 2018-10-19 12:28:36 -04:00
server_methods.go agent: consolidate handling of 405 Method Not Allowed (#3405) 2017-09-25 23:11:19 -07:00
server_wrapper.go Add `AddAccessibleService` to testutil 2017-05-01 13:56:48 -07:00
testlog.go testutil: Set the environment variable NOLOGBUFFER=1 to have test agent logs go straight to stdout 2019-02-13 13:13:10 -06:00

README.md

Consul Testing Utilities

This package provides some generic helpers to facilitate testing in Consul.

TestServer

TestServer is a harness for managing Consul agents and initializing them with test data. Using it, you can form test clusters, create services, add health checks, manipulate the K/V store, etc. This test harness is completely decoupled from Consul's core and API client, meaning it can be easily imported and used in external unit tests for various applications. It works by invoking the Consul CLI, which means it is a requirement to have Consul installed in the $PATH.

Following is an example usage:

package my_program

import (
	"testing"

	"github.com/hashicorp/consul/consul/structs"
	"github.com/hashicorp/consul/testutil"
)

func TestFoo_bar(t *testing.T) {
	// Create a test Consul server
	srv1, err := testutil.NewTestServer()
	if err != nil {
		t.Fatal(err)
	}
	defer srv1.Stop()

	// Create a secondary server, passing in configuration
	// to avoid bootstrapping as we are forming a cluster.
	srv2, err := testutil.NewTestServerConfig(t, func(c *testutil.TestServerConfig) {
		c.Bootstrap = false
	})
	if err != nil {
		t.Fatal(err)
	}
	defer srv2.Stop()

	// Join the servers together
	srv1.JoinLAN(t, srv2.LANAddr)

	// Create a test key/value pair
	srv1.SetKV(t, "foo", []byte("bar"))

	// Create lots of test key/value pairs
	srv1.PopulateKV(t, map[string][]byte{
		"bar": []byte("123"),
		"baz": []byte("456"),
	})

	// Create a service
	srv1.AddService(t, "redis", structs.HealthPassing, []string{"master"})

	// Create a service that will be accessed in target source code
	srv1.AddAccessibleService("redis", structs.HealthPassing, "127.0.0.1", 6379, []string{"master"})

	// Create a service check
	srv1.AddCheck(t, "service:redis", "redis", structs.HealthPassing)

	// Create a node check
	srv1.AddCheck(t, "mem", "", structs.HealthCritical)

	// The HTTPAddr field contains the address of the Consul
	// API on the new test server instance.
	println(srv1.HTTPAddr)

	// All functions also have a wrapper method to limit the passing of "t"
	wrap := srv1.Wrap(t)
	wrap.SetKV("foo", []byte("bar"))
}