Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,5 @@
/_dev/clickhouse
/_dev/clickhouse2
/_dev/grafana
/data_archive
/data_archive
cover.out
26 changes: 25 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,10 @@ down: ## Stops the environment
docker-compose -f ${dc_path} down
env UID=${UID} docker-compose -f ${dc_grafana_path} down

down/clean: down
rm -rf _dev/clickhouse
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ivan-stankov-golang This deletes all the ClickHouse persisted beacon data. What's the motivation behind deleting the folder?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I created a new target down/clean. To be able to test migrations scripts applied on clean database

mkdir -p _dev/clickhouse

restart: down up # Restart the environment

rebuild: ## Rebuilds the environment from scratch
Expand Down Expand Up @@ -137,4 +141,24 @@ docker-hub:

.PHONY: debug-docker-integration-test
debug-docker-integration-test:
docker-compose -f docker-compose.test.yaml up --build integration_server
docker-compose -f docker-compose.test.yaml up --build integration_server

.PHONY: docker/local/build
docker/local/build:
docker build -t front_basicrum_go .

.PHONY: gen
gen:
go generate

.PHONY: cover
cover:
go test -short -cover -coverprofile cover.out ./...
go tool cover -func=cover.out
go tool cover -html=cover.out

.PHONY: cover-integration
cover-integration:
SKIP_E2E=true go test -count=1 -cover -coverprofile cover.out ./...
go tool cover -func=cover.out
go tool cover -html=cover.out
3 changes: 3 additions & 0 deletions config/startup_config.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@ type StartupConfig struct {
Domain string `envconfig:"BRUM_SERVER_SSL_LETS_ENCRYPT_DOMAIN"`
}
}
PrivateAPI struct {
Token string `envconfig:"BRUM_PRIVATE_API_TOKEN"`
}
Database struct {
Username string `required:"true" envconfig:"BRUM_DATABASE_USERNAME"`
Password string `required:"true" envconfig:"BRUM_DATABASE_PASSWORD"`
Expand Down
30 changes: 26 additions & 4 deletions dao/dao.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,15 @@ import (
"github.com/ClickHouse/clickhouse-go/v2"

"github.com/basicrum/front_basicrum_go/beacon"
"github.com/basicrum/front_basicrum_go/types"
)

const (
baseTableName = "webperf_rum_events"
baseHostsTableName = "webperf_rum_hostnames"
tablePrefixPlaceholder = "{prefix}"
bufferSize = 1024
baseTableName = "webperf_rum_events"
baseHostsTableName = "webperf_rum_hostnames"
baseOwnerHostsTableName = "webperf_rum_own_hostnames"
tablePrefixPlaceholder = "{prefix}"
bufferSize = 1024
)

// DAO is data access object for clickhouse database
Expand Down Expand Up @@ -78,3 +80,23 @@ func (p *DAO) SaveHost(event beacon.HostnameEvent) error {
}
return nil
}

// InsertOwnerHostname inserts a new hostname
func (p *DAO) InsertOwnerHostname(item types.OwnerHostname) error {
query := fmt.Sprintf(
"INSERT INTO %s%s(username, hostname, subscription_id, subscription_expire_at) VALUES(?,?,?,?)",
p.prefix,
baseOwnerHostsTableName,
)
return p.conn.Exec(context.Background(), query, item.Username, item.Hostname, item.Subscription.ID, item.Subscription.ExpiresAt)
}

// DeleteOwnerHostname deletes the hostname
func (p *DAO) DeleteOwnerHostname(hostname, username string) error {
query := fmt.Sprintf(
"DELETE FROM %s%s WHERE hostname = ? AND username = ?",
p.prefix,
baseOwnerHostsTableName,
)
return p.conn.Exec(context.Background(), query, hostname, username)
}
117 changes: 110 additions & 7 deletions dao/dao_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (

"github.com/basicrum/front_basicrum_go/beacon"
"github.com/basicrum/front_basicrum_go/config"
"github.com/basicrum/front_basicrum_go/types"
"github.com/stretchr/testify/suite"
)

