diff --git a/server/services/telemetry/telemetry_test.go b/server/services/telemetry/telemetry_test.go new file mode 100644 index 000000000..1fa66ba3b --- /dev/null +++ b/server/services/telemetry/telemetry_test.go @@ -0,0 +1,113 @@ +package telemetry + +import ( + "bytes" + "encoding/json" + "io" + "net/http" + "net/http/httptest" + "os" + "strings" + "testing" + "time" + + "github.com/mattermost/mattermost-server/v6/shared/mlog" + "github.com/stretchr/testify/require" +) + +func mockServer() (chan []byte, *httptest.Server) { + done := make(chan []byte, 1) + + server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + buf := bytes.NewBuffer(nil) + if _, err := io.Copy(buf, r.Body); err != nil { + panic(err) + } + + var v interface{} + err := json.Unmarshal(buf.Bytes(), &v) + if err != nil { + panic(err) + } + + b, err := json.MarshalIndent(v, "", " ") + if err != nil { + panic(err) + } + + // filter the identify message + if strings.Contains(string(b), `"type": "identify"`) { + return + } + + done <- b + })) + + return done, server +} + +func TestTelemetry(t *testing.T) { + receiveChan, server := mockServer() + + os.Setenv("RUDDER_KEY", "mock-test-rudder-key") + os.Setenv("RUDDER_DATAPLANE_URL", server.URL) + + checkMockRudderServer := func(t *testing.T) { + // check mock rudder server got + got := string(<-receiveChan) + require.Contains(t, got, "mockTrackerKey") + require.Contains(t, got, "mockTrackerValue") + } + + t.Run("Register tracker and run telemetry job", func(t *testing.T) { + service := New("mockTelemetryID", mlog.CreateConsoleTestLogger(false, mlog.LvlDebug)) + service.RegisterTracker("mockTracker", func() (Tracker, error) { + return map[string]interface{}{ + "mockTrackerKey": "mockTrackerValue", + }, nil + }) + + service.RunTelemetryJob(time.Now().UnixNano() / int64(time.Millisecond)) + checkMockRudderServer(t) + }) + + t.Run("do telemetry if needed", func(t *testing.T) { + service := New("mockTelemetryID", mlog.CreateConsoleTestLogger(false, mlog.LvlDebug)) + service.RegisterTracker("mockTracker", func() (Tracker, error) { + return map[string]interface{}{ + "mockTrackerKey": "mockTrackerValue", + }, nil + }) + + firstRun := time.Now() + t.Run("Send once every 10 minutes for the first hour", func(t *testing.T) { + service.doTelemetryIfNeeded(firstRun.Add(-30 * time.Minute)) + checkMockRudderServer(t) + }) + + t.Run("Send once every hour thereafter for the first 12 hours", func(t *testing.T) { + // firstRun is 2 hours ago and timestampLastTelemetrySent is hour ago + // need to do telemetry + service.timestampLastTelemetrySent = time.Now().Add(-time.Hour) + service.doTelemetryIfNeeded(firstRun.Add(-2 * time.Hour)) + checkMockRudderServer(t) + + // firstRun is 2 hours ago and timestampLastTelemetrySent is just now + // no need to do telemetry + service.doTelemetryIfNeeded(firstRun.Add(-2 * time.Hour)) + require.Equal(t, 0, len(receiveChan)) + }) + t.Run("Send at the 24 hour mark and every 24 hours after", func(t *testing.T) { + // firstRun is 24 hours ago and timestampLastTelemetrySent is 24 hours ago + // need to do telemetry + service.timestampLastTelemetrySent = time.Now().Add(-24 * time.Hour) + service.doTelemetryIfNeeded(firstRun.Add(-24 * time.Hour)) + checkMockRudderServer(t) + + // firstRun is 24 hours ago and timestampLastTelemetrySent is just now + // no need to do telemetry + service.doTelemetryIfNeeded(firstRun.Add(-24 * time.Hour)) + require.Equal(t, 0, len(receiveChan)) + }) + }) +}