github.com/snowflakedb/gosnowflake@v1.9.0/telemetry_test.go (about) 1 // Copyright (c) 2021-2022 Snowflake Computing Inc. All rights reserved. 2 3 package gosnowflake 4 5 import ( 6 "context" 7 "errors" 8 "math/rand" 9 "net/http" 10 "net/url" 11 "sync" 12 "testing" 13 "time" 14 ) 15 16 func TestTelemetryAddLog(t *testing.T) { 17 runSnowflakeConnTest(t, func(sct *SCTest) { 18 st := &snowflakeTelemetry{ 19 sr: sct.sc.rest, 20 mutex: &sync.Mutex{}, 21 enabled: true, 22 flushSize: defaultFlushSize, 23 } 24 rand.Seed(time.Now().UnixNano()) 25 randNum := rand.Int() % 10000 26 for i := 0; i < randNum; i++ { 27 if err := st.addLog(&telemetryData{ 28 Message: map[string]string{ 29 typeKey: "client_telemetry_type", 30 queryIDKey: "123", 31 }, 32 Timestamp: time.Now().UnixNano() / int64(time.Millisecond), 33 }); err != nil { 34 t.Fatal(err) 35 } 36 } 37 if len(st.logs) != randNum%defaultFlushSize { 38 t.Errorf("length of remaining logs does not match. expected: %v, got: %v", 39 randNum%defaultFlushSize, len(st.logs)) 40 } 41 if err := st.sendBatch(); err != nil { 42 t.Fatal(err) 43 } 44 }) 45 } 46 47 func TestTelemetrySQLException(t *testing.T) { 48 runSnowflakeConnTest(t, func(sct *SCTest) { 49 sct.sc.telemetry = &snowflakeTelemetry{ 50 sr: sct.sc.rest, 51 mutex: &sync.Mutex{}, 52 enabled: true, 53 flushSize: defaultFlushSize, 54 } 55 sfa := &snowflakeFileTransferAgent{ 56 sc: sct.sc, 57 commandType: uploadCommand, 58 srcFiles: make([]string, 0), 59 data: &execResponseData{ 60 SrcLocations: make([]string, 0), 61 }, 62 } 63 if err := sfa.initFileMetadata(); err == nil { 64 t.Fatal("this should have thrown an error") 65 } 66 if len(sct.sc.telemetry.logs) != 1 { 67 t.Errorf("there should be 1 telemetry data in log. found: %v", len(sct.sc.telemetry.logs)) 68 } 69 if sendErr := sct.sc.telemetry.sendBatch(); sendErr != nil { 70 t.Fatal(sendErr) 71 } 72 if len(sct.sc.telemetry.logs) != 0 { 73 t.Errorf("there should be no telemetry data in log. found: %v", len(sct.sc.telemetry.logs)) 74 } 75 }) 76 } 77 78 func TestDisableTelemetry(t *testing.T) { 79 config, err := ParseDSN(dsn) 80 if err != nil { 81 t.Error(err) 82 } 83 config.DisableTelemetry = true 84 sc, err := buildSnowflakeConn(context.Background(), *config) 85 if err != nil { 86 t.Fatal(err) 87 } 88 if err = authenticateWithConfig(sc); err != nil { 89 t.Fatal(err) 90 } 91 if !sc.cfg.DisableTelemetry { 92 t.Errorf("DisableTelemetry should be true. DisableTelemetry: %v", sc.cfg.DisableTelemetry) 93 } 94 if sc.telemetry.enabled { 95 t.Errorf("telemetry should be disabled.") 96 } 97 } 98 99 func TestEnableTelemetry(t *testing.T) { 100 runSnowflakeConnTest(t, func(sct *SCTest) { 101 if sct.sc.cfg.DisableTelemetry { 102 t.Errorf("DisableTelemetry should be false. DisableTelemetry: %v", sct.sc.cfg.DisableTelemetry) 103 } 104 if !sct.sc.telemetry.enabled { 105 t.Errorf("telemetry should be enabled.") 106 } 107 }) 108 } 109 110 func funcPostTelemetryRespFail(_ context.Context, _ *snowflakeRestful, _ *url.URL, _ map[string]string, _ []byte, _ time.Duration, _ currentTimeProvider, _ *Config) (*http.Response, error) { 111 return nil, errors.New("failed to upload metrics to telemetry") 112 } 113 114 func TestTelemetryError(t *testing.T) { 115 runSnowflakeConnTest(t, func(sct *SCTest) { 116 st := &snowflakeTelemetry{ 117 sr: &snowflakeRestful{ 118 FuncPost: funcPostTelemetryRespFail, 119 TokenAccessor: getSimpleTokenAccessor(), 120 }, 121 mutex: &sync.Mutex{}, 122 enabled: true, 123 flushSize: defaultFlushSize, 124 } 125 126 if err := st.addLog(&telemetryData{ 127 Message: map[string]string{ 128 typeKey: "client_telemetry_type", 129 queryIDKey: "123", 130 }, 131 Timestamp: time.Now().UnixNano() / int64(time.Millisecond), 132 }); err != nil { 133 t.Fatal(err) 134 } 135 136 err := st.sendBatch() 137 if err == nil { 138 t.Fatal("should have failed") 139 } 140 }) 141 } 142 143 func TestTelemetryDisabledOnBadResponse(t *testing.T) { 144 runSnowflakeConnTest(t, func(sct *SCTest) { 145 st := &snowflakeTelemetry{ 146 sr: &snowflakeRestful{ 147 FuncPost: postTestAppBadGatewayError, 148 TokenAccessor: getSimpleTokenAccessor(), 149 }, 150 mutex: &sync.Mutex{}, 151 enabled: true, 152 flushSize: defaultFlushSize, 153 } 154 155 if err := st.addLog(&telemetryData{ 156 Message: map[string]string{ 157 typeKey: "client_telemetry_type", 158 queryIDKey: "123", 159 }, 160 Timestamp: time.Now().UnixNano() / int64(time.Millisecond), 161 }); err != nil { 162 t.Fatal(err) 163 } 164 err := st.sendBatch() 165 if err == nil { 166 t.Fatal("should have failed") 167 } 168 if st.enabled == true { 169 t.Fatal("telemetry should be disabled") 170 } 171 172 st.enabled = true 173 st.sr.FuncPost = postTestQueryNotExecuting 174 if err = st.addLog(&telemetryData{ 175 Message: map[string]string{ 176 typeKey: "client_telemetry_type", 177 queryIDKey: "123", 178 }, 179 Timestamp: time.Now().UnixNano() / int64(time.Millisecond), 180 }); err != nil { 181 t.Fatal(err) 182 } 183 err = st.sendBatch() 184 if err == nil { 185 t.Fatal("should have failed") 186 } 187 if st.enabled == true { 188 t.Fatal("telemetry should be disabled") 189 } 190 191 st.enabled = true 192 st.sr.FuncPost = postTestSuccessButInvalidJSON 193 if err = st.addLog(&telemetryData{ 194 Message: map[string]string{ 195 typeKey: "client_telemetry_type", 196 queryIDKey: "123", 197 }, 198 Timestamp: time.Now().UnixNano() / int64(time.Millisecond), 199 }); err != nil { 200 t.Fatal(err) 201 } 202 err = st.sendBatch() 203 if err == nil { 204 t.Fatal("should have failed") 205 } 206 if st.enabled == true { 207 t.Fatal("telemetry should be disabled") 208 } 209 }) 210 } 211 212 func TestTelemetryDisabled(t *testing.T) { 213 runSnowflakeConnTest(t, func(sct *SCTest) { 214 st := &snowflakeTelemetry{ 215 sr: &snowflakeRestful{ 216 FuncPost: postTestAppBadGatewayError, 217 TokenAccessor: getSimpleTokenAccessor(), 218 }, 219 mutex: &sync.Mutex{}, 220 enabled: false, // disable 221 flushSize: defaultFlushSize, 222 } 223 if err := st.addLog(&telemetryData{ 224 Message: map[string]string{ 225 typeKey: "client_telemetry_type", 226 queryIDKey: "123", 227 }, 228 Timestamp: time.Now().UnixNano() / int64(time.Millisecond), 229 }); err == nil { 230 t.Fatal("should have failed") 231 } 232 st.enabled = true 233 if err := st.addLog(&telemetryData{ 234 Message: map[string]string{ 235 typeKey: "client_telemetry_type", 236 queryIDKey: "123", 237 }, 238 Timestamp: time.Now().UnixNano() / int64(time.Millisecond), 239 }); err != nil { 240 t.Fatal(err) 241 } 242 st.enabled = false 243 err := st.sendBatch() 244 if err == nil { 245 t.Fatal("should have failed") 246 } 247 }) 248 } 249 250 func TestAddLogError(t *testing.T) { 251 runSnowflakeConnTest(t, func(sct *SCTest) { 252 st := &snowflakeTelemetry{ 253 sr: &snowflakeRestful{ 254 FuncPost: funcPostTelemetryRespFail, 255 TokenAccessor: getSimpleTokenAccessor(), 256 }, 257 mutex: &sync.Mutex{}, 258 enabled: true, 259 flushSize: 1, 260 } 261 262 if err := st.addLog(&telemetryData{ 263 Message: map[string]string{ 264 typeKey: "client_telemetry_type", 265 queryIDKey: "123", 266 }, 267 Timestamp: time.Now().UnixNano() / int64(time.Millisecond), 268 }); err == nil { 269 t.Fatal("should have failed") 270 } 271 }) 272 }