func NewCTLogEnv(ctx context.Context, cfgs []*configpb.LogConfig, numSequencers int, testID string) (*CTLogEnv, error) {
	logEnv, err := integration.NewLogEnv(ctx, numSequencers, testID)
	if err != nil {
		return nil, fmt.Errorf("failed to create LogEnv: %v", err)
	}
	for _, cfg := range cfgs {
		tree, err := client.CreateAndInitTree(ctx,
			&trillian.CreateTreeRequest{Tree: stestonly.LogTree},
			logEnv.Admin, logEnv.Log)
		if err != nil {
			return nil, fmt.Errorf("failed to provision log %d: %v", cfg.LogId, err)
		}
		cfg.LogId = tree.TreeId
	}
	addr, listener, err := listen()
	if err != nil {
		return nil, fmt.Errorf("failed to find an unused port for CT personality: %v", err)
	}
	server := http.Server{Addr: addr, Handler: nil}
	var wg sync.WaitGroup
	wg.Add(1)
	go func(env *integration.LogEnv, server *http.Server, listener net.Listener, cfgs []*configpb.LogConfig) {
		defer wg.Done()
		cl := trillian.NewTrillianLogClient(env.ClientConn)
		for _, cfg := range cfgs {
			vCfg, err := ctfe.ValidateLogConfig(cfg)
			if err != nil {
				glog.Fatalf("ValidateLogConfig failed: %+v: %v", cfg, err)
			}
			opts := ctfe.InstanceOptions{
				Validated:     vCfg,
				Client:        cl,
				Deadline:      10 * time.Second,
				MetricFactory: prometheus.MetricFactory{},
				RequestLog:    new(ctfe.DefaultRequestLog),
			}
			inst, err := ctfe.SetUpInstance(ctx, opts)
			if err != nil {
				glog.Fatalf("Failed to set up log instance for %+v: %v", cfg, err)
			}
			for path, handler := range inst.Handlers {
				http.Handle(path, handler)
			}
		}
		http.Handle("/metrics", promhttp.Handler())
		server.Serve(listener)
	}(logEnv, &server, listener, cfgs)
	return &CTLogEnv{
		logEnv:       logEnv,
		wg:           &wg,
		ctListener:   listener,
		ctHTTPServer: &server,
		CTAddr:       addr,
	}, nil
}
NewCTLogEnv creates a fresh DB, log server, and CT personality.
testID should be unique to each unittest package so as to allow parallel tests.
Created logIDs will be set to cfgs.
package integration
import (
	"context"
	"fmt"
	"net"
	"net/http"
	"sync"
	"time"
	"github.com/golang/glog"
	"github.com/google/certificate-transparency-go/trillian/ctfe"
	"github.com/google/certificate-transparency-go/trillian/ctfe/configpb"
	"github.com/google/trillian"
	"github.com/google/trillian/client"
	"github.com/google/trillian/monitoring/prometheus"
	"github.com/google/trillian/testonly/integration"
	"github.com/prometheus/client_golang/prometheus/promhttp"
	stestonly "github.com/google/trillian/storage/testonly"
)
type CTLogEnv struct {
	logEnv       *integration.LogEnv
	wg           *sync.WaitGroup
	ctListener   net.Listener
	ctHTTPServer *http.Server
	CTAddr       string
}