Skip to content

Commit

Permalink
feat: add unit tests for creating historical counter
Browse files Browse the repository at this point in the history
  • Loading branch information
mgierada committed Jun 7, 2024
1 parent 66ee06e commit 75e9dfa
Show file tree
Hide file tree
Showing 5 changed files with 95 additions and 11 deletions.
11 changes: 8 additions & 3 deletions server/db/create_historical_counter.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,21 @@ import (
"log"
)

func CreateHistoricalCounter(lastValue int) error {
func CreateHistoricalCounter(tableName string, lastValue int) error {
if lastValue <= 0 {
message := fmt.Sprintf("❌ Error creating new historical counter. Value must be greater than 0. Received: %d", lastValue)
log.Printf(message)
return nil
}
newCounterId := uuid.New().String()
_, err := db.Exec("INSERT INTO historical_counters (counter_id, value) VALUES ($1, $2)", newCounterId, lastValue)
rawInsertQuery := `
INSERT INTO %s (counter_id, value)
VALUES ('%s', %d);
`
insertQuery := fmt.Sprintf(rawInsertQuery, tableName, newCounterId, lastValue)
_, err := db.Exec(insertQuery)
if err != nil {
message := fmt.Sprintf("❌ Error inserting new historical counter row.\n %s", err)
message := fmt.Sprintf("❌ Error inserting new %s row.\n %s", tableName, err)
log.Fatalf(message)
return fmt.Errorf(message)
}
Expand Down
76 changes: 73 additions & 3 deletions server/db/db_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@ import (

var postgresContainer testcontainers.Container

/*
Setup
*/
func TestMain(m *testing.M) {
// Setup before running tests
if err := setup(); err != nil {
Expand Down Expand Up @@ -140,6 +143,9 @@ func teardown() error {
return postgresContainer.Terminate(context.Background())
}

/*
Test Cases
*/
func TestGetCounter(t *testing.T) {
// Insert a row into the counter table
tableName := utils.TableInstance.Counter
Expand Down Expand Up @@ -386,6 +392,7 @@ func TestUpdateCounterTimeDidNotPass(t *testing.T) {
// NOTE: Counter has some value, resetting, should be zero now.
func TestResetCounter(t *testing.T) {

tableName := utils.TableInstance.Counter
_, err := db.Exec(`
INSERT INTO counter (current_value, is_locked, updated_at, reseted_at)
VALUES (42, false, '2024-05-30 12:34:56', '2024-05-01 12:00:00')
Expand Down Expand Up @@ -439,9 +446,7 @@ func TestResetCounter(t *testing.T) {
}

// Cleanup table after test
if _, err = db.Exec(`DELETE FROM counter`); err != nil {
t.Fatalf("failed to clean up table: %s", err)
}
cleanupTable(t, tableName)
}

func TestGetOhnoCounter(t *testing.T) {
Expand Down Expand Up @@ -687,3 +692,68 @@ func TestUpdateOhnoCounterTimeDidNotPass(t *testing.T) {
// Cleanup table after test
cleanupTable(t, tableName)
}

// NOTE: Test covers a situation when counter has some values and we create a historical counter
// by recording ohno event
func TestCreatHistoricalCounter(t *testing.T) {

// Insert a row into the counter table
counterTableName := utils.TableInstance.Counter
historicalCounterTableName := utils.TableInstance.HistoricalCounter
rawInsertQuery := `
INSERT INTO %s (current_value, is_locked, updated_at, reseted_at)
VALUES
(42, false, '2024-05-30 12:34:56', '2024-05-01 12:00:00');`
insertQuery := fmt.Sprintf(rawInsertQuery, counterTableName)

_, err := db.Exec(insertQuery)
if err != nil {
t.Fatalf("failed to insert into table: %s, err: %s", counterTableName, err)
}

// Reset the counter
lastValue, err := ResetCounter()
if err != nil {
t.Fatalf("failed to reset counter data: %s", err)
}

// Create historical counter entry
CreateHistoricalCounter(historicalCounterTableName, lastValue)

// Get historical counter
historicalCounter, err := GetHistoricalCounters(historicalCounterTableName)
if err != nil {
t.Fatalf("failed to get %s: %s", historicalCounterTableName, err)
}

// Check updated_at and created_at should be close to current time
expectedTime := time.Now().UTC()
parsedUpdatedAtTime, err := time.Parse(time.RFC3339, historicalCounter[0].UpdatedAt)
if err != nil {
t.Fatalf("failed to parse updated_at: %s", err)
}
parsedCreatedAtTime, err := time.Parse(time.RFC3339, historicalCounter[0].CreatedAt)
if err != nil {
t.Fatalf("failed to parse created_at: %s", err)
}

// Assert historical counter was created and it is a list
if len(historicalCounter) != 1 {
t.Fatalf("expected 1 historical counter, got %d", len(historicalCounter))
}
if historicalCounter[0].Value != 42 {
t.Fatalf("expected value to be 42, got %d", historicalCounter[0].Value)
}
// Allow for a small time difference (e.g., 5 seconds)
if expectedTime.Sub(parsedUpdatedAtTime).Seconds() > 5 {
t.Errorf("expected updated_at to be close to '%s', got '%s'", expectedTime, historicalCounter[0].UpdatedAt)
}
// Allow for a small time difference (e.g., 5 seconds)
if expectedTime.Sub(parsedCreatedAtTime).Seconds() > 5 {
t.Errorf("expected updated_at to be close to '%s', got '%s'", expectedTime, historicalCounter[0].UpdatedAt)
}

// Cleanup table after test
cleanupTable(t, counterTableName)
cleanupTable(t, historicalCounterTableName)
}
13 changes: 10 additions & 3 deletions server/db/get_historical_counter.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,19 @@ type HistoricalCounter struct {
Value int
}

func GetHistoricalCounters() ([]HistoricalCounter, error) {
func GetHistoricalCounters(tableName string) ([]HistoricalCounter, error) {

rawQuery := `
SELECT
counter_id, updated_at, created_at, value
FROM
%s;
`
query := fmt.Sprintf(rawQuery, tableName)

query := "SELECT counter_id, updated_at, created_at, value FROM historical_counters"
rows, err := db.Query(query)
if err != nil {
return nil, fmt.Errorf("❌ Error querying historical_counters table.\n %s", err)
return nil, fmt.Errorf("❌ Error querying %s table.\n %s", tableName, err)
}
defer rows.Close()

Expand Down
3 changes: 2 additions & 1 deletion server/handlers/counter.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"log"
"net/http"
"server/db"
"server/utils"
)

func GetCounter(w http.ResponseWriter, r *http.Request) {
Expand Down Expand Up @@ -32,7 +33,7 @@ func GetOhnoCounter(w http.ResponseWriter, r *http.Request) {
func GetHistoricalCounter(w http.ResponseWriter, r *http.Request) {
log.Printf("🔗 received GET /historical request\n")

hCounters, err := db.GetHistoricalCounters()
hCounters, err := db.GetHistoricalCounters(utils.TableInstance.HistoricalCounter)
if err != nil {
log.Fatalf("❌ Error retrieving historical_counter data.\n %s", err)
}
Expand Down
3 changes: 2 additions & 1 deletion server/handlers/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"log"
"net/http"
"server/db"
"server/utils"
)

type ServerResponse struct {
Expand Down Expand Up @@ -38,7 +39,7 @@ func RecordOhNoEvent(w http.ResponseWriter, r *http.Request) {
return
}

err = db.CreateHistoricalCounter(last_value)
err = db.CreateHistoricalCounter(utils.TableInstance.HistoricalCounter, last_value)
if err != nil {
log.Printf("❌ Error creating historical counter.\n %s", err)
http.Error(w, "Error creating historical counter.", http.StatusInternalServerError)
Expand Down

0 comments on commit 75e9dfa

Please sign in to comment.