1
0
Fork 0
telegraf/plugins/inputs/ecs/client_test.go

321 lines
6.6 KiB
Go
Raw Permalink Normal View History

package ecs
import (
"bytes"
"errors"
"io"
"net/http"
"net/url"
"os"
"testing"
"github.com/docker/docker/api/types/container"
"github.com/stretchr/testify/require"
)
type pollMock struct {
getTask func() (*ecsTask, error)
getStats func() (map[string]*container.StatsResponse, error)
}
func (p *pollMock) task() (*ecsTask, error) {
return p.getTask()
}
func (p *pollMock) containerStats() (map[string]*container.StatsResponse, error) {
return p.getStats()
}
func TestEcsClient_PollSync(t *testing.T) {
tests := []struct {
name string
mock *pollMock
want *ecsTask
want1 map[string]*container.StatsResponse
wantErr bool
}{
{
name: "success",
mock: &pollMock{
getTask: func() (*ecsTask, error) {
return &validMeta, nil
},
getStats: func() (map[string]*container.StatsResponse, error) {
return validStats, nil
},
},
want: &validMeta,
want1: validStats,
},
{
name: "task err",
mock: &pollMock{
getTask: func() (*ecsTask, error) {
return nil, errors.New("err")
},
getStats: func() (map[string]*container.StatsResponse, error) {
return validStats, nil
},
},
wantErr: true,
},
{
name: "stats err",
mock: &pollMock{
getTask: func() (*ecsTask, error) {
return &validMeta, nil
},
getStats: func() (map[string]*container.StatsResponse, error) {
return nil, errors.New("err")
},
},
wantErr: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got, got1, err := pollSync(tt.mock)
if (err != nil) != tt.wantErr {
t.Errorf("ecsClient.pollSync() error = %v, wantErr %v", err, tt.wantErr)
return
}
require.Equal(t, tt.want, got, "ecsClient.pollSync() got = %v, want %v", got, tt.want)
require.Equal(t, tt.want1, got1, "ecsClient.pollSync() got1 = %v, want %v", got1, tt.want1)
})
}
}
type mockDo struct {
do func() (*http.Response, error)
}
func (m mockDo) Do(*http.Request) (*http.Response, error) {
return m.do()
}
func TestEcsClient_Task(t *testing.T) {
tests := []struct {
name string
client httpClient
want *ecsTask
wantErr bool
}{
{
name: "happy",
client: mockDo{
do: func() (*http.Response, error) {
rc, err := os.Open("testdata/metadata.golden")
if err != nil {
return nil, err
}
return &http.Response{
StatusCode: http.StatusOK,
Body: io.NopCloser(rc),
}, nil
},
},
want: &validMeta,
},
{
name: "do err",
client: mockDo{
do: func() (*http.Response, error) {
return nil, errors.New("err")
},
},
wantErr: true,
},
{
name: "malformed 500 resp",
client: mockDo{
do: func() (*http.Response, error) {
return &http.Response{
StatusCode: http.StatusInternalServerError,
Body: io.NopCloser(bytes.NewReader([]byte("foo"))),
}, nil
},
},
wantErr: true,
},
{
name: "malformed 200 resp",
client: mockDo{
do: func() (*http.Response, error) {
return &http.Response{
StatusCode: http.StatusOK,
Body: io.NopCloser(bytes.NewReader([]byte("foo"))),
}, nil
},
},
wantErr: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
c := &ecsClient{
client: tt.client,
taskURL: "abc",
}
got, err := c.task()
if (err != nil) != tt.wantErr {
t.Errorf("ecsClient.task() error = %v, wantErr %v", err, tt.wantErr)
return
}
require.Equal(t, tt.want, got, "ecsClient.task() = %v, want %v", got, tt.want)
})
}
}
func TestEcsClient_ContainerStats(t *testing.T) {
tests := []struct {
name string
client httpClient
want map[string]*container.StatsResponse
wantErr bool
}{
{
name: "happy",
client: mockDo{
do: func() (*http.Response, error) {
rc, err := os.Open("testdata/stats.golden")
if err != nil {
return nil, err
}
return &http.Response{
StatusCode: http.StatusOK,
Body: io.NopCloser(rc),
}, nil
},
},
want: validStats,
},
{
name: "do err",
client: mockDo{
do: func() (*http.Response, error) {
return nil, errors.New("err")
},
},
want: nil,
wantErr: true,
},
{
name: "malformed 200 resp",
client: mockDo{
do: func() (*http.Response, error) {
return &http.Response{
StatusCode: http.StatusOK,
Body: io.NopCloser(bytes.NewReader([]byte("foo"))),
}, nil
},
},
want: nil,
wantErr: true,
},
{
name: "malformed 500 resp",
client: mockDo{
do: func() (*http.Response, error) {
return &http.Response{
StatusCode: http.StatusInternalServerError,
Body: io.NopCloser(bytes.NewReader([]byte("foo"))),
}, nil
},
},
want: nil,
wantErr: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
c := &ecsClient{
client: tt.client,
statsURL: "abc",
}
got, err := c.containerStats()
if (err != nil) != tt.wantErr {
t.Errorf("ecsClient.containerStats() error = %v, wantErr %v", err, tt.wantErr)
return
}
require.Equal(t, tt.want, got, "ecsClient.containerStats() = %v, want %v", got, tt.want)
})
}
}
func TestResolveTaskURL(t *testing.T) {
tests := []struct {
name string
base string
ver int
exp string
}{
{
name: "default v2 endpoint",
base: v2Endpoint,
ver: 2,
exp: "http://169.254.170.2/v2/metadata",
},
{
name: "custom v2 endpoint",
base: "http://192.168.0.1",
ver: 2,
exp: "http://192.168.0.1/v2/metadata",
},
{
name: "theoretical v3 endpoint",
base: "http://169.254.170.2/v3/metadata",
ver: 3,
exp: "http://169.254.170.2/v3/metadata/task",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
baseURL, err := url.Parse(tt.base)
require.NoError(t, err)
act := resolveTaskURL(baseURL, tt.ver)
require.Equal(t, tt.exp, act)
})
}
}
func TestResolveStatsURL(t *testing.T) {
tests := []struct {
name string
base string
ver int
exp string
}{
{
name: "default v2 endpoint",
base: v2Endpoint,
ver: 2,
exp: "http://169.254.170.2/v2/stats",
},
{
name: "custom v2 endpoint",
base: "http://192.168.0.1",
ver: 2,
exp: "http://192.168.0.1/v2/stats",
},
{
name: "theoretical v3 endpoint",
base: "http://169.254.170.2/v3/metadata",
ver: 3,
exp: "http://169.254.170.2/v3/metadata/task/stats",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
baseURL, err := url.Parse(tt.base)
require.NoError(t, err)
act := resolveStatsURL(baseURL, tt.ver)
require.Equal(t, tt.exp, act)
})
}
}