github.com/keybase/client/go@v0.0.0-20241007131713-f10651d043c8/kbfs/libpages/stats_mysql_test.go (about) 1 // Copyright 2020 Keybase Inc. All rights reserved. 2 // Use of this source code is governed by a BSD 3 // license that can be found in the LICENSE file. 4 5 //go:build integration 6 // +build integration 7 8 package libpages 9 10 import ( 11 "context" 12 "database/sql" 13 "fmt" 14 "os" 15 "strconv" 16 "testing" 17 "time" 18 19 _ "github.com/go-sql-driver/mysql" 20 "github.com/keybase/client/go/kbfs/test/clocktest" 21 "github.com/keybase/client/go/kbfs/tlf" 22 "github.com/stretchr/testify/require" 23 "go.uber.org/zap" 24 ) 25 26 const defaultTestDSN = "root@unix(/tmp/mysql.sock)/kbp_test?parseTime=true" 27 const TestDSNEnvName = "TEST_DB_DSN" 28 29 func makeMySQLActivityStatsStorerForTest(t *testing.T) ( 30 *mysqlActivityStatsStorer, *clocktest.TestClock) { 31 logger, err := zap.NewDevelopment() 32 require.NoError(t, err) 33 dsn := os.Getenv(TestDSNEnvName) 34 if len(dsn) == 0 { 35 dsn = defaultTestDSN 36 } 37 db, err := sql.Open("mysql", dsn) 38 require.NoError(t, err, "open mysql") 39 clock := clocktest.NewTestClockNow() 40 return newMySQLActivityStatsStorerNoStart(clock, db, logger), clock 41 } 42 43 func TestMySQLActivityStatsStorer(t *testing.T) { 44 storer, clock := makeMySQLActivityStatsStorerForTest(t) 45 storer.createTablesIfNotExists(context.Background()) 46 47 // Make a prefix based on time so we don't have to clear the DB in test. 48 domainPrefix := strconv.FormatInt(time.Now().Unix(), 16) 49 makeDomain := func(id int) string { 50 return fmt.Sprintf("%s-%d.example.com", domainPrefix, id) 51 } 52 53 tlfID1, err := tlf.MakeRandomID(tlf.Public) 54 require.NoError(t, err) 55 tlfID2, err := tlf.MakeRandomID(tlf.Public) 56 require.NoError(t, err) 57 host1 := makeDomain(1) 58 host2 := makeDomain(2) 59 host3 := makeDomain(3) 60 61 clock.Add(30 * time.Second) 62 63 // At 00:30 64 storer.RecordActives(tlfID1, host1) 65 storer.RecordActives(tlfID1, host2) 66 storer.RecordActives(tlfID2, host3) 67 68 clock.Add(time.Minute) 69 70 // At 01:30 71 storer.RecordActives(tlfID1, host1) 72 storer.RecordActives(tlfID1, host2) 73 74 clock.Add(30 * time.Second) 75 76 storer.flushInserts() 77 78 // Now we're at 02:00 79 80 check := func() { 81 activeTlfs, activeHosts, err := storer.GetActives(time.Minute) 82 require.NoError(t, err) 83 require.Equal(t, 1, activeTlfs) 84 require.Equal(t, 2, activeHosts) 85 86 activeTlfs, activeHosts, err = storer.GetActives(2 * time.Minute) 87 require.NoError(t, err) 88 require.Equal(t, 2, activeTlfs) 89 require.Equal(t, 3, activeHosts) 90 } 91 check() 92 93 t.Logf("make sure older time don't override newer time") 94 clock.Add(-5 * time.Minute) 95 storer.RecordActives(tlfID1, host1) 96 storer.RecordActives(tlfID1, host2) 97 storer.RecordActives(tlfID2, host3) 98 clock.Add(5 * time.Minute) 99 storer.flushInserts() 100 check() 101 }