Skip to content

Commit

Permalink
Merge pull request #16 from NETWAYS/chore/tests
Browse files Browse the repository at this point in the history
Add basic unittests for SQL operations
  • Loading branch information
martialblog authored Sep 16, 2024
2 parents 02d03bd + fd369c7 commit b44972b
Show file tree
Hide file tree
Showing 5 changed files with 154 additions and 8 deletions.
6 changes: 0 additions & 6 deletions cleanup.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,6 @@ func (t Table) OldestTime(db *sql.DB, instanceID int) (ts time.Time, err error)
query := fmt.Sprintf("SELECT %s FROM %s%s WHERE instance_id = ? ORDER BY %s ASC LIMIT 1", //nolint:gosec
t.TimeColumn, IcingaPrefix, t.Name, t.TimeColumn)

// log.Debugf("running query: %s - [%d]", query, instanceID)

row := db.QueryRow(query, instanceID)

var tsString string
Expand Down Expand Up @@ -72,8 +70,6 @@ func (t Table) Cleanup(db *sql.DB, instanceID int, since time.Time, limit int) (
query := fmt.Sprintf("DELETE FROM %s%s WHERE instance_id = ? AND %s < ? LIMIT %d", //nolint:gosec
IcingaPrefix, t.Name, t.TimeColumn, limit)

// log.Debugf("running query: %s - [%d %s]", query, instanceID, since)

result, err := db.Exec(query, instanceID, since)
if err != nil {
err = fmt.Errorf("could not purge rows for %s: %w", t.Name, err)
Expand All @@ -88,8 +84,6 @@ func (t Table) Count(db *sql.DB, instanceID int, since time.Time) (rows int64, e
query := fmt.Sprintf("SELECT count(*) FROM %s%s WHERE instance_id = ? AND %s < ?", //nolint:gosec
IcingaPrefix, t.Name, t.TimeColumn)

// log.Debugf("running query: %s - [%d %s]", query, instanceID, since)

row := db.QueryRow(query, instanceID, since)

err = row.Scan(&rows)
Expand Down
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ module github.com/NETWAYS/ido-cleanup
go 1.21

require (
github.com/DATA-DOG/go-sqlmock v1.5.2
github.com/go-sql-driver/mysql v1.8.1
github.com/spf13/pflag v1.0.5
)
Expand Down
3 changes: 3 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA=
filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4=
github.com/DATA-DOG/go-sqlmock v1.5.2 h1:OcvFkGmslmlZibjAjaHm3L//6LiuBgolP7OputlJIzU=
github.com/DATA-DOG/go-sqlmock v1.5.2/go.mod h1:88MAG/4G7SMwSE3CeA0ZKzrT5CiOU3OJ+JlNzwDqpNU=
github.com/go-sql-driver/mysql v1.8.1 h1:LedoTUt/eveggdHS9qUFC1EFSa8bU2+1pZjSRpvNJ1Y=
github.com/go-sql-driver/mysql v1.8.1/go.mod h1:wEBSXgmK//2ZFJyE+qWnIsVGmvmEKlqwuVSjsCm7DZg=
github.com/kisielk/sqlstruct v0.0.0-20201105191214-5f3e10d3ab46/go.mod h1:yyMNCyc/Ib3bDTKd379tNMpB/7/H5TjM2Y9QJ5THLbE=
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
5 changes: 3 additions & 2 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ func main() {
db.SetConnMaxLifetime(time.Minute * 15)

// Load instance ID
instanceID, err := getInstanceID(db)
instanceID, err := getInstanceID(db, instance)
if err != nil {
_ = db.Close()

Expand Down Expand Up @@ -161,6 +161,7 @@ func handleArguments() {
pflag.PrintDefaults()
}

// knownTables is a slice of Table structs
for _, table := range knownTables {
age := uint(0)
if v, ok := defaultAges[table.Name]; ok {
Expand Down Expand Up @@ -249,7 +250,7 @@ func runCleanup(db *sql.DB, instanceID int, logger *slog.Logger) (busy bool) {
return
}

func getInstanceID(db *sql.DB) (id int, err error) {
func getInstanceID(db *sql.DB, instance string) (id int, err error) {
row := db.QueryRow("SELECT instance_id FROM icinga_instances WHERE instance_name = ?", instance)

err = row.Scan(&id)
Expand Down
147 changes: 147 additions & 0 deletions main_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
package main

import (
"testing"
"time"

"github.com/DATA-DOG/go-sqlmock"
)

func TestGetInstanceID_WithOK(t *testing.T) {
db, mock, err := sqlmock.New()
if err != nil {
t.Fatalf("an error '%s' was not expected when opening a stub database connection", err)
}
defer db.Close()

expected := 1

rows := sqlmock.NewRows([]string{"instance_id"}).
AddRow(expected)

mock.ExpectQuery("SELECT instance_id FROM icinga_instances WHERE instance_name = ?").WillReturnRows(rows)

id, err := getInstanceID(db, "default")

if err != nil {
t.Errorf("error was not expected while getting instance: %s", err)
}

if err := mock.ExpectationsWereMet(); err != nil {
t.Errorf("there were unfulfilled expectations: %s", err)
}

if id != expected {
t.Errorf("actual: %d, expected: %d", id, expected)
}
}

func TestGetInstanceID_WithError(t *testing.T) {
db, mock, err := sqlmock.New()
if err != nil {
t.Fatalf("an error '%s' was not expected when opening a stub database connection", err)
}
defer db.Close()

_, DbErr := getInstanceID(db, "default")

if err != nil {
t.Errorf("error was not expected while getting instance: %s", err)
}

if err := mock.ExpectationsWereMet(); err != nil {
t.Errorf("there were unfulfilled expectations: %s", err)
}

if DbErr == nil {
t.Errorf("expected an error got nil")
}
}

func TestOldestTime_WithOK(t *testing.T) {
db, mock, err := sqlmock.New()
if err != nil {
t.Fatalf("an error '%s' was not expected when opening a stub database connection", err)
}
defer db.Close()

expected := "2024-07-02 08:25:44"
rows := sqlmock.NewRows([]string{"start_time"}).
AddRow(expected)

mock.ExpectQuery("SELECT start_time FROM icinga_notifications WHERE (.+) ORDER BY start_time ASC LIMIT 1").WillReturnRows(rows)

table := Table{"notifications", "start_time"}
oldest, err := table.OldestTime(db, 1)

if "2024-07-02 08:25:44 +0000 UTC" != oldest.String() {
t.Errorf("returned timestamp not expected: %s", oldest.String())
}

if err != nil {
t.Errorf("error was not expected while getting oldest time: %s", err)
}

if err := mock.ExpectationsWereMet(); err != nil {
t.Errorf("there were unfulfilled expectations: %s", err)
}
}

func TestCleanup_WithOK(t *testing.T) {
db, mock, err := sqlmock.New()
if err != nil {
t.Fatalf("an error '%s' was not expected when opening a stub database connection", err)
}
defer db.Close()

ts := time.Now()
mock.ExpectExec("DELETE FROM icinga_notifications WHERE (.+) AND start_time (.+) LIMIT 10").
WithArgs(1, ts).
WillReturnResult(sqlmock.NewResult(1, 1))

table := Table{"notifications", "start_time"}
r, err := table.Cleanup(db, 1, ts, 10)

if 1 != r {
t.Errorf("returned rows not expected: %d", r)
}

if err != nil {
t.Errorf("error was not expected while cleanup: %s", err)
}

if err := mock.ExpectationsWereMet(); err != nil {
t.Errorf("there were unfulfilled expectations: %s", err)
}
}

func TestCount_WithOK(t *testing.T) {
db, mock, err := sqlmock.New()
if err != nil {
t.Fatalf("an error '%s' was not expected when opening a stub database connection", err)
}
defer db.Close()

rows := sqlmock.NewRows([]string{"count(*)"}).
AddRow(123)

ts := time.Now()
mock.ExpectQuery("SELECT count(.+) FROM icinga_notifications WHERE instance_id = (.+) AND start_time < (.+)").
WithArgs(1, ts).
WillReturnRows(rows)

table := Table{"notifications", "start_time"}
r, err := table.Count(db, 1, ts)

if 123 != r {
t.Errorf("returned rows not expected: %d", r)
}

if err != nil {
t.Errorf("error was not expected while cleanup: %s", err)
}

if err := mock.ExpectationsWereMet(); err != nil {
t.Errorf("there were unfulfilled expectations: %s", err)
}
}

0 comments on commit b44972b

Please sign in to comment.