mirror of
https://github.com/alireza0/s-ui.git
synced 2026-10-20 19:02:09 +00:00
fix reset traffic #1261
Some checks are pending
Release S-UI / test (push) Waiting to run
Release S-UI / build-frontend (push) Blocked by required conditions
Release S-UI / build-386 (push) Blocked by required conditions
Release S-UI / build-amd64 (push) Blocked by required conditions
Release S-UI / build-armv5 (push) Blocked by required conditions
Release S-UI / build-armv6 (push) Blocked by required conditions
Release S-UI / build-armv7 (push) Blocked by required conditions
Release S-UI / build-arm64 (push) Blocked by required conditions
Release S-UI / build-s390x (push) Blocked by required conditions
Release S-UI / build-windows-amd64 (push) Blocked by required conditions
Release S-UI / build-windows-arm64 (push) Blocked by required conditions
Release S-UI / publish (push) Blocked by required conditions
Some checks are pending
Release S-UI / test (push) Waiting to run
Release S-UI / build-frontend (push) Blocked by required conditions
Release S-UI / build-386 (push) Blocked by required conditions
Release S-UI / build-amd64 (push) Blocked by required conditions
Release S-UI / build-armv5 (push) Blocked by required conditions
Release S-UI / build-armv6 (push) Blocked by required conditions
Release S-UI / build-armv7 (push) Blocked by required conditions
Release S-UI / build-arm64 (push) Blocked by required conditions
Release S-UI / build-s390x (push) Blocked by required conditions
Release S-UI / build-windows-amd64 (push) Blocked by required conditions
Release S-UI / build-windows-arm64 (push) Blocked by required conditions
Release S-UI / publish (push) Blocked by required conditions
This commit is contained in:
parent
79df6290f4
commit
bb0f49ac35
2 changed files with 78 additions and 0 deletions
|
|
@ -243,6 +243,13 @@ func (s *ClientService) preserveServerOwnedFields(tx *gorm.DB, client *model.Cli
|
|||
}
|
||||
client.CreatedAt = existing.CreatedAt
|
||||
client.OnlineAt = existing.OnlineAt
|
||||
|
||||
if client.Up == 0 && client.Down == 0 {
|
||||
client.TotalUp = existing.TotalUp + existing.Up
|
||||
client.TotalDown = existing.TotalDown + existing.Down
|
||||
return
|
||||
}
|
||||
|
||||
client.Up = existing.Up
|
||||
client.Down = existing.Down
|
||||
client.TotalUp = existing.TotalUp
|
||||
|
|
|
|||
|
|
@ -190,3 +190,74 @@ func TestClientNameJSONIsValid(t *testing.T) {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
// The counter-preserving guard above also swallowed the panel's reset-usage
|
||||
// button, which is the only legitimate way a form writes these columns: the
|
||||
// zeros it posted were replaced by the stored values, so usage never reset and
|
||||
// a client over its quota was disabled again on the next deplete run. #1261
|
||||
func TestResetUsageThroughTheClientForm(t *testing.T) {
|
||||
db := clientTestDB(t)
|
||||
s := &ClientService{}
|
||||
|
||||
c := createClient(t, db, &model.Client{
|
||||
Name: "someone",
|
||||
Enable: true,
|
||||
Up: 4_000,
|
||||
Down: 6_000,
|
||||
TotalUp: 10_000,
|
||||
TotalDown: 20_000,
|
||||
})
|
||||
|
||||
// What the reset button posts: counters zeroed, everything else as shown.
|
||||
reset := &model.Client{
|
||||
Id: c.Id,
|
||||
Name: "someone",
|
||||
Enable: true,
|
||||
Up: 0,
|
||||
Down: 0,
|
||||
}
|
||||
s.preserveServerOwnedFields(db, reset)
|
||||
|
||||
if reset.Up != 0 || reset.Down != 0 {
|
||||
t.Errorf("reset was discarded: up=%d down=%d, want 0/0", reset.Up, reset.Down)
|
||||
}
|
||||
// The lifetime counters take on what was just cleared.
|
||||
if reset.TotalUp != 14_000 || reset.TotalDown != 26_000 {
|
||||
t.Errorf("totals = %d/%d, want 14000/26000", reset.TotalUp, reset.TotalDown)
|
||||
}
|
||||
}
|
||||
|
||||
// Traffic that arrives while the form is open is counted into the totals, not
|
||||
// lost: the totals come from the stored row, never from the form.
|
||||
func TestResetUsageCountsTrafficArrivingWhileOpen(t *testing.T) {
|
||||
db := clientTestDB(t)
|
||||
s := &ClientService{}
|
||||
|
||||
c := createClient(t, db, &model.Client{
|
||||
Name: "someone",
|
||||
Enable: true,
|
||||
Up: 1_000,
|
||||
Down: 1_000,
|
||||
TotalUp: 500,
|
||||
})
|
||||
|
||||
// The stats job lands after the operator opened the form.
|
||||
if err := db.Model(model.Client{}).Where("id = ?", c.Id).
|
||||
Updates(map[string]any{"up": 3_000, "down": 9_000}).Error; err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
// A form rendered before that, with the totals it computed for itself.
|
||||
reset := &model.Client{
|
||||
Id: c.Id,
|
||||
Name: "someone",
|
||||
Enable: true,
|
||||
TotalUp: 1_500,
|
||||
TotalDown: 1_000,
|
||||
}
|
||||
s.preserveServerOwnedFields(db, reset)
|
||||
|
||||
if reset.TotalUp != 3_500 || reset.TotalDown != 9_000 {
|
||||
t.Errorf("totals = %d/%d, want 3500/9000", reset.TotalUp, reset.TotalDown)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue