github.com/mattermosttest/mattermost-server/v5@v5.0.0-20200917143240-9dfa12e121f9/app/diagnostics_test.go (about) 1 // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. 2 // See LICENSE.txt for license information. 3 4 package app 5 6 import ( 7 "encoding/json" 8 "io/ioutil" 9 "net/http" 10 "net/http/httptest" 11 "testing" 12 "time" 13 14 "github.com/stretchr/testify/assert" 15 "github.com/stretchr/testify/require" 16 17 "github.com/mattermost/mattermost-server/v5/model" 18 ) 19 20 func TestPluginSetting(t *testing.T) { 21 settings := &model.PluginSettings{ 22 Plugins: map[string]map[string]interface{}{ 23 "test": { 24 "foo": "bar", 25 }, 26 }, 27 } 28 assert.Equal(t, "bar", pluginSetting(settings, "test", "foo", "asd")) 29 assert.Equal(t, "asd", pluginSetting(settings, "test", "qwe", "asd")) 30 } 31 32 func TestPluginActivated(t *testing.T) { 33 states := map[string]*model.PluginState{ 34 "foo": { 35 Enable: true, 36 }, 37 "bar": { 38 Enable: false, 39 }, 40 } 41 assert.True(t, pluginActivated(states, "foo")) 42 assert.False(t, pluginActivated(states, "bar")) 43 assert.False(t, pluginActivated(states, "none")) 44 } 45 46 func TestPluginVersion(t *testing.T) { 47 plugins := []*model.BundleInfo{ 48 { 49 Manifest: &model.Manifest{ 50 Id: "test.plugin", 51 Version: "1.2.3", 52 }, 53 }, 54 { 55 Manifest: &model.Manifest{ 56 Id: "test.plugin2", 57 Version: "4.5.6", 58 }, 59 }, 60 } 61 assert.Equal(t, "1.2.3", pluginVersion(plugins, "test.plugin")) 62 assert.Equal(t, "4.5.6", pluginVersion(plugins, "test.plugin2")) 63 assert.Empty(t, pluginVersion(plugins, "unknown.plugin")) 64 } 65 66 func TestRudderDiagnostics(t *testing.T) { 67 if testing.Short() { 68 t.SkipNow() 69 } 70 71 th := SetupWithCustomConfig(t, func(config *model.Config) { 72 *config.PluginSettings.Enable = false 73 }) 74 defer th.TearDown() 75 76 type batch struct { 77 MessageId string 78 UserId string 79 Event string 80 Timestamp time.Time 81 Properties map[string]interface{} 82 } 83 84 type payload struct { 85 MessageId string 86 SentAt time.Time 87 Batch []batch 88 Context struct { 89 Library struct { 90 Name string 91 Version string 92 } 93 } 94 } 95 96 data := make(chan payload, 100) 97 server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 98 body, err := ioutil.ReadAll(r.Body) 99 require.NoError(t, err) 100 101 var p payload 102 err = json.Unmarshal(body, &p) 103 require.NoError(t, err) 104 105 data <- p 106 })) 107 defer server.Close() 108 109 marketplaceServer := httptest.NewServer(http.HandlerFunc(func(res http.ResponseWriter, req *http.Request) { 110 res.WriteHeader(http.StatusOK) 111 json, err := json.Marshal([]*model.MarketplacePlugin{{ 112 BaseMarketplacePlugin: &model.BaseMarketplacePlugin{ 113 Manifest: &model.Manifest{ 114 Id: "testplugin", 115 }, 116 }, 117 }}) 118 require.NoError(t, err) 119 res.Write(json) 120 })) 121 122 defer func() { marketplaceServer.Close() }() 123 124 diagnosticID := "test-diagnostic-id-12345" 125 th.App.SetDiagnosticId(diagnosticID) 126 th.Server.initDiagnostics(server.URL) 127 128 assertPayload := func(t *testing.T, actual payload, event string, properties map[string]interface{}) { 129 t.Helper() 130 assert.NotEmpty(t, actual.MessageId) 131 assert.False(t, actual.SentAt.IsZero()) 132 if assert.Len(t, actual.Batch, 1) { 133 assert.NotEmpty(t, actual.Batch[0].MessageId, "message id should not be empty") 134 assert.Equal(t, diagnosticID, actual.Batch[0].UserId) 135 if event != "" { 136 assert.Equal(t, event, actual.Batch[0].Event) 137 } 138 assert.False(t, actual.Batch[0].Timestamp.IsZero(), "batch timestamp should not be the zero value") 139 if properties != nil { 140 assert.Equal(t, properties, actual.Batch[0].Properties) 141 } 142 } 143 assert.Equal(t, "analytics-go", actual.Context.Library.Name) 144 assert.Equal(t, "3.0.0", actual.Context.Library.Version) 145 } 146 147 collectInfo := func(info *[]string) { 148 t.Helper() 149 for { 150 select { 151 case result := <-data: 152 assertPayload(t, result, "", nil) 153 *info = append(*info, result.Batch[0].Event) 154 case <-time.After(time.Second * 1): 155 return 156 } 157 } 158 } 159 160 collectBatches := func(info *[]batch) { 161 t.Helper() 162 for { 163 select { 164 case result := <-data: 165 assertPayload(t, result, "", nil) 166 *info = append(*info, result.Batch[0]) 167 case <-time.After(time.Second * 1): 168 return 169 } 170 } 171 } 172 173 // Should send a client identify message 174 select { 175 case identifyMessage := <-data: 176 assertPayload(t, identifyMessage, "", nil) 177 case <-time.After(time.Second * 1): 178 require.Fail(t, "Did not receive ID message") 179 } 180 181 t.Run("Send", func(t *testing.T) { 182 testValue := "test-send-value-6789" 183 th.App.Srv().SendDiagnostic("Testing Diagnostic", map[string]interface{}{ 184 "hey": testValue, 185 }) 186 select { 187 case result := <-data: 188 assertPayload(t, result, "Testing Diagnostic", map[string]interface{}{ 189 "hey": testValue, 190 }) 191 case <-time.After(time.Second * 1): 192 require.Fail(t, "Did not receive diagnostic") 193 } 194 }) 195 196 // Plugins remain disabled at this point 197 t.Run("SendDailyDiagnosticsPluginsDisabled", func(t *testing.T) { 198 th.App.Srv().sendDailyDiagnostics(true) 199 200 var info []string 201 // Collect the info sent. 202 collectInfo(&info) 203 204 for _, item := range []string{ 205 TRACK_CONFIG_SERVICE, 206 TRACK_CONFIG_TEAM, 207 TRACK_CONFIG_SQL, 208 TRACK_CONFIG_LOG, 209 TRACK_CONFIG_NOTIFICATION_LOG, 210 TRACK_CONFIG_FILE, 211 TRACK_CONFIG_RATE, 212 TRACK_CONFIG_EMAIL, 213 TRACK_CONFIG_PRIVACY, 214 TRACK_CONFIG_OAUTH, 215 TRACK_CONFIG_LDAP, 216 TRACK_CONFIG_COMPLIANCE, 217 TRACK_CONFIG_LOCALIZATION, 218 TRACK_CONFIG_SAML, 219 TRACK_CONFIG_PASSWORD, 220 TRACK_CONFIG_CLUSTER, 221 TRACK_CONFIG_METRICS, 222 TRACK_CONFIG_SUPPORT, 223 TRACK_CONFIG_NATIVEAPP, 224 TRACK_CONFIG_EXPERIMENTAL, 225 TRACK_CONFIG_ANALYTICS, 226 TRACK_CONFIG_PLUGIN, 227 TRACK_ACTIVITY, 228 TRACK_SERVER, 229 TRACK_CONFIG_MESSAGE_EXPORT, 230 // TRACK_PLUGINS, 231 } { 232 require.Contains(t, info, item) 233 } 234 }) 235 236 // Enable plugins for the remainder of the tests. 237 th.App.UpdateConfig(func(cfg *model.Config) { *cfg.PluginSettings.Enable = true }) 238 239 t.Run("SendDailyDiagnostics", func(t *testing.T) { 240 th.App.Srv().sendDailyDiagnostics(true) 241 242 var info []string 243 // Collect the info sent. 244 collectInfo(&info) 245 246 for _, item := range []string{ 247 TRACK_CONFIG_SERVICE, 248 TRACK_CONFIG_TEAM, 249 TRACK_CONFIG_SQL, 250 TRACK_CONFIG_LOG, 251 TRACK_CONFIG_NOTIFICATION_LOG, 252 TRACK_CONFIG_FILE, 253 TRACK_CONFIG_RATE, 254 TRACK_CONFIG_EMAIL, 255 TRACK_CONFIG_PRIVACY, 256 TRACK_CONFIG_OAUTH, 257 TRACK_CONFIG_LDAP, 258 TRACK_CONFIG_COMPLIANCE, 259 TRACK_CONFIG_LOCALIZATION, 260 TRACK_CONFIG_SAML, 261 TRACK_CONFIG_PASSWORD, 262 TRACK_CONFIG_CLUSTER, 263 TRACK_CONFIG_METRICS, 264 TRACK_CONFIG_SUPPORT, 265 TRACK_CONFIG_NATIVEAPP, 266 TRACK_CONFIG_EXPERIMENTAL, 267 TRACK_CONFIG_ANALYTICS, 268 TRACK_CONFIG_PLUGIN, 269 TRACK_ACTIVITY, 270 TRACK_SERVER, 271 TRACK_CONFIG_MESSAGE_EXPORT, 272 TRACK_PLUGINS, 273 } { 274 require.Contains(t, info, item) 275 } 276 }) 277 278 t.Run("Diagnostics for Marketplace plugins is returned", func(t *testing.T) { 279 th.App.Srv().trackPluginConfig(th.App.Srv().Config(), marketplaceServer.URL) 280 281 var batches []batch 282 collectBatches(&batches) 283 284 for _, b := range batches { 285 if b.Event == TRACK_CONFIG_PLUGIN { 286 assert.Contains(t, b.Properties, "enable_testplugin") 287 assert.Contains(t, b.Properties, "version_testplugin") 288 289 // Confirm known plugins are not present 290 assert.NotContains(t, b.Properties, "enable_jira") 291 assert.NotContains(t, b.Properties, "version_jira") 292 } 293 } 294 }) 295 296 t.Run("Diagnostics for known plugins is returned, if request to Marketplace fails", func(t *testing.T) { 297 th.App.Srv().trackPluginConfig(th.App.Srv().Config(), "http://some.random.invalid.url") 298 299 var batches []batch 300 collectBatches(&batches) 301 302 for _, b := range batches { 303 if b.Event == TRACK_CONFIG_PLUGIN { 304 assert.NotContains(t, b.Properties, "enable_testplugin") 305 assert.NotContains(t, b.Properties, "version_testplugin") 306 307 // Confirm known plugins are present 308 assert.Contains(t, b.Properties, "enable_jira") 309 assert.Contains(t, b.Properties, "version_jira") 310 } 311 } 312 }) 313 314 t.Run("SendDailyDiagnosticsNoRudderKey", func(t *testing.T) { 315 th.App.Srv().SendDailyDiagnostics() 316 317 select { 318 case <-data: 319 require.Fail(t, "Should not send diagnostics when the rudder key is not set") 320 case <-time.After(time.Second * 1): 321 // Did not receive diagnostics 322 } 323 }) 324 325 t.Run("SendDailyDiagnosticsDisabled", func(t *testing.T) { 326 th.App.UpdateConfig(func(cfg *model.Config) { *cfg.LogSettings.EnableDiagnostics = false }) 327 328 th.App.Srv().sendDailyDiagnostics(true) 329 330 select { 331 case <-data: 332 require.Fail(t, "Should not send diagnostics when they are disabled") 333 case <-time.After(time.Second * 1): 334 // Did not receive diagnostics 335 } 336 }) 337 }