[#7] mclock: Add tag stat

Signed-off-by: Dmitrii Stepanov <d.stepanov@yadro.com>
This commit is contained in:
Dmitrii Stepanov 2025-02-18 15:36:58 +03:00 committed by Evgenii Stratonikov
parent cafa869fea
commit 25102d1e1a
3 changed files with 214 additions and 2 deletions

View file

@ -39,6 +39,21 @@ func TestMClockSharesScheduling(t *testing.T) {
releases = append(releases, release)
}
stats := q.Stats()
require.Equal(t, 2, len(stats))
for _, s := range stats {
switch s.Tag() {
case "class1":
require.Equal(t, uint64(1), s.InProgress())
require.Equal(t, uint64(reqCount/2-1), s.Pending())
case "class2":
require.Equal(t, uint64(0), s.InProgress())
require.Equal(t, uint64(reqCount/2), s.Pending())
default:
require.Fail(t, "unknown tag:"+s.Tag())
}
}
var result []string
var wg sync.WaitGroup
for i := 0; i < reqCount; i++ {
@ -52,6 +67,21 @@ func TestMClockSharesScheduling(t *testing.T) {
}
wg.Wait()
stats = q.Stats()
require.Equal(t, 2, len(stats))
for _, s := range stats {
switch s.Tag() {
case "class1":
require.Equal(t, uint64(0), s.InProgress())
require.Equal(t, uint64(0), s.Pending())
case "class2":
require.Equal(t, uint64(0), s.InProgress())
require.Equal(t, uint64(0), s.Pending())
default:
require.Fail(t, "unknown tag:"+s.Tag())
}
}
// Requests must be scheduled as class1->class1->class2->class1->class1->class2...,
// because the ratio is 2 to 1.
// However, there may be deviations due to rounding and sorting.
@ -116,7 +146,37 @@ func TestMClockRequestCancel(t *testing.T) {
require.Equal(t, 0, q.limitQueue.Len())
require.Equal(t, 0, q.reservationQueue.Len())
stats := q.Stats()
require.Equal(t, 2, len(stats))
for _, s := range stats {
switch s.Tag() {
case "class1":
require.Equal(t, uint64(1), s.InProgress())
require.Equal(t, uint64(0), s.Pending())
case "class2":
require.Equal(t, uint64(0), s.InProgress())
require.Equal(t, uint64(0), s.Pending())
default:
require.Fail(t, "unknown tag:"+s.Tag())
}
}
release1()
stats = q.Stats()
require.Equal(t, 2, len(stats))
for _, s := range stats {
switch s.Tag() {
case "class1":
require.Equal(t, uint64(0), s.InProgress())
require.Equal(t, uint64(0), s.Pending())
case "class2":
require.Equal(t, uint64(0), s.InProgress())
require.Equal(t, uint64(0), s.Pending())
default:
require.Fail(t, "unknown tag:"+s.Tag())
}
}
}
func TestMClockLimitScheduling(t *testing.T) {
@ -159,6 +219,21 @@ func TestMClockLimitScheduling(t *testing.T) {
}
}
stats := q.Stats()
require.Equal(t, 2, len(stats))
for _, s := range stats {
switch s.Tag() {
case "class1":
require.Equal(t, uint64(0), s.InProgress())
require.Equal(t, uint64(reqCount/2), s.Pending())
case "class2":
require.Equal(t, uint64(0), s.InProgress())
require.Equal(t, uint64(reqCount/2), s.Pending())
default:
require.Fail(t, "unknown tag:"+s.Tag())
}
}
cl.v = math.MaxFloat64
var result []string
@ -202,6 +277,21 @@ func TestMClockLimitScheduling(t *testing.T) {
require.Equal(t, 0, q.sharesQueue.Len())
require.Equal(t, 0, q.limitQueue.Len())
require.Equal(t, 0, q.reservationQueue.Len())
stats = q.Stats()
require.Equal(t, 2, len(stats))
for _, s := range stats {
switch s.Tag() {
case "class1":
require.Equal(t, uint64(0), s.InProgress())
require.Equal(t, uint64(0), s.Pending())
case "class2":
require.Equal(t, uint64(0), s.InProgress())
require.Equal(t, uint64(0), s.Pending())
default:
require.Fail(t, "unknown tag:"+s.Tag())
}
}
}
func TestMClockReservationScheduling(t *testing.T) {
@ -245,9 +335,39 @@ func TestMClockReservationScheduling(t *testing.T) {
}
}
stats := q.Stats()
require.Equal(t, 2, len(stats))
for _, s := range stats {
switch s.Tag() {
case "class1":
require.Equal(t, uint64(0), s.InProgress())
require.Equal(t, uint64(reqCount/2), s.Pending())
case "class2":
require.Equal(t, uint64(0), s.InProgress())
require.Equal(t, uint64(reqCount/2), s.Pending())
default:
require.Fail(t, "unknown tag:"+s.Tag())
}
}
cl.v = 1.00001 // 1s elapsed
q.scheduleRequest()
stats = q.Stats()
require.Equal(t, 2, len(stats))
for _, s := range stats {
switch s.Tag() {
case "class1":
require.Equal(t, uint64(0), s.InProgress())
require.Equal(t, uint64(reqCount/2), s.Pending())
case "class2":
require.Equal(t, uint64(100), s.InProgress())
require.Equal(t, uint64(reqCount/2-100), s.Pending())
default:
require.Fail(t, "unknown tag:"+s.Tag())
}
}
var result []string
for i, req := range requests {
select {
@ -263,6 +383,21 @@ func TestMClockReservationScheduling(t *testing.T) {
require.Equal(t, "class2", res)
}
stats = q.Stats()
require.Equal(t, 2, len(stats))
for _, s := range stats {
switch s.Tag() {
case "class1":
require.Equal(t, uint64(0), s.InProgress())
require.Equal(t, uint64(reqCount/2), s.Pending())
case "class2":
require.Equal(t, uint64(0), s.InProgress())
require.Equal(t, uint64(reqCount/2-100), s.Pending())
default:
require.Fail(t, "unknown tag:"+s.Tag())
}
}
cl.v = math.MaxFloat64
q.scheduleRequest()
@ -270,6 +405,21 @@ func TestMClockReservationScheduling(t *testing.T) {
require.Equal(t, 0, q.sharesQueue.Len())
require.Equal(t, 0, q.limitQueue.Len())
require.Equal(t, 0, q.reservationQueue.Len())
stats = q.Stats()
require.Equal(t, 2, len(stats))
for _, s := range stats {
switch s.Tag() {
case "class1":
require.Equal(t, uint64(reqCount/2), s.InProgress())
require.Equal(t, uint64(0), s.Pending())
case "class2":
require.Equal(t, uint64(reqCount/2-100), s.InProgress())
require.Equal(t, uint64(0), s.Pending())
default:
require.Fail(t, "unknown tag:"+s.Tag())
}
}
}
func TestMClockIdleTag(t *testing.T) {