@@ -17,124 +17,101 @@ package stackdriver
1717import (
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
3533var (
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
5050func 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
5969func 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-
179134type 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