Expand Down Expand Up @@ -85,7 +86,7 @@ func (s *daoTestSuite) Test_SaveHost() {
sleep()

// then
s.Equal(1, s.countHosts())
s.Equal(1, s.countRows(baseHostsTableName))

// given
event = beacon.NewHostnameEvent(
Expand All @@ -100,7 +101,77 @@ func (s *daoTestSuite) Test_SaveHost() {
sleep()

// then
s.Equal(1, s.countHosts())
s.Equal(1, s.countRows(baseHostsTableName))
}

func (s *daoTestSuite) Test_InsertOwnerHostname() {
// given
ownerHostname := types.NewOwnerHostname(
"test1",
"hostname1",
types.NewSubscription(time.Now()),
)

// when
err := s.dao.InsertOwnerHostname(ownerHostname)
s.NoError(err)

// then
s.Equal(1, s.countRows(baseOwnerHostsTableName))

// given
ownerHostname = types.NewOwnerHostname(
"test1",
"hostname1",
types.NewSubscription(time.Now().Add(time.Hour)),
)

// when
err = s.dao.InsertOwnerHostname(ownerHostname)
s.NoError(err)

// then
s.Equal(1, s.countRows(baseOwnerHostsTableName))

whereClause := "WHERE hostname='hostname1'"
s.Equal(
"test1",
s.selectColumnString("username", baseOwnerHostsTableName, whereClause),
)
s.Equal(
ownerHostname.Subscription.ID,
s.selectColumnString("subscription_id", baseOwnerHostsTableName, whereClause),
)
s.EqualTime(
ownerHostname.Subscription.ExpiresAt,
s.selectColumnTime("subscription_expire_at", baseOwnerHostsTableName, whereClause),
)
}

func (s *daoTestSuite) Test_DeleteOwnerHostname() {
// given
ownerHostname := types.NewOwnerHostname(
"test1",
"hostname1",
types.NewSubscription(time.Now()),
)

// when
err := s.dao.InsertOwnerHostname(ownerHostname)
s.NoError(err)

// then
s.Equal(1, s.countRows(baseOwnerHostsTableName))

// when
err = s.dao.DeleteOwnerHostname(
"hostname1",
"test1",
)
s.NoError(err)

// then
s.Equal(0, s.countRows(baseOwnerHostsTableName))
}

func sleep() {
Expand All @@ -115,10 +186,10 @@ func (s *daoTestSuite) truncateTable(table string) {
s.NoError(err)
}

func (s *daoTestSuite) countHosts() int {
s.optimizeFinal()
func (s *daoTestSuite) countRows(tableName string) int {
s.optimizeFinal(tableName)

query := fmt.Sprintf("SELECT count(*) FROM %v%v ", s.dao.prefix, baseHostsTableName)
query := fmt.Sprintf("SELECT count(*) FROM %v%v", s.dao.prefix, tableName)
rows, err := s.dao.conn.Query(context.Background(), query)
s.NoError(err)
defer rows.Close()
Expand All @@ -135,8 +206,40 @@ func (s *daoTestSuite) countHosts() int {
return int(result)
}

func (s *daoTestSuite) optimizeFinal() {
query := fmt.Sprintf("optimize table %v%v final", s.dao.prefix, baseHostsTableName)
func (s *daoTestSuite) optimizeFinal(tableName string) {
query := fmt.Sprintf("optimize table %v%v final", s.dao.prefix, tableName)
err := s.dao.conn.Exec(context.Background(), query)
s.NoError(err)
}

func (s *daoTestSuite) selectColumnString(columnName, tableName, whereClause string) string {
var value string
s.selectColumn(columnName, tableName, whereClause, &value)
return value
}

func (s *daoTestSuite) selectColumnTime(columnName, tableName, whereClause string) time.Time {
var value time.Time
s.selectColumn(columnName, tableName, whereClause, &value)
return value
}

func (s *daoTestSuite) selectColumn(columnName, tableName, whereClause string, value any) {
s.optimizeFinal(tableName)

query := fmt.Sprintf("SELECT %v FROM %v%v %v", columnName, s.dao.prefix, tableName, whereClause)
rows, err := s.dao.conn.Query(context.Background(), query)
s.NoError(err)
defer rows.Close()

if !rows.Next() {
return
}
err = rows.Scan(value)
s.NoError(err)
}

// EqualTime assert that two times are the same truncated to seconds
func (s *daoTestSuite) EqualTime(expected, actual time.Time) {
s.Equal(expected.Truncate(time.Second).UnixMilli(), actual.UnixMilli())
}
25 changes: 4 additions & 21 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,10 @@ go 1.21
require (
github.com/ClickHouse/clickhouse-go/v2 v2.10.1
github.com/eapache/go-resiliency v1.3.1-0.20230202171514-83b926b9feca
github.com/golang/mock v1.3.1
github.com/martinlindhe/base36 v1.1.1
github.com/mileusna/useragent v1.3.3
github.com/robfig/cron/v3 v3.0.1
github.com/rs/cors v1.9.0
github.com/stretchr/testify v1.8.4
github.com/ua-parser/uap-go v0.0.0-20211112212520-00c877edfe0f
Expand All @@ -17,32 +19,13 @@ require (
)

require (
github.com/cilium/ebpf v0.11.0 // indirect
github.com/codemodus/kace v0.5.1 // indirect
github.com/cosiner/argv v0.1.0 // indirect
github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect
github.com/derekparker/trie v0.0.0-20230829180723-39f4de51ef7d // indirect
github.com/fatih/color v1.15.0 // indirect
github.com/go-delve/delve v1.21.0 // indirect
github.com/go-delve/liner v1.2.3-0.20220127212407-d32d89dd2a5d // indirect
github.com/google/go-dap v0.11.0 // indirect
github.com/hashicorp/golang-lru v1.0.2 // indirect
github.com/inconshreveable/mousetrap v1.1.0 // indirect
github.com/jinzhu/inflection v1.0.0 // indirect
github.com/kr/text v0.2.0 // indirect
github.com/mattn/go-colorable v0.1.13 // indirect
github.com/mattn/go-isatty v0.0.19 // indirect
github.com/mattn/go-runewidth v0.0.15 // indirect
github.com/oschwald/maxminddb-golang v1.11.0 // indirect
github.com/rivo/uniseg v0.4.4 // indirect
github.com/robfig/cron/v3 v3.0.1 // indirect
github.com/russross/blackfriday/v2 v2.1.0 // indirect
github.com/shurcooL/sanitized_anchor_name v1.0.0 // indirect
github.com/sirupsen/logrus v1.9.3 // indirect
github.com/spf13/cobra v1.7.0 // indirect
github.com/spf13/pflag v1.0.5 // indirect
go.starlark.net v0.0.0-20230925163745-10651d5192ab // indirect
golang.org/x/arch v0.5.0 // indirect
golang.org/x/exp v0.0.0-20230905200255-921286631fa9 // indirect
golang.org/x/net v0.12.0 // indirect
golang.org/x/text v0.11.0 // indirect
Expand All @@ -55,9 +38,9 @@ require (
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/go-faster/city v1.0.1 // indirect
github.com/go-faster/errors v0.6.1 // indirect
github.com/google/uuid v1.3.0 // indirect
github.com/google/uuid v1.3.0
github.com/kelseyhightower/envconfig v1.4.0
github.com/klauspost/compress v1.16.7 // indirect
github.com/klauspost/compress v1.16.7
github.com/oschwald/geoip2-golang v1.9.0
github.com/paulmach/orb v0.10.0 // indirect
github.com/pierrec/lz4/v4 v4.1.18 // indirect
Expand Down
Loading