storagenode/storagenodedb: fix null at_rest_total values for storage usage

Wrapping a COALESCE around the computed at_rest_total value to fallback
to the original at_rest_total value when the computed value is null.

https://forum.storj.io/t/release-preparation-v1-62/19444/5?u=clement

Change-Id: Ifa268ccbe35a63e3b68f07464194fa034ad261b5
This commit is contained in:
Clement Sam 2022-08-23 12:19:13 +00:00 committed by Igor
parent f35b4163f9
commit bac0155664
2 changed files with 38 additions and 2 deletions

View File

@ -61,7 +61,7 @@ func (db *storageUsageDB) GetDaily(ctx context.Context, satelliteID storj.NodeID
// hour_difference = current row interval_end_time - previous row interval_end_time
// Rows with 0-hour difference are assumed to be 24 hours.
query := `SELECT satellite_id,
24 * (at_rest_total / COALESCE((CAST(strftime('%s', interval_end_time) AS NUMERIC) - CAST(strftime('%s', LAG(interval_end_time) OVER (PARTITION BY satellite_id ORDER BY interval_end_time)) AS NUMERIC)) / 3600, 24)),
COALESCE(24 * (at_rest_total / COALESCE((CAST(strftime('%s', interval_end_time) AS NUMERIC) - CAST(strftime('%s', LAG(interval_end_time) OVER (PARTITION BY satellite_id ORDER BY interval_end_time)) AS NUMERIC)) / 3600, 24)), at_rest_total),
timestamp
FROM storage_usage
WHERE satellite_id = ?
@ -111,7 +111,7 @@ func (db *storageUsageDB) GetDailyTotal(ctx context.Context, from, to time.Time)
query := `SELECT SUM(usages.at_rest_total), usages.timestamp
FROM (
SELECT timestamp,
24 * (at_rest_total / COALESCE((CAST(strftime('%s', interval_end_time) AS NUMERIC) - CAST(strftime('%s', LAG(interval_end_time) OVER (PARTITION BY satellite_id ORDER BY interval_end_time)) AS NUMERIC)) / 3600, 24)) AS at_rest_total
COALESCE(24 * (at_rest_total / COALESCE((CAST(strftime('%s', interval_end_time) AS NUMERIC) - CAST(strftime('%s', LAG(interval_end_time) OVER (PARTITION BY satellite_id ORDER BY interval_end_time)) AS NUMERIC)) / 3600, 24)), at_rest_total) AS at_rest_total
FROM storage_usage
WHERE ? <= timestamp AND timestamp <= ?
) as usages

View File

@ -150,6 +150,42 @@ func TestEmptyStorageUsage(t *testing.T) {
})
}
func TestZeroStorageUsage(t *testing.T) {
storagenodedbtest.Run(t, func(ctx *testcontext.Context, t *testing.T, db storagenode.DB) {
storageUsageDB := db.StorageUsage()
now := time.Now().UTC()
satelliteID := testrand.NodeID()
stamp := storageusage.Stamp{
SatelliteID: satelliteID,
AtRestTotal: 0,
IntervalStart: time.Date(now.Year(), now.Month(), now.Day(), 0, 0, 0, 0, now.Location()),
IntervalEndTime: now,
}
expectedStamp := []storageusage.Stamp{stamp}
t.Run("store", func(t *testing.T) {
err := storageUsageDB.Store(ctx, []storageusage.Stamp{stamp})
assert.NoError(t, err)
})
t.Run("get daily", func(t *testing.T) {
res, err := storageUsageDB.GetDaily(ctx, satelliteID, time.Time{}, now)
assert.NoError(t, err)
assert.Equal(t, len(res), 1)
assert.Equal(t, expectedStamp[0].AtRestTotal, res[0].AtRestTotal)
})
t.Run("get daily total", func(t *testing.T) {
res, err := storageUsageDB.GetDailyTotal(ctx, time.Time{}, now)
assert.NoError(t, err)
assert.Equal(t, len(res), 1)
assert.Equal(t, expectedStamp[0].AtRestTotal, res[0].AtRestTotal)
})
})
}
// makeStorageUsageStamps creates storage usage stamps and expected summaries for provided satellites.
// Creates one entry per day for 30 days with last date as beginning of provided endDate.
func makeStorageUsageStamps(satellites []storj.NodeID, days int, endDate time.Time) ([]storageusage.Stamp, map[storj.NodeID]float64) {