func TestCreation(t *testing.T) {
	listenFrom := config.ListenFrom{}
	listenFrom.ListenAddr = workarounds.GolangDoesnotAllowPointerToStringLiteral("127.0.0.1:0")
	forwardTo := dptest.NewBasicSink()
	ctx := context.Background()
	l, err := ListenerLoader(ctx, forwardTo, &listenFrom)
	defer l.Close()
	assert.Equal(t, nil, err, "Expect no error")
	assert.Equal(t, numStats, len(l.Stats()), "Expect no stats")
	forwarder, err := NewForwarder("127.0.0.1", nettest.TCPPort(l.psocket), time.Second, []string{"zzfirst"}, 10)
	defer forwarder.Close()
	assert.Equal(t, nil, err, "Expect no error")
	assert.Equal(t, 1, len(forwarder.pool.conns))
	timeToSend := time.Now().Round(time.Second)
	dpSent := dptest.DP()
	dpSent.Timestamp = timeToSend
	log.Info("Sending a dp")
	forwarder.AddDatapoints(ctx, []*datapoint.Datapoint{dpSent})
	log.Info("Looking for DP back")
	dpSeen := forwardTo.Next()

	assert.Equal(t, "randtest."+dpSent.Metric, dpSeen.Metric, "Expect metric back")
	assert.Equal(t, dpSent.Timestamp, dpSeen.Timestamp, "Expect metric back")

	// Test creating a new connection if pool is empty
	for forwarder.pool.Get() != nil {
	}

	forwarder.AddDatapoints(ctx, []*datapoint.Datapoint{dpSent})
	dpSeen = forwardTo.Next()
	assert.Equal(t, "randtest."+dpSent.Metric, dpSeen.Metric, "Expect metric back")
	assert.Equal(t, dpSent.Timestamp, dpSeen.Timestamp, "Expect metric back")
	//
	// Test creation error if pool is empty
	for forwarder.pool.Get() != nil {
	}

	forwarder.dialer = func(network, address string, timeout time.Duration) (net.Conn, error) {
		return nil, errors.New("nope")
	}
	assert.Error(t, forwarder.AddDatapoints(ctx, []*datapoint.Datapoint{dpSeen}))

	forwarder.dialer = net.DialTimeout
	assert.NoError(t, forwarder.AddDatapoints(ctx, []*datapoint.Datapoint{dpSeen}), "Should get the conn back")

}
func TestCarbonNoWriteEvents(t *testing.T) {
	listenFrom := config.ListenFrom{}
	listenFrom.ListenAddr = workarounds.GolangDoesnotAllowPointerToStringLiteral("127.0.0.1:0")
	forwardTo := dptest.NewBasicSink()
	ctx := context.Background()
	l, err := ListenerLoader(ctx, forwardTo, &listenFrom)
	defer l.Close()
	assert.Equal(t, nil, err, "Expect no error")
	assert.Equal(t, numStats, len(l.Stats()), "Expect no stats")
	forwarder, err := NewForwarder("127.0.0.1", nettest.TCPPort(l.psocket), time.Second, []string{"zzfirst"}, 10)
	assert.Equal(t, nil, err, "Expect no error")
	assert.Equal(t, 1, len(forwarder.pool.conns))
	timeToSend := time.Now().Round(time.Second)
	eSent := dptest.E()
	eSent.Timestamp = timeToSend
	eSent.Meta["blarg"] = "abcd 123 123"
	log.Info("Sending a e")
	forwarder.AddEvents(ctx, []*event.Event{eSent})
	assert.Equal(t, 0, len(forwardTo.EventsChan))

}
func TestLoader(t *testing.T) {
	listenFrom := config.ListenFrom{}
	listenFrom.ListenAddr = workarounds.GolangDoesnotAllowPointerToStringLiteral("127.0.0.1:0")
	ctx := context.Background()
	forwardTo := dptest.NewBasicSink()
	l, err := ListenerLoader(ctx, forwardTo, &listenFrom)
	port := nettest.TCPPort(l.psocket)

	ft := config.ForwardTo{
		Host: workarounds.GolangDoesnotAllowPointerToStringLiteral("127.0.0.1"),
		Port: workarounds.GolangDoesnotAllowPointerToUint16Literal(port),
	}
	f, err := ForwarderLoader(context.Background(), &ft)
	assert.NoError(t, err)
	dpSent := dptest.DP()
	dpSent.Dimensions = map[string]string{}
	assert.NoError(t, f.AddDatapoints(ctx, []*datapoint.Datapoint{dpSent}))
	dpSeen := forwardTo.Next()
	assert.Equal(t, dpSent.Metric, dpSeen.Metric)
	assert.Equal(t, numStats+1, len(f.Stats()))
}
func TestCarbonWrite(t *testing.T) {
	listenFrom := config.ListenFrom{}
	listenFrom.ListenAddr = workarounds.GolangDoesnotAllowPointerToStringLiteral("127.0.0.1:0")
	forwardTo := dptest.NewBasicSink()
	ctx := context.Background()
	l, err := ListenerLoader(ctx, forwardTo, &listenFrom)
	defer l.Close()
	assert.Equal(t, nil, err, "Expect no error")
	assert.Equal(t, numStats, len(l.Stats()), "Expect no stats")
	forwarder, err := NewForwarder("127.0.0.1", nettest.TCPPort(l.psocket), time.Second, []string{"zzfirst"}, 10)
	assert.Equal(t, nil, err, "Expect no error")
	assert.Equal(t, 1, len(forwarder.pool.conns))
	timeToSend := time.Now().Round(time.Second)
	dpSent := dptest.DP()
	dpSent.Timestamp = timeToSend
	dpSent.Meta[carbonNative] = "abcd 123 123"
	log.Info("Sending a dp")
	forwarder.AddDatapoints(ctx, []*datapoint.Datapoint{dpSent})
	log.Info("Looking for DP back")
	dpSeen := forwardTo.Next()

	assert.Equal(t, "abcd", dpSeen.Metric, "Expect metric back")
}
func TestWriteError(t *testing.T) {
	listenFrom := config.ListenFrom{}
	listenFrom.ListenAddr = workarounds.GolangDoesnotAllowPointerToStringLiteral("127.0.0.1:0")

	forwardTo := dptest.NewBasicSink()
	ctx := context.Background()
	l, err := ListenerLoader(ctx, forwardTo, &listenFrom)
	defer l.Close()
	forwarder, err := NewForwarder("127.0.0.1", nettest.TCPPort(l.psocket), time.Second, []string{}, 10)
	assert.Equal(t, nil, err, "Expect no error")

	forwarder.dialer = func(network, address string, timeout time.Duration) (net.Conn, error) {
		mockConn := mockConn{}
		mockConn.writeReturn = errors.New("deadline error")
		return &mockConn, nil
	}

	for forwarder.pool.Get() != nil {
	}

	dpSent := dptest.DP()
	assert.Error(t, forwarder.AddDatapoints(ctx, []*datapoint.Datapoint{dpSent}))
}
func setupServerForwarder(t *testing.T) (*dptest.BasicSink, *ListenerServer, *Forwarder) {
	// TODO: Break this out into smaller tests
	listenFromSignalfx := config.ListenFrom{}
	listenFromSignalfx.ListenAddr = workarounds.GolangDoesnotAllowPointerToStringLiteral("127.0.0.1:0")

	finalDatapointDestination := dptest.NewBasicSink()
	ctx := context.Background()
	l, err := ListenerLoader(ctx, finalDatapointDestination, &listenFromSignalfx)
	assert.Equal(t, nil, err, "Expect no error")

	port := nettest.TCPPort(l.listener)

	forwardTo := config.ForwardTo{
		URL:              workarounds.GolangDoesnotAllowPointerToStringLiteral(fmt.Sprintf("http://127.0.0.1:%d/v2/datapoint", port)),
		TimeoutDuration:  workarounds.GolangDoesnotAllowPointerToDurationLiteral(time.Second * 1),
		DefaultAuthToken: workarounds.GolangDoesnotAllowPointerToStringLiteral("AUTH_TOKEN"),
		DefaultSource:    workarounds.GolangDoesnotAllowPointerToStringLiteral("proxy-source"),
		SourceDimensions: workarounds.GolangDoesnotAllowPointerToStringLiteral("username,ignored,hostname"),
	}

	_, forwarder, err := ForwarderLoader1(ctx, &forwardTo)
	assert.NoError(t, err, "Expect no error")
	return finalDatapointDestination, l, forwarder
}