// Ensure higher priority dequeued first func TestPlanQueue_Dequeue_Priority(t *testing.T) { pq := testPlanQueue(t) pq.SetEnabled(true) plan1 := mock.Plan() plan1.Priority = 10 pq.Enqueue(plan1) plan2 := mock.Plan() plan2.Priority = 30 pq.Enqueue(plan2) plan3 := mock.Plan() plan3.Priority = 20 pq.Enqueue(plan3) out1, _ := pq.Dequeue(time.Second) if out1.plan != plan2 { t.Fatalf("bad: %#v", out1) } out2, _ := pq.Dequeue(time.Second) if out2.plan != plan3 { t.Fatalf("bad: %#v", out2) } out3, _ := pq.Dequeue(time.Second) if out3.plan != plan1 { t.Fatalf("bad: %#v", out3) } }
func TestPlanQueue_Enqueue_Disable(t *testing.T) { pq := testPlanQueue(t) // Enqueue plan := mock.Plan() pq.SetEnabled(true) future, err := pq.Enqueue(plan) if err != nil { t.Fatalf("err: %v", err) } // Flush via SetEnabled pq.SetEnabled(false) // Check the stats stats := pq.Stats() if stats.Depth != 0 { t.Fatalf("bad: %#v", stats) } // Future should be canceled res, err := future.Wait() if err != planQueueFlushed { t.Fatalf("err: %v", err) } if res != nil { t.Fatalf("bad: %#v", res) } }
// Ensure FIFO at fixed priority func TestPlanQueue_Dequeue_FIFO(t *testing.T) { pq := testPlanQueue(t) pq.SetEnabled(true) plans := make([]*structs.Plan, 100) for i := 0; i < len(plans); i++ { if i%5 == 0 { time.Sleep(10 * time.Millisecond) } plans[i] = mock.Plan() pq.Enqueue(plans[i]) } var prev *pendingPlan for i := range plans { out, err := pq.Dequeue(time.Second) if err != nil { t.Fatalf("failed to dequeue plan %d: %v", i, err) } if prev != nil && out.enqueueTime.Before(prev.enqueueTime) { t.Fatalf("out of order dequeue at %d, prev=%v, got=%v", i, prev.enqueueTime, out.enqueueTime) } prev = out } }
func TestPlanQueue_Enqueue_Dequeue(t *testing.T) { pq := testPlanQueue(t) if pq.Enabled() { t.Fatalf("should not be enabled") } pq.SetEnabled(true) if !pq.Enabled() { t.Fatalf("should be enabled") } plan := mock.Plan() future, err := pq.Enqueue(plan) if err != nil { t.Fatalf("err: %v", err) } stats := pq.Stats() if stats.Depth != 1 { t.Fatalf("bad: %#v", stats) } resCh := make(chan *structs.PlanResult, 1) go func() { res, err := future.Wait() if err != nil { t.Fatalf("err: %v", err) } resCh <- res }() pending, err := pq.Dequeue(time.Second) if err != nil { t.Fatalf("err: %v", err) } stats = pq.Stats() if stats.Depth != 0 { t.Fatalf("bad: %#v", stats) } if pending == nil || pending.plan != plan { t.Fatalf("bad: %#v", pending) } result := mock.PlanResult() pending.respond(result, nil) select { case r := <-resCh: if r != result { t.Fatalf("Bad: %#v", r) } case <-time.After(time.Second): t.Fatalf("timeout") } }
// Ensure FIFO at fixed priority func TestPlanQueue_Dequeue_FIFO(t *testing.T) { pq := testPlanQueue(t) pq.SetEnabled(true) NUM := 100 plans := make([]*structs.Plan, NUM) for i := 0; i < NUM; i++ { plan := mock.Plan() pq.Enqueue(plan) plans[i] = plan } for i := 0; i < NUM; i++ { out1, _ := pq.Dequeue(time.Second) if out1.plan != plans[i] { t.Fatalf("bad: %d %#v", i, out1) } } }
func TestPlanEndpoint_Submit(t *testing.T) { s1 := testServer(t, func(c *Config) { c.NumSchedulers = 0 }) defer s1.Shutdown() codec := rpcClient(t, s1) testutil.WaitForLeader(t, s1.RPC) // Create the register request eval1 := mock.Eval() testutil.WaitForResult(func() (bool, error) { err := s1.evalBroker.Enqueue(eval1) return err == nil, err }, func(err error) { t.Fatalf("err: %v", err) }) evalOut, token, err := s1.evalBroker.Dequeue([]string{eval1.Type}, time.Second) if err != nil { t.Fatalf("err: %v", err) } if evalOut != eval1 { t.Fatalf("Bad eval") } // Submit a plan plan := mock.Plan() plan.EvalID = eval1.ID plan.EvalToken = token req := &structs.PlanRequest{ Plan: plan, WriteRequest: structs.WriteRequest{Region: "global"}, } var resp structs.PlanResponse if err := msgpackrpc.CallWithCodec(codec, "Plan.Submit", req, &resp); err != nil { t.Fatalf("err: %v", err) } if resp.Result == nil { t.Fatalf("missing result") } }