Skip to content

Consul

package consul

import (
    "context"
    "fmt"

    "github.com/testcontainers/testcontainers-go"
    "github.com/testcontainers/testcontainers-go/wait"
)

// consulContainer represents the consul container type used in the module
type consulContainer struct {
    testcontainers.Container
    endpoint string
}

// setupConsul creates an instance of the consul container type
func setupConsul(ctx context.Context) (*consulContainer, error) {
    req := testcontainers.ContainerRequest{
        Image:        "consul:latest",
        ExposedPorts: []string{"8500/tcp", "8600/udp"},
        Name:         "badger",
        Cmd:          []string{"agent", "-server", "-ui", "-node=server-1", "-bootstrap-expect=1", "-client=0.0.0.0"},
        WaitingFor:   wait.ForListeningPort("8500/tcp"),
    }
    container, err := testcontainers.GenericContainer(ctx, testcontainers.GenericContainerRequest{
        ContainerRequest: req,
        Started:          true,
    })
    if err != nil {
        return nil, err
    }
    mappedPort, err := container.MappedPort(ctx, "8500")
    if err != nil {
        return nil, err
    }

    host, err := container.Host(ctx)
    if err != nil {
        return nil, err
    }

    return &consulContainer{Container: container, endpoint: fmt.Sprintf("%s:%s", host, mappedPort.Port())}, nil
}
package consul

import (
    "bytes"
    "context"
    "testing"

    "github.com/hashicorp/consul/api"
)

func TestConsul(t *testing.T) {
    ctx := context.Background()

    container, err := setupConsul(ctx)
    if err != nil {
        t.Fatal(err)
    }

    // Clean up the container after the test is complete
    t.Cleanup(func() {
        if err := container.Terminate(ctx); err != nil {
            t.Fatalf("failed to terminate container: %s", err)
        }
    })

    // perform assertions
    cfg := api.DefaultConfig()
    cfg.Address = container.endpoint
    client, err := api.NewClient(cfg)
    if nil != err {
        t.Fatal(err)
    }
    bs := []byte("apple")
    _, err = client.KV().Put(&api.KVPair{
        Key:   "fruit",
        Value: bs,
    }, nil)
    if nil != err {
        t.Fatal(err)
    }
    pair, _, err := client.KV().Get("fruit", nil)
    if err != nil {
        t.Fatal(err)
    }
    if pair.Key != "fruit" || !bytes.Equal(pair.Value, []byte("apple")) {
        t.Errorf("get KV: %v %s,expect them to be: 'fruit' and 'apple'\n", pair.Key, pair.Value)
    }
}