capacity report in terms of offers and tasks
This commit is contained in:
parent
7ccb38f5e6
commit
b184c4c0d2
5 changed files with 912 additions and 1 deletions
|
@ -767,6 +767,8 @@ func TestRealisClient_PartitionPolicy(t *testing.T) {
|
|||
assert.NoError(t, err)
|
||||
}
|
||||
|
||||
err = r.KillJob(job.JobKey())
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
|
||||
func TestRealisClient_UpdateStrategies(t *testing.T) {
|
||||
|
@ -925,3 +927,408 @@ func TestRealisClient_GetJobSummary(t *testing.T) {
|
|||
err = r.KillJob(job.JobKey())
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
|
||||
func TestRealisClient_Offers(t *testing.T) {
|
||||
var offers []realis.Offer
|
||||
|
||||
// since offers are being recycled, it take a few tries to get all of them.
|
||||
i := 0
|
||||
for ; len(offers) < 3 && i < 5; i++ {
|
||||
offers, _ = r.Offers()
|
||||
time.Sleep(5 * time.Second)
|
||||
}
|
||||
|
||||
assert.NotEqual(t, i, 5)
|
||||
}
|
||||
|
||||
func TestRealisClient_MaintenanceHosts(t *testing.T) {
|
||||
offers, err := r.Offers()
|
||||
assert.NoError(t, err)
|
||||
|
||||
for i := 0; i < len(offers); i++ {
|
||||
_, err := r.DrainHosts(offers[i].Hostname)
|
||||
assert.NoError(t, err)
|
||||
|
||||
hosts, err := r.MaintenanceHosts()
|
||||
assert.Equal(t, i+1, len(hosts))
|
||||
}
|
||||
|
||||
// clean up
|
||||
for i := 0; i < len(offers); i++ {
|
||||
_, err := r.EndMaintenance(offers[i].Hostname)
|
||||
assert.NoError(t, err)
|
||||
|
||||
// Monitor change to DRAINING and DRAINED mode
|
||||
_, err = r.MonitorHostMaintenance(
|
||||
[]string{offers[i].Hostname},
|
||||
[]aurora.MaintenanceMode{aurora.MaintenanceMode_NONE},
|
||||
5*time.Second,
|
||||
10*time.Second)
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestRealisClient_AvailOfferReport(t *testing.T) {
|
||||
var offers []realis.Offer
|
||||
|
||||
i := 0
|
||||
for ; len(offers) < 3 && i < 5; i++ {
|
||||
offers, _ = r.Offers()
|
||||
time.Sleep(5 * time.Second)
|
||||
}
|
||||
|
||||
assert.NotEqual(t, i, 3)
|
||||
|
||||
capacity, err := r.AvailOfferReport()
|
||||
assert.NoError(t, err)
|
||||
|
||||
// 2 groups for non-dedicated & dedicated
|
||||
assert.Equal(t, 2, len(capacity))
|
||||
// 4 resources: cpus, disk, mem, ports
|
||||
assert.Equal(t, 4, len(capacity["non-dedicated"]))
|
||||
}
|
||||
|
||||
func TestRealisClient_FitTasks(t *testing.T) {
|
||||
var offers []realis.Offer
|
||||
|
||||
i := 0
|
||||
for ; len(offers) < 3 && i < 5; i++ {
|
||||
offers, _ = r.Offers()
|
||||
time.Sleep(5 * time.Second)
|
||||
}
|
||||
|
||||
assert.NotEqual(t, i, 5)
|
||||
|
||||
cpuPerOffer := 0.0
|
||||
for _, r := range offers[0].Resources {
|
||||
if r.Name == "cpus" {
|
||||
cpuPerOffer = r.Scalar.Value
|
||||
}
|
||||
}
|
||||
|
||||
validCpu := cpuPerOffer / 5
|
||||
inValidCpu := cpuPerOffer + 1
|
||||
gpu := int64(1)
|
||||
|
||||
tests := []struct {
|
||||
message string
|
||||
request aurora.Resource
|
||||
constraints []*aurora.Constraint
|
||||
expected int64
|
||||
isError bool
|
||||
}{
|
||||
{
|
||||
message: "task with gpu request",
|
||||
request: aurora.Resource{
|
||||
NumGpus: &gpu,
|
||||
},
|
||||
expected: 0,
|
||||
isError: false,
|
||||
},
|
||||
{
|
||||
message: "empty resource request",
|
||||
request: aurora.Resource{},
|
||||
expected: -1,
|
||||
isError: true,
|
||||
},
|
||||
{
|
||||
message: "valid resource request",
|
||||
request: aurora.Resource{
|
||||
NumCpus: &validCpu,
|
||||
},
|
||||
expected: 10,
|
||||
isError: false,
|
||||
},
|
||||
{
|
||||
message: "invalid cpu request",
|
||||
request: aurora.Resource{
|
||||
NumCpus: &inValidCpu,
|
||||
},
|
||||
expected: 0,
|
||||
isError: false,
|
||||
},
|
||||
{
|
||||
message: "dedicated constraint",
|
||||
request: aurora.Resource{
|
||||
NumCpus: &validCpu,
|
||||
},
|
||||
constraints: []*aurora.Constraint{
|
||||
{
|
||||
Name: "dedicated",
|
||||
Constraint: &aurora.TaskConstraint{
|
||||
Value: &aurora.ValueConstraint{
|
||||
Negated: false,
|
||||
Values: []string{"vagrant/bar"},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
expected: 5,
|
||||
isError: false,
|
||||
},
|
||||
{
|
||||
message: "value constraint on zone",
|
||||
request: aurora.Resource{
|
||||
NumCpus: &validCpu,
|
||||
},
|
||||
constraints: []*aurora.Constraint{
|
||||
{
|
||||
Name: "zone",
|
||||
Constraint: &aurora.TaskConstraint{
|
||||
Value: &aurora.ValueConstraint{
|
||||
Negated: false,
|
||||
Values: []string{"west"},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
expected: 10,
|
||||
isError: false,
|
||||
},
|
||||
{
|
||||
message: "negative value constraint on zone",
|
||||
request: aurora.Resource{
|
||||
NumCpus: &validCpu,
|
||||
},
|
||||
constraints: []*aurora.Constraint{
|
||||
{
|
||||
Name: "zone",
|
||||
Constraint: &aurora.TaskConstraint{
|
||||
Value: &aurora.ValueConstraint{
|
||||
Negated: true,
|
||||
Values: []string{"west"},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
expected: 0,
|
||||
isError: false,
|
||||
},
|
||||
{
|
||||
message: "negative value constraint on host",
|
||||
request: aurora.Resource{
|
||||
NumCpus: &validCpu,
|
||||
},
|
||||
constraints: []*aurora.Constraint{
|
||||
{
|
||||
Name: "host",
|
||||
Constraint: &aurora.TaskConstraint{
|
||||
Value: &aurora.ValueConstraint{
|
||||
Negated: true,
|
||||
Values: []string{"agent-one"},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
expected: 5,
|
||||
isError: false,
|
||||
},
|
||||
{
|
||||
message: "value constraint on unavailable zone",
|
||||
request: aurora.Resource{
|
||||
NumCpus: &validCpu,
|
||||
},
|
||||
constraints: []*aurora.Constraint{
|
||||
{
|
||||
Name: "zone",
|
||||
Constraint: &aurora.TaskConstraint{
|
||||
Value: &aurora.ValueConstraint{
|
||||
Negated: false,
|
||||
Values: []string{"east"},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
expected: 0,
|
||||
isError: false,
|
||||
},
|
||||
{
|
||||
message: "value constraint on unavailable attribute",
|
||||
request: aurora.Resource{
|
||||
NumCpus: &validCpu,
|
||||
},
|
||||
constraints: []*aurora.Constraint{
|
||||
{
|
||||
Name: "os",
|
||||
Constraint: &aurora.TaskConstraint{
|
||||
Value: &aurora.ValueConstraint{
|
||||
Negated: false,
|
||||
Values: []string{"windows"},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
expected: 0,
|
||||
isError: false,
|
||||
},
|
||||
{
|
||||
message: "1 value constraint with 2 values",
|
||||
request: aurora.Resource{
|
||||
NumCpus: &validCpu,
|
||||
},
|
||||
constraints: []*aurora.Constraint{
|
||||
{
|
||||
Name: "host",
|
||||
Constraint: &aurora.TaskConstraint{
|
||||
Value: &aurora.ValueConstraint{
|
||||
Negated: false,
|
||||
Values: []string{"agent-one", "agent-two"},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
expected: 10,
|
||||
isError: false,
|
||||
},
|
||||
{
|
||||
message: "2 value constraints",
|
||||
request: aurora.Resource{
|
||||
NumCpus: &validCpu,
|
||||
},
|
||||
constraints: []*aurora.Constraint{
|
||||
{
|
||||
Name: "host",
|
||||
Constraint: &aurora.TaskConstraint{
|
||||
Value: &aurora.ValueConstraint{
|
||||
Negated: false,
|
||||
Values: []string{"agent-one"},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "rack",
|
||||
Constraint: &aurora.TaskConstraint{
|
||||
Value: &aurora.ValueConstraint{
|
||||
Negated: false,
|
||||
Values: []string{"2"},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
expected: 0,
|
||||
isError: false,
|
||||
},
|
||||
{
|
||||
message: "limit constraint on host",
|
||||
request: aurora.Resource{
|
||||
NumCpus: &validCpu,
|
||||
},
|
||||
constraints: []*aurora.Constraint{
|
||||
{
|
||||
Name: "host",
|
||||
Constraint: &aurora.TaskConstraint{
|
||||
Limit: &aurora.LimitConstraint{
|
||||
Limit: 1,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
expected: 2,
|
||||
isError: false,
|
||||
},
|
||||
{
|
||||
message: "limit constraint on zone",
|
||||
request: aurora.Resource{
|
||||
NumCpus: &validCpu,
|
||||
},
|
||||
constraints: []*aurora.Constraint{
|
||||
{
|
||||
Name: "zone",
|
||||
Constraint: &aurora.TaskConstraint{
|
||||
Limit: &aurora.LimitConstraint{
|
||||
Limit: 1,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
expected: 1,
|
||||
isError: false,
|
||||
},
|
||||
{
|
||||
message: "limit constraint on zone & host",
|
||||
request: aurora.Resource{
|
||||
NumCpus: &validCpu,
|
||||
},
|
||||
constraints: []*aurora.Constraint{
|
||||
{
|
||||
Name: "host",
|
||||
Constraint: &aurora.TaskConstraint{
|
||||
Limit: &aurora.LimitConstraint{
|
||||
Limit: 1,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "zone",
|
||||
Constraint: &aurora.TaskConstraint{
|
||||
Limit: &aurora.LimitConstraint{
|
||||
Limit: 1,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
expected: 1,
|
||||
isError: false,
|
||||
},
|
||||
{
|
||||
message: "limit constraint on unavailable zone",
|
||||
request: aurora.Resource{
|
||||
NumCpus: &validCpu,
|
||||
},
|
||||
constraints: []*aurora.Constraint{
|
||||
{
|
||||
Name: "gpu-host", // no host has gpu-host attribute
|
||||
Constraint: &aurora.TaskConstraint{
|
||||
Limit: &aurora.LimitConstraint{
|
||||
Limit: 1,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
expected: 0,
|
||||
isError: false,
|
||||
},
|
||||
{
|
||||
message: "limit & dedicated constraint",
|
||||
request: aurora.Resource{
|
||||
NumCpus: &validCpu,
|
||||
},
|
||||
constraints: []*aurora.Constraint{
|
||||
{
|
||||
Name: "dedicated",
|
||||
Constraint: &aurora.TaskConstraint{
|
||||
Value: &aurora.ValueConstraint{
|
||||
Negated: false,
|
||||
Values: []string{"vagrant/bar"},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "host",
|
||||
Constraint: &aurora.TaskConstraint{
|
||||
Limit: &aurora.LimitConstraint{
|
||||
Limit: 1,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
expected: 1,
|
||||
isError: false,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range tests {
|
||||
task := aurora.NewTaskConfig()
|
||||
task.Resources = []*aurora.Resource{&tc.request}
|
||||
task.Constraints = tc.constraints
|
||||
|
||||
numTasks, err := r.FitTasks(task, offers)
|
||||
|
||||
if !tc.isError {
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, tc.expected, numTasks, tc.message)
|
||||
} else {
|
||||
assert.Error(t, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue