func TestSubscribeWhenAlreadyActive(t *testing.T) {
	maybeSkipIntegrationTest(t)
	s, err := NewSession()
	if err != nil {
		t.Fatalf("Failed to create session: %v", err)
	}
	defer s.Close()
	if err := s.Subscribe("control-log"); err != nil {
		t.Fatalf("Failed to start event listener: %v", err)
	}
	if err := s.Subscribe("log"); err != nil {
		t.Fatalf("Failed to subscribe to additional events: %v", err)
	}
}
TestSubscribeWhenAlreadyActive tests that subscriptions can
be made incrementally. Namely, a caller can subcribe to one set
of events, and later add to the subcribed events.
package vici
import (
	"context"
	"flag"
	"log"
	"net"
	"os/exec"
	"reflect"
	"testing"
	"time"
)
func mockCharon(ctx context.Context) net.Conn {
	client, srvr := net.Pipe()
	go func() {
		defer func() {
			srvr.Close()
		}()
		tr := &transport{conn: srvr}
		for {
			select {
			case <-ctx.Done():
				return
			default:
				break
			}
			p, err := tr.recv()
			if err != nil {
				return
			}
			switch p.ptype {
			case pktEventRegister, pktEventUnregister:
				var ack *packet
				if p.name != "test-event" {
					ack = newPacket(pktEventUnknown, "", nil)
				} else {
					ack = newPacket(pktEventConfirm, "", nil)
				}
				err := tr.send(ack)
				if err != nil {
					return
				}
				if p.ptype == pktEventRegister && ack.ptype == pktEventConfirm {
					msg := NewMessage()
					err := msg.Set("test", "hello world!")
					if err != nil {
						log.Printf("Failed to set message field: %v", err)
					}
					event := newPacket(pktEvent, "test-event", msg)
					err = tr.send(event)
					if err != nil {
						log.Printf("Failed to send test-event message: %v", err)
					}
				}
			default:
				continue
			}
		}
	}()
	return client
}
func TestSubscribeAndCloseSession(t *testing.T) {
	dctx, dcancel := context.WithCancel(context.Background())
	defer dcancel()
	conn := mockCharon(dctx)
	s, err := NewSession(withTestConn(conn))
	if err != nil {
		t.Fatalf("Failed to create session: %v", err)
	}
	defer s.Close()
	err = s.Subscribe("test-event")
	if err != nil {
		t.Fatalf("Failed to start event listener: %v", err)
	}
	e, err := s.NextEvent(context.TODO())
	if err != nil {
		t.Fatalf("Unexpected error on NextEvent: %v", err)
	}
	if e.Message.Get("test") != "hello world!" {
		t.Fatalf("Unexpected message: %v", e)
	}
	s.Close()
	e, err = s.NextEvent(context.TODO())
	if err == nil {
		t.Fatalf("Expected error after closing listener, got message: %v", e)
	}
}
func TestSessionClose(t *testing.T) {
	conn, _ := net.Pipe()
	s, err := NewSession(withTestConn(conn))
	if err != nil {
		t.Fatalf("Failed to create session: %v", err)
	}
	if err := s.Close(); err != nil {
		t.Fatalf("Unpexected error when closing Session: %v", err)
	}
}
func TestIdempotentSessionClose(t *testing.T) {
	conn, _ := net.Pipe()
	s, err := NewSession(withTestConn(conn))
	if err != nil {
		t.Fatalf("Failed to create session: %v", err)
	}
	if err := s.Close(); err != nil {
		t.Fatalf("Unpexected error when closing Session (first close): %v", err)
	}
	if err := s.Close(); err != nil {
		t.Fatalf("Unpexected error when closing Session (second close): %v", err)
	}
}
var (
	doIntegrationTests = flag.Bool("integration", false, "Run integration tests that require charon")
)
func maybeSkipIntegrationTest(t *testing.T) {
	if !*doIntegrationTests {
		t.Skip("Skipping integration test.")
	}
}
func TestCommandRequest(t *testing.T) {
	maybeSkipIntegrationTest(t)
	s, err := NewSession()
	if err != nil {
		t.Fatalf("Failed to create a session: %v", err)
	}
	defer s.Close()
	resp, err := s.CommandRequest("version", nil)
	if err != nil {
		t.Fatalf("Failed to get charon version information: %v", err)
	}
	if d := resp.Get("daemon"); d == "" {
		t.Fatal("Expected non-empty value at key 'daemon'")
	}
}
func TestStreamedCommandRequest(t *testing.T) {
	maybeSkipIntegrationTest(t)
	s, err := NewSession()
	if err != nil {
		t.Fatalf("Failed to create a session: %v", err)
	}
	defer s.Close()
	ms, err := s.StreamedCommandRequest("list-authorities", "list-authority", nil)
	if err != nil {
		t.Fatalf("Failed to list authorities: %v", err)
	}
	for i, m := range ms.Messages() {
		if m.Err() != nil {
			t.Fatalf("Got error in message #%d: %v", i+1, m.Err())
		}
	}
}