mirror of
https://github.com/Wei-Shaw/sub2api.git
synced 2026-10-29 00:10:31 +00:00
fix(ops): preserve zero-valued system metrics
This commit is contained in:
@@ -114,37 +114,37 @@ INSERT INTO ops_system_metrics (
|
||||
opsNullFloat64(input.QPS),
|
||||
opsNullFloat64(input.TPS),
|
||||
|
||||
opsNullInt(input.DurationP50Ms),
|
||||
opsNullInt(input.DurationP90Ms),
|
||||
opsNullInt(input.DurationP95Ms),
|
||||
opsNullInt(input.DurationP99Ms),
|
||||
opsNullMetricInt(input.DurationP50Ms),
|
||||
opsNullMetricInt(input.DurationP90Ms),
|
||||
opsNullMetricInt(input.DurationP95Ms),
|
||||
opsNullMetricInt(input.DurationP99Ms),
|
||||
opsNullFloat64(input.DurationAvgMs),
|
||||
opsNullInt(input.DurationMaxMs),
|
||||
opsNullMetricInt(input.DurationMaxMs),
|
||||
|
||||
opsNullInt(input.TTFTP50Ms),
|
||||
opsNullInt(input.TTFTP90Ms),
|
||||
opsNullInt(input.TTFTP95Ms),
|
||||
opsNullInt(input.TTFTP99Ms),
|
||||
opsNullMetricInt(input.TTFTP50Ms),
|
||||
opsNullMetricInt(input.TTFTP90Ms),
|
||||
opsNullMetricInt(input.TTFTP95Ms),
|
||||
opsNullMetricInt(input.TTFTP99Ms),
|
||||
opsNullFloat64(input.TTFTAvgMs),
|
||||
opsNullInt(input.TTFTMaxMs),
|
||||
opsNullMetricInt(input.TTFTMaxMs),
|
||||
|
||||
opsNullFloat64(input.CPUUsagePercent),
|
||||
opsNullInt(input.MemoryUsedMB),
|
||||
opsNullInt(input.MemoryTotalMB),
|
||||
opsNullMetricInt64(input.MemoryUsedMB),
|
||||
opsNullMetricInt64(input.MemoryTotalMB),
|
||||
opsNullFloat64(input.MemoryUsagePercent),
|
||||
|
||||
opsNullBool(input.DBOK),
|
||||
opsNullBool(input.RedisOK),
|
||||
|
||||
opsNullInt(input.RedisConnTotal),
|
||||
opsNullInt(input.RedisConnIdle),
|
||||
opsNullMetricInt(input.RedisConnTotal),
|
||||
opsNullMetricInt(input.RedisConnIdle),
|
||||
|
||||
opsNullInt(input.DBConnActive),
|
||||
opsNullInt(input.DBConnIdle),
|
||||
opsNullInt(input.DBConnWaiting),
|
||||
opsNullMetricInt(input.DBConnActive),
|
||||
opsNullMetricInt(input.DBConnIdle),
|
||||
opsNullMetricInt(input.DBConnWaiting),
|
||||
|
||||
opsNullInt(input.GoroutineCount),
|
||||
opsNullInt(input.ConcurrencyQueueDepth),
|
||||
opsNullMetricInt(input.GoroutineCount),
|
||||
opsNullMetricInt(input.ConcurrencyQueueDepth),
|
||||
)
|
||||
return err
|
||||
}
|
||||
@@ -437,6 +437,20 @@ func opsNullFloat64(v *float64) any {
|
||||
return sql.NullFloat64{Float64: *v, Valid: true}
|
||||
}
|
||||
|
||||
func opsNullMetricInt(v *int) any {
|
||||
if v == nil {
|
||||
return sql.NullInt64{}
|
||||
}
|
||||
return sql.NullInt64{Int64: int64(*v), Valid: true}
|
||||
}
|
||||
|
||||
func opsNullMetricInt64(v *int64) any {
|
||||
if v == nil {
|
||||
return sql.NullInt64{}
|
||||
}
|
||||
return sql.NullInt64{Int64: *v, Valid: true}
|
||||
}
|
||||
|
||||
func opsNullTime(v *time.Time) any {
|
||||
if v == nil || v.IsZero() {
|
||||
return sql.NullTime{}
|
||||
|
||||
@@ -0,0 +1,59 @@
|
||||
package repository
|
||||
|
||||
import (
|
||||
"context"
|
||||
"database/sql/driver"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/DATA-DOG/go-sqlmock"
|
||||
"github.com/Wei-Shaw/sub2api/internal/service"
|
||||
)
|
||||
|
||||
func TestInsertSystemMetricsNullableIntegerMetrics(t *testing.T) {
|
||||
createdAt := time.Date(2026, time.September, 4, 12, 0, 0, 0, time.UTC)
|
||||
zero := 0
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
dbConnActive *int
|
||||
wantDBActive driver.Value
|
||||
}{
|
||||
{name: "explicit zero is preserved", dbConnActive: &zero, wantDBActive: int64(0)},
|
||||
{name: "unavailable metric remains null", dbConnActive: nil, wantDBActive: nil},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
db, mock, err := sqlmock.New()
|
||||
if err != nil {
|
||||
t.Fatalf("sqlmock.New: %v", err)
|
||||
}
|
||||
t.Cleanup(func() { _ = db.Close() })
|
||||
|
||||
args := make([]driver.Value, 40)
|
||||
args[0] = createdAt
|
||||
args[1] = int64(1)
|
||||
for i := 4; i <= 12; i++ {
|
||||
args[i] = int64(0)
|
||||
}
|
||||
args[35] = tt.wantDBActive
|
||||
|
||||
mock.ExpectExec("INSERT INTO ops_system_metrics").
|
||||
WithArgs(args...).
|
||||
WillReturnResult(sqlmock.NewResult(1, 1))
|
||||
|
||||
repo := &opsRepository{db: db}
|
||||
err = repo.InsertSystemMetrics(context.Background(), &service.OpsInsertSystemMetricsInput{
|
||||
CreatedAt: createdAt,
|
||||
DBConnActive: tt.dbConnActive,
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("InsertSystemMetrics: %v", err)
|
||||
}
|
||||
if err := mock.ExpectationsWereMet(); err != nil {
|
||||
t.Fatalf("unmet SQL expectations: %v", err)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user