Skip to content

Commit b59222d

Browse files
committed
test implemented
1 parent 4535ee9 commit b59222d

File tree

3 files changed

+149
-150
lines changed

3 files changed

+149
-150
lines changed

monitoring/exporter/stackdriver/data_test.go

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ import (
2323
"go.opencensus.io/stats"
2424
"go.opencensus.io/stats/view"
2525
"go.opencensus.io/tag"
26-
monitoredrespb "google.golang.org/genproto/googleapis/api/monitoredres"
26+
mrpb "google.golang.org/genproto/googleapis/api/monitoredres"
2727
)
2828

2929
// This file defines various data needed for testing.
@@ -56,8 +56,9 @@ const (
5656
var (
5757
ctx = context.Background()
5858

59+
invalidDataErrStr = "invalid data"
5960
// This error is used for test to catch some error happpened.
60-
invalidDataError = errors.New("invalid data")
61+
invalidDataError = errors.New(invalidDataErrStr)
6162
// This error is used for unexpected error.
6263
unrecognizedDataError = errors.New("unrecognized data")
6364

@@ -84,7 +85,7 @@ var (
8485
Name: metric3name,
8586
Description: metric3desc,
8687
TagKeys: []tag.Key{projectKey},
87-
Measure: stats.Int(metric3name, metric3desc, stats.UnitDimensionless),
88+
Measure: stats.Int64(metric3name, metric3desc, stats.UnitDimensionless),
8889
Aggregation: view.Sum(),
8990
}
9091

@@ -111,11 +112,11 @@ var (
111112
Data: &view.SumData{Value: 5},
112113
}
113114
view3row1 = &view.Row{
114-
Tags: []tag.Tag{{ProjectKeyName, project1}},
115+
Tags: []tag.Tag{{projectKey, project1}},
115116
Data: &view.SumData{Value: 6},
116117
}
117118
view3row2 = &view.Row{
118-
Tags: []tag.Tag{{ProjectKeyName, project1}},
119+
Tags: []tag.Tag{{projectKey, project2}},
119120
Data: &view.SumData{Value: 7},
120121
}
121122
// This Row does not have valid Data field, so is invalid.
@@ -126,15 +127,15 @@ var (
126127
startTime2 = endTime2.Add(-10 * time.Second)
127128
endTime2 = time.Now()
128129

129-
resource1 = &monitoredrespb.MonitoredResource{
130+
resource1 = &mrpb.MonitoredResource{
130131
Type: "cloudsql_database",
131132
Labels: map[string]string{
132133
"project_id": project1,
133134
"region": "us-central1",
134135
"database_id": "cloud-SQL-instance-1",
135136
},
136137
}
137-
resource2 = &monitoredrespb.MonitoredResource{
138+
resource2 = &mrpb.MonitoredResource{
138139
Type: "gce_instance",
139140
Labels: map[string]string{
140141
"project_id": project2,

monitoring/exporter/stackdriver/mock_check_test.go

Lines changed: 53 additions & 104 deletions
Original file line numberDiff line numberDiff line change
@@ -17,124 +17,101 @@ package stackdriver
1717
import (
1818
"context"
1919
"fmt"
20-
"os"
2120
"strings"
2221
"testing"
23-
"time"
2422

2523
monitoring "cloud.google.com/go/monitoring/apiv3"
2624
gax "github.com/googleapis/gax-go"
2725
"google.golang.org/api/option"
2826
"google.golang.org/api/support/bundler"
29-
monitoringpb "google.golang.org/genproto/googleapis/monitoring/v3"
27+
mpb "google.golang.org/genproto/googleapis/monitoring/v3"
3028
)
3129

3230
// This file defines various mocks for testing, and checking functions for mocked data. We mock
3331
// metric client and bundler because their actions involves RPC calls or non-deterministic behavior.
3432

3533
var (
36-
// bundlerMark records
37-
bundlerMark map[string]*bundler.Bundler
38-
// projAddedRds saves all
39-
projAddedRds map[string][]*RowData
34+
// bundlerRec records project ID of given bundler.
35+
bndlerProjMap map[*bundler.Bundler]string
36+
// projRds saves all RowData objects passed to addToBundler call by project ID.
37+
projRds map[string]*[]*RowData
4038

4139
// timeSeriesReqs saves all incoming requests for creating time series.
42-
timeSerieReqs []*monitoringpb.CreateTimeSeriesRequest
40+
timeSeriesReqs []*mpb.CreateTimeSeriesRequest
4341
// timeSeriesResults holds predefined error values to be returned by mockCreateTimeSerie()
4442
// calls. Each errors in timeSeriesResults are returned per each mockCreateTimeSeries()
4543
// call. If all errors in timeSeriesResults are used, all other mockCreateTimeSeries calls
4644
// will return nil.
4745
timeSeriesResults []error
46+
47+
errRds []errRowData
4848
)
4949

5050
func init() {
5151
// For testing convenience, we reduce maximum time series that metric client accepts.
5252
MaxTimeSeriesPerUpload = 3
5353

54+
// Mock functions.
5455
newMetricClient = mockNewMetricClient
5556
createTimeSeries = mockCreateTimeSeries
57+
newBundler = mockNewBundler
58+
addToBundler = mockAddToBundler
59+
}
5660

61+
func testInit() {
62+
bndlerProjMap = map[*bundler.Bundler]string{}
63+
projRds = map[string]*[]*RowData{}
64+
timeSeriesReqs = nil
65+
timeSeriesResults = nil
66+
errRds = nil
5767
}
5868

5969
func mockNewMetricClient(_ context.Context, _ ...option.ClientOption) (*monitoring.MetricClient, error) {
6070
return nil, nil
6171
}
6272

63-
func mockCreateTimeSeries(_ *monitoing.MetricClient, _ context.Context, req *monitoringpb.CreateTimeSeriesRequest, _ ...gax.CallOption) error {
64-
createTimeSeriesReq = append(createTimeSeriesReq, req)
65-
// Check returnErrs and if not empty, return the first error from it.
66-
if len(createTimereturnErrs) == 0 {
73+
func mockCreateTimeSeries(_ *monitoring.MetricClient, _ context.Context, req *mpb.CreateTimeSeriesRequest, _ ...gax.CallOption) error {
74+
timeSeriesReqs = append(timeSeriesReqs, req)
75+
// Check timeSeriesResults and if not empty, return the first error from it.
76+
if len(timeSeriesResults) == 0 {
6777
return nil
6878
}
69-
err := data.returnErrs[0]
79+
err := timeSeriesResults[0]
7080
// Delete the returning error.
71-
data.returnErrs = data.returnErrs[1:]
81+
timeSeriesResults = timeSeriesResults[1:]
7282
return err
7383
}
7484

75-
func mockNewBundler(projectID string, _ interface{}, _ int) *bundler.Bundler {
85+
func mockNewBundler(projectID string, _ interface{}, _ func(interface{})) *bundler.Bundler {
7686
bndler := &bundler.Bundler{}
77-
bndler2proj[bndler] = projectID
78-
return bndlr
87+
bndlerProjMap[bndler] = projectID
88+
return bndler
7989
}
8090

81-
func addToBundler(bndler *bundler.Bundler, item interface{}, _ int) error {
82-
rds := &projAddRds[bndler2proj[bndler]]
83-
*rds = append(*rds, iterm.(*RowData))
84-
return nil
85-
}
86-
87-
func TestMain(m *testing.M) {
88-
89-
// Clear all data that stores behavior of mocked functions.
90-
createTimeSeriesReq = nil
91-
createTimeSeriesReturnErrs = nil
92-
93-
os.Exit(m.Run())
94-
}
95-
96-
// We define mock Client.
97-
98-
func (data *mockMetricClientData) createTimeSeries(_ *monitoring.MetricClient, _ context.Context, req *monitoringpb.CreateTimeSeriesRequest, opts ...gax.CallOption) error {
99-
data.reqs = append(data.reqs, req)
100-
// Check returnErrs and if not empty, return the first error from it.
101-
if len(data.returnErrs) == 0 {
102-
return nil
91+
func mockAddToBundler(bndler *bundler.Bundler, item interface{}, _ int) error {
92+
projID := bndlerProjMap[bndler]
93+
rds, ok := projRds[projID]
94+
if !ok {
95+
var rdsOrig []*RowData
96+
rds = &rdsOrig
97+
projRds[projID] = rds
10398
}
104-
err := data.returnErrs[0]
105-
// Delete the returning error.
106-
data.returnErrs = data.returnErrs[1:]
107-
return err
108-
}
109-
110-
func (data *mockMetricClientData) addReturnErrs(errs ...error) {
111-
data.returnErrs = append(data.returnErrs, errs...)
112-
}
113-
114-
func (data *mockMetricClientData) newMetricClient(_ context.Context, _ ...option.ClientOption) (*monitoring.MetricClient, error) {
115-
return nil, nil
116-
}
117-
118-
func newMockClientData() *mockMetricClientData {
119-
data := &mockMetricClientData{}
120-
newMetricClient = data.newMetricClient
121-
createTimeSeries = data.createTimesSeries
122-
return data
99+
*rds = append(*rds, item.(*RowData))
100+
return nil
123101
}
124102

125103
// checkMetricClient checks all recorded requests in mock metric client. We only compare int64
126104
// values of the time series. To make this work, we assigned different int64 values for all valid
127105
// rows in the test.
128-
func checkMetricClientData(t *testing.T, data *mockMetricClientData, wantReqsValues [][]int64) {
129-
reqs := data.reqs
130-
reqsLen, wantReqsLen := len(reqs), len(wantReqsValues)
106+
func checkMetricClient(t *testing.T, wantReqsValues [][]int64) {
107+
reqsLen, wantReqsLen := len(timeSeriesReqs), len(wantReqsValues)
131108
if reqsLen != wantReqsLen {
132109
t.Errorf("number of requests got: %d, want %d", reqsLen, wantReqsLen)
133110
return
134111
}
135112
for i := 0; i < reqsLen; i++ {
136113
prefix := fmt.Sprintf("%d-th request mismatch", i+1)
137-
tsArr := reqs[i].TimeSeries
114+
tsArr := timeSeriesReqs[i].TimeSeries
138115
wantTsValues := wantReqsValues[i]
139116
tsArrLen, wantTsArrLen := len(tsArr), len(wantTsValues)
140117
if tsArrLen != wantTsArrLen {
@@ -143,7 +120,7 @@ func checkMetricClientData(t *testing.T, data *mockMetricClientData, wantReqsVal
143120
}
144121
for j := 0; j < tsArrLen; j++ {
145122
// This is how monitoring API stores the int64 value.
146-
tsVal := tsArr[j].Points[0].Value.Value.(*monitoringpb.TypedValue_Int64Value).Int64Value
123+
tsVal := tsArr[j].Points[0].Value.Value.(*mpb.TypedValue_Int64Value).Int64Value
147124
wantTsVal := wantTsValues[j]
148125
if tsVal != wantTsVal {
149126
t.Errorf("%s: Value got: %d, want: %d", prefix, tsVal, wantTsVal)
@@ -152,39 +129,17 @@ func checkMetricClientData(t *testing.T, data *mockMetricClientData, wantReqsVal
152129
}
153130
}
154131

155-
// We define mock bundler.
156-
157-
type mockBundler struct {
158-
// rowDataArr saves all incoming RowData to the bundler.
159-
rowDataArr []*RowData
160-
}
161-
162-
func (b *mockBundler) Add(rowData interface{}, _ int) error {
163-
b.rowDataArr = append(b.rowDataArr, rowData.(*RowData))
164-
return nil
165-
}
166-
167-
func (b *mockBundler) Flush() {}
168-
169-
func mockNewExpBundler(_ func(interface{}), _ time.Duration, _ int) expBundler {
170-
return &mockBundler{}
171-
}
172-
173132
// We define a storage for all errors happened in export operation.
174133

175-
type errStorage struct {
176-
errRds []errRowData
177-
}
178-
179134
type errRowData struct {
180135
err error
181136
rds []*RowData
182137
}
183138

184139
// onError records any incoming error and accompanying RowData array. This method is passed to the
185140
// exporter to record errors.
186-
func (e *errStorage) onError(err error, rds ...*RowData) {
187-
e.errRds = append(e.errRds, errRowData{err, rds})
141+
func testOnError(err error, rds ...*RowData) {
142+
errRds = append(errRds, errRowData{err, rds})
188143
}
189144

190145
// errRowDataCheck contains data for checking content of error storage.
@@ -194,8 +149,7 @@ type errRowDataCheck struct {
194149
}
195150

196151
// checkErrStorage checks content of error storage. For returned errors, we check prefix and suffix.
197-
func checkErrStorage(t *testing.T, errStore *errStorage, wantErrRdCheck []errRowDataCheck) {
198-
errRds := errStore.errRds
152+
func checkErrStorage(t *testing.T, wantErrRdCheck []errRowDataCheck) {
199153
gotLen, wantLen := len(errRds), len(wantErrRdCheck)
200154
if gotLen != wantLen {
201155
t.Errorf("number of reported errors: %d, want: %d", gotLen, wantLen)
@@ -248,48 +202,43 @@ func checkRowData(rd, wantRd *RowData) error {
248202

249203
// newMockExp creates mock expoter and error storage storing all errors. Caller need not set
250204
// opts.OnError.
251-
func newMockExp(t *testing.T, opts *Options) (*StatsExporter, *errStorage) {
252-
errStore := &errStorage{}
253-
opts.OnError = errStore.onError
254-
exp, err := NewStatsExporter(ctx, opts)
205+
func newTestExp(t *testing.T, opts *Options) *Exporter {
206+
opts.OnError = testOnError
207+
exp, err := NewExporter(ctx, opts)
255208
if err != nil {
256209
t.Fatalf("creating exporter failed: %v", err)
257210
}
258-
return exp, errStore
211+
return exp
259212
}
260213

261214
// checkExpProjData checks all data passed to the bundler by bundler.Add().
262-
func checkExpProjData(t *testing.T, exp *StatsExporter, wantProjData map[string][]*RowData) {
215+
func checkExpProjData(t *testing.T, wantProjData map[string][]*RowData) {
263216
wantProj := map[string]bool{}
264217
for proj := range wantProjData {
265218
wantProj[proj] = true
266219
}
267-
for proj := range exp.projDataMap {
220+
for proj := range projRds {
268221
if !wantProj[proj] {
269222
t.Errorf("project in exporter's project data not wanted: %s", proj)
270223
}
271224
}
272225

273226
for proj, wantRds := range wantProjData {
274-
pd, ok := exp.projDataMap[proj]
227+
rds, ok := projRds[proj]
275228
if !ok {
276229
t.Errorf("wanted project not found in exporter's project data: %v", proj)
277230
continue
278231
}
279-
// We know that bundler is mocked, so we can check the data in it.
280-
if err := checkRowDataArr(pd.bndler.(*mockBundler).rowDataArr, wantRds); err != nil {
232+
if err := checkRowDataArr(*rds, wantRds); err != nil {
281233
t.Errorf("RowData array mismatch for project %s: %v", proj, err)
282234
}
283235
}
284236
}
285237

286238
// newMockUploader creates objects to test behavior of projectData.uploadRowData. Other uses are not
287239
// recommended.
288-
func newMockUploader(t *testing.T, opts *Options) (*projectData, *mockMetricClient, *errStorage) {
289-
exp, errStore := newMockExp(t, opts)
290-
pd := exp.newProjectData(project1)
291-
cl := exp.client.(*mockMetricClient)
292-
return pd, cl, errStore
240+
func newTestProjData(t *testing.T, opts *Options) *projectData {
241+
return newTestExp(t, opts).newProjectData(project1)
293242
}
294243

295244
// checkLabels checks data in labels.

0 commit comments

Comments
 (0)