Skip to content

Commit

Permalink
Add integration test.
Browse files Browse the repository at this point in the history
  • Loading branch information
AlekSi committed Jun 22, 2017
1 parent d3fa2fa commit 62d6e97
Show file tree
Hide file tree
Showing 7 changed files with 126 additions and 30 deletions.
19 changes: 16 additions & 3 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,13 +1,26 @@
sudo: false
dist: trusty
sudo: required
language: go
group: edge

go:
- 1.7.x
- 1.8.x
- tip

env:
- PROXYSQL_IMAGE=percona/proxysql:1.2.1
- PROXYSQL_IMAGE=perconalab/proxysql:1.3.6

services:
- docker

before_script:
- docker --version
- docker-compose --version
- docker-compose up -d

script:
- make
- make format build testall

after_success:
- bash <(curl -s https://codecov.io/bash)
7 changes: 5 additions & 2 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,14 @@ The easiest way to make a local development setup is to use Docker Compose.

```
docker-compose up
<wait>
mysql --host=127.0.0.1 --port=16032 --user=admin --password=admin < proxysql.sql
make all testall
export DATA_SOURCE_NAME='admin:admin@tcp(127.0.0.1:16032)/'
./proxysql_exporter
```

`testall` make target will run integration test and also leave ProxySQL inside Docker container in configured state.


## Vendoring

We use [Glide](https://glide.sh) to vendor dependencies. Please use released version of Glide (i.e. do not `go get`
Expand Down
6 changes: 5 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,11 @@ style:

test:
@echo ">> running tests"
@$(GO) test -short -race -coverprofile coverage.txt $(pkgs)
@$(GO) test -v -short -race -coverprofile coverage.txt $(pkgs)

testall:
@echo ">> running all tests"
@$(GO) test -v -race -coverprofile coverage.txt $(pkgs)

format:
@echo ">> formatting code"
Expand Down
4 changes: 2 additions & 2 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
# see CONTRIBUTING.md
---
version: '3'
services:
proxysql:
# image: percona/proxysql
image: perconalab/proxysql:1.3.6
image: ${PROXYSQL_IMAGE:-perconalab/proxysql:1.3.6}
environment:
# those environment variables are not actually required by ProxySQL, but entrypoint erroneously checks them
- CLUSTER_NAME=dummy
Expand Down
13 changes: 9 additions & 4 deletions exporter.go
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,14 @@ func (e *Exporter) Collect(ch chan<- prometheus.Metric) {
e.proxysqlUp.Collect(ch)
}

func (e *Exporter) db() (*sql.DB, error) {
db, err := sql.Open("mysql", e.dsn)
if err == nil {
err = db.Ping()
}
return db, err
}

func (e *Exporter) scrape(ch chan<- prometheus.Metric) {
e.scrapesTotal.Inc()
var err error
Expand All @@ -121,10 +129,7 @@ func (e *Exporter) scrape(ch chan<- prometheus.Metric) {
}
}(time.Now())

db, err := sql.Open("mysql", e.dsn)
if err == nil {
err = db.Ping()
}
db, err := e.db()
if err != nil {
log.Errorln("Error opening connection to ProxySQL:", err)
e.proxysqlUp.Set(0)
Expand Down
93 changes: 89 additions & 4 deletions exporter_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import (
"regexp"
"strings"
"testing"
"time"

"github.com/prometheus/client_golang/prometheus"
dto "github.com/prometheus/client_model/go"
Expand Down Expand Up @@ -107,7 +108,7 @@ func TestScrapeMySQLGlobal(t *testing.T) {
close(ch)
}()

counterExpected := []*metricResult{
counterExpected := []metricResult{
{"proxysql_mysql_status_active_transactions", labelMap{}, 3, dto.MetricType_GAUGE},
{"proxysql_mysql_status_backend_query_time_nsec", labelMap{}, 76355784684851, dto.MetricType_UNTYPED},
{"proxysql_mysql_status_client_connections_aborted", labelMap{}, 0, dto.MetricType_COUNTER},
Expand All @@ -117,7 +118,7 @@ func TestScrapeMySQLGlobal(t *testing.T) {
}
convey.Convey("Metrics comparison", t, convey.FailureContinues, func() {
for _, expect := range counterExpected {
got := readMetric(<-ch)
got := *readMetric(<-ch)
convey.So(got, convey.ShouldResemble, expect)
}
})
Expand Down Expand Up @@ -159,7 +160,7 @@ func TestScrapeMySQLConnectionPool(t *testing.T) {
close(ch)
}()

counterExpected := []*metricResult{
counterExpected := []metricResult{
{"proxysql_connection_pool_status", labelMap{"hostgroup": "0", "endpoint": "10.91.142.80:3306"}, 1, dto.MetricType_GAUGE},
{"proxysql_connection_pool_conn_used", labelMap{"hostgroup": "0", "endpoint": "10.91.142.80:3306"}, 0, dto.MetricType_GAUGE},
{"proxysql_connection_pool_conn_free", labelMap{"hostgroup": "0", "endpoint": "10.91.142.80:3306"}, 45, dto.MetricType_GAUGE},
Expand Down Expand Up @@ -202,7 +203,7 @@ func TestScrapeMySQLConnectionPool(t *testing.T) {
}
convey.Convey("Metrics comparison", t, convey.FailureContinues, func() {
for _, expect := range counterExpected {
got := readMetric(<-ch)
got := *readMetric(<-ch)
convey.So(got, convey.ShouldResemble, expect)
}
})
Expand All @@ -212,3 +213,87 @@ func TestScrapeMySQLConnectionPool(t *testing.T) {
t.Errorf("there were unfulfilled expectations: %s", err)
}
}

func TestExporter(t *testing.T) {
if testing.Short() {
t.Skip("-short is passed, skipping integration test")
}

// wait up to 30 seconds for ProxySQL to become available
exporter := NewExporter("admin:admin@tcp(127.0.0.1:16032)/", true, true)
for i := 0; i < 30; i++ {
db, err := exporter.db()
if err != nil {
time.Sleep(time.Second)
continue
}

// configure ProxySQL
for _, q := range strings.Split(`
DELETE FROM mysql_servers;
INSERT INTO mysql_servers(hostgroup_id, hostname, port) VALUES (1, 'mysql', 3306);
INSERT INTO mysql_servers(hostgroup_id, hostname, port) VALUES (1, 'percona-server', 3306);
LOAD MYSQL SERVERS TO RUNTIME;
SAVE MYSQL SERVERS TO DISK;
DELETE FROM mysql_users;
INSERT INTO mysql_users(username, password, default_hostgroup) VALUES ('root', '', 1);
INSERT INTO mysql_users(username, password, default_hostgroup) VALUES ('monitor', 'monitor', 1);
LOAD MYSQL USERS TO RUNTIME;
SAVE MYSQL USERS TO DISK;
`, ";") {
q = strings.TrimSpace(q)
if q == "" {
continue
}
_, err = db.Exec(q)
if err != nil {
t.Fatalf("Failed to execute %q\n%s", q, err)
}
}
break
}

convey.Convey("Metrics descriptions", t, convey.FailureContinues, func() {
ch := make(chan *prometheus.Desc)
go func() {
exporter.Describe(ch)
close(ch)
}()

descs := make(map[string]struct{})
for d := range ch {
descs[d.String()] = struct{}{}
}

convey.So(descs, convey.ShouldContainKey,
`Desc{fqName: "proxysql_connection_pool_latency_us", help: "The currently ping time in microseconds, as reported from Monitor.", constLabels: {}, variableLabels: [hostgroup endpoint]}`)
})

convey.Convey("Metrics data", t, convey.FailureContinues, func() {
ch := make(chan prometheus.Metric)
go func() {
exporter.Collect(ch)
close(ch)
}()

var metrics []metricResult
for m := range ch {
got := *readMetric(m)
got.value = 0 // ignore actual values in comparison for now
metrics = append(metrics, got)
}

for _, m := range metrics {
convey.So(m.name, convey.ShouldEqual, strings.ToLower(m.name))
for k := range m.labels {
convey.So(k, convey.ShouldEqual, strings.ToLower(k))
}
}

convey.So(metricResult{"proxysql_connection_pool_latency_us", labelMap{"hostgroup": "1", "endpoint": "mysql:3306"}, 0, dto.MetricType_GAUGE},
convey.ShouldBeIn, metrics)
convey.So(metricResult{"proxysql_connection_pool_latency_us", labelMap{"hostgroup": "1", "endpoint": "percona-server:3306"}, 0, dto.MetricType_GAUGE},
convey.ShouldBeIn, metrics)
})
}
14 changes: 0 additions & 14 deletions proxysql.sql

This file was deleted.

0 comments on commit 62d6e97

Please sign in to comment.