1package awslogs // import "github.com/docker/docker/daemon/logger/awslogs"
2
3import (
4	"fmt"
5
6	"github.com/aws/aws-sdk-go/service/cloudwatchlogs"
7)
8
9type mockcwlogsclient struct {
10	createLogGroupArgument  chan *cloudwatchlogs.CreateLogGroupInput
11	createLogGroupResult    chan *createLogGroupResult
12	createLogStreamArgument chan *cloudwatchlogs.CreateLogStreamInput
13	createLogStreamResult   chan *createLogStreamResult
14	putLogEventsArgument    chan *cloudwatchlogs.PutLogEventsInput
15	putLogEventsResult      chan *putLogEventsResult
16}
17
18type createLogGroupResult struct {
19	successResult *cloudwatchlogs.CreateLogGroupOutput
20	errorResult   error
21}
22
23type createLogStreamResult struct {
24	successResult *cloudwatchlogs.CreateLogStreamOutput
25	errorResult   error
26}
27
28type putLogEventsResult struct {
29	successResult *cloudwatchlogs.PutLogEventsOutput
30	errorResult   error
31}
32
33func newMockClient() *mockcwlogsclient {
34	return &mockcwlogsclient{
35		createLogGroupArgument:  make(chan *cloudwatchlogs.CreateLogGroupInput, 1),
36		createLogGroupResult:    make(chan *createLogGroupResult, 1),
37		createLogStreamArgument: make(chan *cloudwatchlogs.CreateLogStreamInput, 1),
38		createLogStreamResult:   make(chan *createLogStreamResult, 1),
39		putLogEventsArgument:    make(chan *cloudwatchlogs.PutLogEventsInput, 1),
40		putLogEventsResult:      make(chan *putLogEventsResult, 1),
41	}
42}
43
44func newMockClientBuffered(buflen int) *mockcwlogsclient {
45	return &mockcwlogsclient{
46		createLogStreamArgument: make(chan *cloudwatchlogs.CreateLogStreamInput, buflen),
47		createLogStreamResult:   make(chan *createLogStreamResult, buflen),
48		putLogEventsArgument:    make(chan *cloudwatchlogs.PutLogEventsInput, buflen),
49		putLogEventsResult:      make(chan *putLogEventsResult, buflen),
50	}
51}
52
53func (m *mockcwlogsclient) CreateLogGroup(input *cloudwatchlogs.CreateLogGroupInput) (*cloudwatchlogs.CreateLogGroupOutput, error) {
54	m.createLogGroupArgument <- input
55	output := <-m.createLogGroupResult
56	return output.successResult, output.errorResult
57}
58
59func (m *mockcwlogsclient) CreateLogStream(input *cloudwatchlogs.CreateLogStreamInput) (*cloudwatchlogs.CreateLogStreamOutput, error) {
60	m.createLogStreamArgument <- input
61	output := <-m.createLogStreamResult
62	return output.successResult, output.errorResult
63}
64
65func (m *mockcwlogsclient) PutLogEvents(input *cloudwatchlogs.PutLogEventsInput) (*cloudwatchlogs.PutLogEventsOutput, error) {
66	events := make([]*cloudwatchlogs.InputLogEvent, len(input.LogEvents))
67	copy(events, input.LogEvents)
68	m.putLogEventsArgument <- &cloudwatchlogs.PutLogEventsInput{
69		LogEvents:     events,
70		SequenceToken: input.SequenceToken,
71		LogGroupName:  input.LogGroupName,
72		LogStreamName: input.LogStreamName,
73	}
74
75	// Intended mock output
76	output := <-m.putLogEventsResult
77
78	// Checked enforced limits in mock
79	totalBytes := 0
80	for _, evt := range events {
81		if evt.Message == nil {
82			continue
83		}
84		eventBytes := len([]byte(*evt.Message))
85		if eventBytes > maximumBytesPerEvent {
86			// exceeded per event message size limits
87			return nil, fmt.Errorf("maximum bytes per event exceeded: Event too large %d, max allowed: %d", eventBytes, maximumBytesPerEvent)
88		}
89		// total event bytes including overhead
90		totalBytes += eventBytes + perEventBytes
91	}
92
93	if totalBytes > maximumBytesPerPut {
94		// exceeded per put maximum size limit
95		return nil, fmt.Errorf("maximum bytes per put exceeded: Upload too large %d, max allowed: %d", totalBytes, maximumBytesPerPut)
96	}
97
98	return output.successResult, output.errorResult
99}
100
101type mockmetadataclient struct {
102	regionResult chan *regionResult
103}
104
105type regionResult struct {
106	successResult string
107	errorResult   error
108}
109
110func newMockMetadataClient() *mockmetadataclient {
111	return &mockmetadataclient{
112		regionResult: make(chan *regionResult, 1),
113	}
114}
115
116func (m *mockmetadataclient) Region() (string, error) {
117	output := <-m.regionResult
118	return output.successResult, output.errorResult
119}
120