diff --git a/nomad/client_endpoint_test.go b/nomad/client_endpoint_test.go index a89b69449..df54a3a4c 100644 --- a/nomad/client_endpoint_test.go +++ b/nomad/client_endpoint_test.go @@ -5,6 +5,7 @@ import ( "testing" "github.com/hashicorp/net-rpc-msgpackrpc" + "github.com/hashicorp/nomad/nomad/mock" "github.com/hashicorp/nomad/nomad/structs" "github.com/hashicorp/nomad/testutil" ) @@ -16,7 +17,7 @@ func TestClientEndpoint_Register(t *testing.T) { testutil.WaitForLeader(t, s1.RPC) // Create the register request - node := mockNode() + node := mock.Node() req := &structs.NodeRegisterRequest{ Node: node, WriteRequest: structs.WriteRequest{Region: "region1"}, @@ -52,7 +53,7 @@ func TestClientEndpoint_Deregister(t *testing.T) { testutil.WaitForLeader(t, s1.RPC) // Create the register request - node := mockNode() + node := mock.Node() reg := &structs.NodeRegisterRequest{ Node: node, WriteRequest: structs.WriteRequest{Region: "region1"}, @@ -95,7 +96,7 @@ func TestClientEndpoint_UpdateStatus(t *testing.T) { testutil.WaitForLeader(t, s1.RPC) // Create the register request - node := mockNode() + node := mock.Node() reg := &structs.NodeRegisterRequest{ Node: node, WriteRequest: structs.WriteRequest{Region: "region1"}, @@ -142,7 +143,7 @@ func TestClientEndpoint_GetNode(t *testing.T) { testutil.WaitForLeader(t, s1.RPC) // Create the register request - node := mockNode() + node := mock.Node() reg := &structs.NodeRegisterRequest{ Node: node, WriteRequest: structs.WriteRequest{Region: "region1"}, @@ -192,7 +193,7 @@ func TestClientEndpoint_CreateNodeEvals(t *testing.T) { testutil.WaitForLeader(t, s1.RPC) // Inject fake evaluations - alloc := mockAlloc() + alloc := mock.Alloc() state := s1.fsm.State() err := state.UpdateAllocations(1, nil, []*structs.Allocation{alloc}) if err != nil { diff --git a/nomad/eval_broker_test.go b/nomad/eval_broker_test.go index 651c5414d..d459785f4 100644 --- a/nomad/eval_broker_test.go +++ b/nomad/eval_broker_test.go @@ -4,6 +4,7 @@ import ( "testing" "time" + "github.com/hashicorp/nomad/nomad/mock" "github.com/hashicorp/nomad/nomad/structs" ) @@ -29,7 +30,7 @@ func TestEvalBroker_Enqueue_Dequeue_Nack_Ack(t *testing.T) { b := testBroker(t, 0) // Enqueue, but broker is disabled! - eval := mockEval() + eval := mock.Eval() err := b.Enqueue(eval) if err != nil { t.Fatalf("err: %v", err) @@ -167,13 +168,13 @@ func TestEvalBroker_Serialize_DuplicateJobID(t *testing.T) { b := testBroker(t, 0) b.SetEnabled(true) - eval := mockEval() + eval := mock.Eval() err := b.Enqueue(eval) if err != nil { t.Fatalf("err: %v", err) } - eval2 := mockEval() + eval2 := mock.Eval() eval2.JobID = eval.JobID eval2.CreateIndex = eval.CreateIndex + 1 err = b.Enqueue(eval2) @@ -181,7 +182,7 @@ func TestEvalBroker_Serialize_DuplicateJobID(t *testing.T) { t.Fatalf("err: %v", err) } - eval3 := mockEval() + eval3 := mock.Eval() eval3.JobID = eval.JobID eval3.CreateIndex = eval.CreateIndex + 2 err = b.Enqueue(eval3) @@ -319,7 +320,7 @@ func TestEvalBroker_Enqueue_Disable(t *testing.T) { b := testBroker(t, 0) // Enqueue - eval := mockEval() + eval := mock.Eval() b.SetEnabled(true) err := b.Enqueue(eval) if err != nil { @@ -367,15 +368,15 @@ func TestEvalBroker_Dequeue_Priority(t *testing.T) { b := testBroker(t, 0) b.SetEnabled(true) - eval1 := mockEval() + eval1 := mock.Eval() eval1.Priority = 10 b.Enqueue(eval1) - eval2 := mockEval() + eval2 := mock.Eval() eval2.Priority = 30 b.Enqueue(eval2) - eval3 := mockEval() + eval3 := mock.Eval() eval3.Priority = 20 b.Enqueue(eval3) @@ -402,7 +403,7 @@ func TestEvalBroker_Dequeue_FIFO(t *testing.T) { NUM := 100 for i := 0; i < NUM; i++ { - eval1 := mockEval() + eval1 := mock.Eval() eval1.CreateIndex = uint64(i) eval1.ModifyIndex = uint64(i) b.Enqueue(eval1) @@ -423,7 +424,7 @@ func TestEvalBroker_Dequeue_Fairness(t *testing.T) { NUM := 100 for i := 0; i < NUM; i++ { - eval1 := mockEval() + eval1 := mock.Eval() if i < (NUM / 2) { eval1.Type = structs.JobTypeService } else { @@ -481,7 +482,7 @@ func TestEvalBroker_Dequeue_Blocked(t *testing.T) { time.Sleep(5 * time.Millisecond) // Enqueue - eval := mockEval() + eval := mock.Eval() err := b.Enqueue(eval) if err != nil { t.Fatalf("err: %v", err) @@ -504,7 +505,7 @@ func TestEvalBroker_Nack_Timeout(t *testing.T) { b.SetEnabled(true) // Enqueue - eval := mockEval() + eval := mock.Eval() err := b.Enqueue(eval) if err != nil { t.Fatalf("err: %v", err) diff --git a/nomad/eval_endpoint_test.go b/nomad/eval_endpoint_test.go index 78491c100..06bde4a6e 100644 --- a/nomad/eval_endpoint_test.go +++ b/nomad/eval_endpoint_test.go @@ -6,6 +6,7 @@ import ( "time" "github.com/hashicorp/net-rpc-msgpackrpc" + "github.com/hashicorp/nomad/nomad/mock" "github.com/hashicorp/nomad/nomad/structs" "github.com/hashicorp/nomad/testutil" ) @@ -17,7 +18,7 @@ func TestEvalEndpoint_GetEval(t *testing.T) { testutil.WaitForLeader(t, s1.RPC) // Create the register request - eval1 := mockEval() + eval1 := mock.Eval() s1.fsm.State().UpsertEvals(1000, []*structs.Evaluation{eval1}) // Lookup the eval @@ -59,7 +60,7 @@ func TestEvalEndpoint_Dequeue(t *testing.T) { testutil.WaitForLeader(t, s1.RPC) // Create the register request - eval1 := mockEval() + eval1 := mock.Eval() s1.evalBroker.Enqueue(eval1) // Dequeue the eval @@ -94,7 +95,7 @@ func TestEvalEndpoint_Ack(t *testing.T) { }) // Create the register request - eval1 := mockEval() + eval1 := mock.Eval() s1.evalBroker.Enqueue(eval1) out, err := s1.evalBroker.Dequeue(defaultSched, time.Second) if err != nil { @@ -132,7 +133,7 @@ func TestEvalEndpoint_Nack(t *testing.T) { }) // Create the register request - eval1 := mockEval() + eval1 := mock.Eval() s1.evalBroker.Enqueue(eval1) out, _ := s1.evalBroker.Dequeue(defaultSched, time.Second) if out == nil { diff --git a/nomad/fsm.go b/nomad/fsm.go index f63810f8b..31a808dd7 100644 --- a/nomad/fsm.go +++ b/nomad/fsm.go @@ -8,6 +8,7 @@ import ( "github.com/armon/go-metrics" "github.com/hashicorp/go-msgpack/codec" + "github.com/hashicorp/nomad/nomad/state" "github.com/hashicorp/nomad/nomad/structs" "github.com/hashicorp/raft" ) @@ -38,14 +39,14 @@ type nomadFSM struct { evalBroker *EvalBroker logOutput io.Writer logger *log.Logger - state *StateStore + state *state.StateStore } // nomadSnapshot is used to provide a snapshot of the current // state in a way that can be accessed concurrently with operations // that may modify the live state. type nomadSnapshot struct { - snap *StateSnapshot + snap *state.StateSnapshot } // snapshotHeader is the first entry in our snapshot @@ -55,7 +56,7 @@ type snapshotHeader struct { // NewFSMPath is used to construct a new FSM with a blank state func NewFSM(evalBroker *EvalBroker, logOutput io.Writer) (*nomadFSM, error) { // Create a state store - state, err := NewStateStore(logOutput) + state, err := state.NewStateStore(logOutput) if err != nil { return nil, err } @@ -75,7 +76,7 @@ func (n *nomadFSM) Close() error { } // State is used to return a handle to the current state -func (n *nomadFSM) State() *StateStore { +func (n *nomadFSM) State() *state.StateStore { return n.state } @@ -253,14 +254,14 @@ func (n *nomadFSM) Restore(old io.ReadCloser) error { defer old.Close() // Create a new state store - state, err := NewStateStore(n.logOutput) + newState, err := state.NewStateStore(n.logOutput) if err != nil { return err } - n.state = state + n.state = newState // Start the state restore - restore, err := state.Restore() + restore, err := newState.Restore() if err != nil { return err } @@ -325,7 +326,7 @@ func (n *nomadFSM) Restore(old io.ReadCloser) error { } case IndexSnapshot: - idx := new(IndexEntry) + idx := new(state.IndexEntry) if err := dec.Decode(idx); err != nil { return err } @@ -395,7 +396,7 @@ func (s *nomadSnapshot) persistIndexes(sink raft.SnapshotSink, } // Prepare the request struct - idx := raw.(*IndexEntry) + idx := raw.(*state.IndexEntry) // Write out a node registration sink.Write([]byte{byte(IndexSnapshot)}) diff --git a/nomad/fsm_test.go b/nomad/fsm_test.go index ed65027c8..724a990a0 100644 --- a/nomad/fsm_test.go +++ b/nomad/fsm_test.go @@ -6,6 +6,8 @@ import ( "reflect" "testing" + "github.com/hashicorp/nomad/nomad/mock" + "github.com/hashicorp/nomad/nomad/state" "github.com/hashicorp/nomad/nomad/structs" "github.com/hashicorp/raft" ) @@ -28,6 +30,17 @@ func (m *MockSink) Close() error { return nil } +func testStateStore(t *testing.T) *state.StateStore { + state, err := state.NewStateStore(os.Stderr) + if err != nil { + t.Fatalf("err: %v", err) + } + if state == nil { + t.Fatalf("missing state") + } + return state +} + func testFSM(t *testing.T) *nomadFSM { fsm, err := NewFSM(testBroker(t, 0), os.Stderr) if err != nil { @@ -52,7 +65,7 @@ func TestFSM_RegisterNode(t *testing.T) { fsm := testFSM(t) req := structs.NodeRegisterRequest{ - Node: mockNode(), + Node: mock.Node(), } buf, err := structs.Encode(structs.NodeRegisterRequestType, req) if err != nil { @@ -80,7 +93,7 @@ func TestFSM_RegisterNode(t *testing.T) { func TestFSM_DeregisterNode(t *testing.T) { fsm := testFSM(t) - node := mockNode() + node := mock.Node() req := structs.NodeRegisterRequest{ Node: node, } @@ -120,7 +133,7 @@ func TestFSM_DeregisterNode(t *testing.T) { func TestFSM_UpdateNodeStatus(t *testing.T) { fsm := testFSM(t) - node := mockNode() + node := mock.Node() req := structs.NodeRegisterRequest{ Node: node, } @@ -162,7 +175,7 @@ func TestFSM_RegisterJob(t *testing.T) { fsm := testFSM(t) req := structs.JobRegisterRequest{ - Job: mockJob(), + Job: mock.Job(), } buf, err := structs.Encode(structs.JobRegisterRequestType, req) if err != nil { @@ -190,7 +203,7 @@ func TestFSM_RegisterJob(t *testing.T) { func TestFSM_DeregisterJob(t *testing.T) { fsm := testFSM(t) - job := mockJob() + job := mock.Job() req := structs.JobRegisterRequest{ Job: job, } @@ -232,7 +245,7 @@ func TestFSM_UpdateEval(t *testing.T) { fsm.evalBroker.SetEnabled(true) req := structs.EvalUpdateRequest{ - Evals: []*structs.Evaluation{mockEval()}, + Evals: []*structs.Evaluation{mock.Eval()}, } buf, err := structs.Encode(structs.EvalUpdateRequestType, req) if err != nil { @@ -266,7 +279,7 @@ func TestFSM_UpdateEval(t *testing.T) { func TestFSM_DeleteEval(t *testing.T) { fsm := testFSM(t) - eval := mockEval() + eval := mock.Eval() req := structs.EvalUpdateRequest{ Evals: []*structs.Evaluation{eval}, } @@ -306,7 +319,7 @@ func TestFSM_DeleteEval(t *testing.T) { func TestFSM_UpdateAllocations(t *testing.T) { fsm := testFSM(t) - alloc := mockAlloc() + alloc := mock.Alloc() req := structs.AllocUpdateRequest{ Evict: nil, Alloc: []*structs.Allocation{alloc}, @@ -384,9 +397,9 @@ func TestFSM_SnapshotRestore_Nodes(t *testing.T) { // Add some state fsm := testFSM(t) state := fsm.State() - node1 := mockNode() + node1 := mock.Node() state.RegisterNode(1000, node1) - node2 := mockNode() + node2 := mock.Node() state.RegisterNode(1001, node2) // Verify the contents @@ -406,9 +419,9 @@ func TestFSM_SnapshotRestore_Jobs(t *testing.T) { // Add some state fsm := testFSM(t) state := fsm.State() - job1 := mockJob() + job1 := mock.Job() state.RegisterJob(1000, job1) - job2 := mockJob() + job2 := mock.Job() state.RegisterJob(1001, job2) // Verify the contents @@ -428,9 +441,9 @@ func TestFSM_SnapshotRestore_Evals(t *testing.T) { // Add some state fsm := testFSM(t) state := fsm.State() - eval1 := mockEval() + eval1 := mock.Eval() state.UpsertEvals(1000, []*structs.Evaluation{eval1}) - eval2 := mockEval() + eval2 := mock.Eval() state.UpsertEvals(1001, []*structs.Evaluation{eval2}) // Verify the contents @@ -450,9 +463,9 @@ func TestFSM_SnapshotRestore_Allocs(t *testing.T) { // Add some state fsm := testFSM(t) state := fsm.State() - alloc1 := mockAlloc() + alloc1 := mock.Alloc() state.UpdateAllocations(1000, nil, []*structs.Allocation{alloc1}) - alloc2 := mockAlloc() + alloc2 := mock.Alloc() state.UpdateAllocations(1001, nil, []*structs.Allocation{alloc2}) // Verify the contents @@ -472,7 +485,7 @@ func TestFSM_SnapshotRestore_Indexes(t *testing.T) { // Add some state fsm := testFSM(t) state := fsm.State() - node1 := mockNode() + node1 := mock.Node() state.RegisterNode(1000, node1) // Verify the contents diff --git a/nomad/job_endpoint_test.go b/nomad/job_endpoint_test.go index 2541e5f80..ffd17dee3 100644 --- a/nomad/job_endpoint_test.go +++ b/nomad/job_endpoint_test.go @@ -5,6 +5,7 @@ import ( "testing" "github.com/hashicorp/net-rpc-msgpackrpc" + "github.com/hashicorp/nomad/nomad/mock" "github.com/hashicorp/nomad/nomad/structs" "github.com/hashicorp/nomad/testutil" ) @@ -16,7 +17,7 @@ func TestJobEndpoint_Register(t *testing.T) { testutil.WaitForLeader(t, s1.RPC) // Create the register request - job := mockJob() + job := mock.Job() req := &structs.JobRegisterRequest{ Job: job, WriteRequest: structs.WriteRequest{Region: "region1"}, @@ -83,7 +84,7 @@ func TestJobEndpoint_Register_Existing(t *testing.T) { testutil.WaitForLeader(t, s1.RPC) // Create the register request - job := mockJob() + job := mock.Job() req := &structs.JobRegisterRequest{ Job: job, WriteRequest: structs.WriteRequest{Region: "region1"}, @@ -99,7 +100,7 @@ func TestJobEndpoint_Register_Existing(t *testing.T) { } // Update the job definition - job2 := mockJob() + job2 := mock.Job() job2.Priority = 100 job2.ID = job.ID req.Job = job2 @@ -167,7 +168,7 @@ func TestJobEndpoint_Deregister(t *testing.T) { testutil.WaitForLeader(t, s1.RPC) // Create the register request - job := mockJob() + job := mock.Job() reg := &structs.JobRegisterRequest{ Job: job, WriteRequest: structs.WriteRequest{Region: "region1"}, @@ -241,7 +242,7 @@ func TestJobEndpoint_GetJob(t *testing.T) { testutil.WaitForLeader(t, s1.RPC) // Create the register request - job := mockJob() + job := mock.Job() reg := &structs.JobRegisterRequest{ Job: job, WriteRequest: structs.WriteRequest{Region: "region1"}, diff --git a/nomad/leader_test.go b/nomad/leader_test.go index e3daa1d16..d62070e6a 100644 --- a/nomad/leader_test.go +++ b/nomad/leader_test.go @@ -6,6 +6,7 @@ import ( "testing" "time" + "github.com/hashicorp/nomad/nomad/mock" "github.com/hashicorp/nomad/nomad/structs" "github.com/hashicorp/nomad/testutil" ) @@ -250,7 +251,7 @@ func TestLeader_EvalBroker_Reset(t *testing.T) { // Inject a pending eval req := structs.EvalUpdateRequest{ - Evals: []*structs.Evaluation{mockEval()}, + Evals: []*structs.Evaluation{mock.Eval()}, } _, _, err := leader.raftApply(structs.EvalUpdateRequestType, req) if err != nil { diff --git a/nomad/mock/mock.go b/nomad/mock/mock.go new file mode 100644 index 000000000..123e86b27 --- /dev/null +++ b/nomad/mock/mock.go @@ -0,0 +1,157 @@ +package mock + +import ( + crand "crypto/rand" + "fmt" + + "github.com/hashicorp/nomad/nomad/structs" +) + +func GenerateUUID() string { + buf := make([]byte, 16) + if _, err := crand.Read(buf); err != nil { + panic(fmt.Errorf("failed to read random bytes: %v", err)) + } + + return fmt.Sprintf("%08x-%04x-%04x-%04x-%12x", + buf[0:4], + buf[4:6], + buf[6:8], + buf[8:10], + buf[10:16]) +} + +func Node() *structs.Node { + node := &structs.Node{ + ID: GenerateUUID(), + Datacenter: "dc1", + Name: "foobar", + Attributes: map[string]string{ + "os": "linux", + "arch": "x86", + "version": "0.1.0", + "driver.docker": "1.0.0", + }, + Resources: &structs.Resources{ + CPU: 4.0, + MemoryMB: 8192, + DiskMB: 100 * 1024, + IOPS: 150, + Networks: []*structs.NetworkResource{ + &structs.NetworkResource{ + Public: true, + CIDR: "192.168.0.100/32", + ReservedPorts: []int{22}, + MBits: 1000, + }, + }, + }, + Reserved: &structs.Resources{ + CPU: 0.1, + MemoryMB: 256, + DiskMB: 4 * 1024, + }, + Links: map[string]string{ + "consul": "foobar.dc1", + }, + Meta: map[string]string{ + "pci-dss": "true", + }, + NodeClass: "linux-medium-pci", + Status: structs.NodeStatusReady, + } + return node +} + +func Job() *structs.Job { + job := &structs.Job{ + ID: GenerateUUID(), + Name: "my-job", + Type: structs.JobTypeService, + Priority: 50, + AllAtOnce: false, + Constraints: []*structs.Constraint{ + &structs.Constraint{ + Hard: true, + LTarget: "attr.os", + RTarget: "linux", + Operand: "=", + }, + }, + TaskGroups: []*structs.TaskGroup{ + &structs.TaskGroup{ + Name: "web", + Count: 10, + Tasks: []*structs.Task{ + &structs.Task{ + Name: "web", + Driver: "docker", + Config: map[string]string{ + "image": "hashicorp/web", + "version": "v1.2.3", + }, + Resources: &structs.Resources{ + CPU: 0.5, + MemoryMB: 256, + }, + }, + }, + Meta: map[string]string{ + "elb_check_type": "http", + "elb_check_interval": "30s", + "elb_check_min": "3", + }, + }, + }, + Meta: map[string]string{ + "owner": "armon", + }, + Status: structs.JobStatusPending, + } + return job +} + +func Eval() *structs.Evaluation { + eval := &structs.Evaluation{ + ID: GenerateUUID(), + Priority: 50, + Type: structs.JobTypeService, + JobID: GenerateUUID(), + Status: structs.EvalStatusPending, + } + return eval +} + +func Alloc() *structs.Allocation { + alloc := &structs.Allocation{ + ID: GenerateUUID(), + NodeID: "foo", + Resources: &structs.Resources{ + CPU: 1.0, + MemoryMB: 1024, + DiskMB: 1024, + IOPS: 10, + Networks: []*structs.NetworkResource{ + &structs.NetworkResource{ + Public: true, + CIDR: "192.168.0.100/32", + ReservedPorts: []int{12345}, + MBits: 100, + }, + }, + }, + Job: Job(), + } + alloc.JobID = alloc.Job.ID + return alloc +} + +func Plan() *structs.Plan { + return &structs.Plan{ + Priority: 50, + } +} + +func PlanResult() *structs.PlanResult { + return &structs.PlanResult{} +} diff --git a/nomad/plan_apply.go b/nomad/plan_apply.go index 0ff4a5a0b..d25699ca3 100644 --- a/nomad/plan_apply.go +++ b/nomad/plan_apply.go @@ -5,6 +5,7 @@ import ( "time" "github.com/armon/go-metrics" + "github.com/hashicorp/nomad/nomad/state" "github.com/hashicorp/nomad/nomad/structs" ) @@ -69,7 +70,7 @@ func (s *Server) applyPlan(result *structs.PlanResult) (uint64, error) { // evaluatePlan is used to determine what portions of a plan // can be applied if any. Returns if there should be a plan application // which may be partial or if there was an error -func evaluatePlan(snap *StateSnapshot, plan *structs.Plan) (*structs.PlanResult, error) { +func evaluatePlan(snap *state.StateSnapshot, plan *structs.Plan) (*structs.PlanResult, error) { defer metrics.MeasureSince([]string{"nomad", "plan", "evaluate"}, time.Now()) // Create a result holder for the plan @@ -123,7 +124,7 @@ func evaluatePlan(snap *StateSnapshot, plan *structs.Plan) (*structs.PlanResult, // evaluateNodePlan is used to evalute the plan for a single node, // returning if the plan is valid or if an error is encountered -func evaluateNodePlan(snap *StateSnapshot, plan *structs.Plan, nodeID string) (bool, error) { +func evaluateNodePlan(snap *state.StateSnapshot, plan *structs.Plan, nodeID string) (bool, error) { // If this is an evict-only plan, it always 'fits' since we are removing things. if len(plan.NodeAllocation[nodeID]) == 0 { return true, nil diff --git a/nomad/plan_apply_test.go b/nomad/plan_apply_test.go index e309a194d..e7f91581f 100644 --- a/nomad/plan_apply_test.go +++ b/nomad/plan_apply_test.go @@ -3,6 +3,7 @@ package nomad import ( "testing" + "github.com/hashicorp/nomad/nomad/mock" "github.com/hashicorp/nomad/nomad/structs" "github.com/hashicorp/nomad/testutil" ) @@ -30,11 +31,11 @@ func TestPlanApply_applyPlan(t *testing.T) { testutil.WaitForLeader(t, s1.RPC) // Register ndoe - node := mockNode() + node := mock.Node() testRegisterNode(t, s1, node) // Register alloc - alloc := mockAlloc() + alloc := mock.Alloc() plan := &structs.PlanResult{ NodeEvict: map[string][]string{ node.ID: []string{}, @@ -63,7 +64,7 @@ func TestPlanApply_applyPlan(t *testing.T) { } // Evict alloc, Register alloc2 - alloc2 := mockAlloc() + alloc2 := mock.Alloc() plan = &structs.PlanResult{ NodeEvict: map[string][]string{ node.ID: []string{alloc.ID}, @@ -103,11 +104,11 @@ func TestPlanApply_applyPlan(t *testing.T) { func TestPlanApply_EvalPlan_Simple(t *testing.T) { state := testStateStore(t) - node := mockNode() + node := mock.Node() state.RegisterNode(1000, node) snap, _ := state.Snapshot() - alloc := mockAlloc() + alloc := mock.Alloc() plan := &structs.Plan{ NodeAllocation: map[string][]*structs.Allocation{ node.ID: []*structs.Allocation{alloc}, @@ -125,14 +126,14 @@ func TestPlanApply_EvalPlan_Simple(t *testing.T) { func TestPlanApply_EvalPlan_Partial(t *testing.T) { state := testStateStore(t) - node := mockNode() + node := mock.Node() state.RegisterNode(1000, node) - node2 := mockNode() + node2 := mock.Node() state.RegisterNode(1001, node2) snap, _ := state.Snapshot() - alloc := mockAlloc() - alloc2 := mockAlloc() // Ensure alloc2 does not fit + alloc := mock.Alloc() + alloc2 := mock.Alloc() // Ensure alloc2 does not fit alloc2.Resources = node2.Resources plan := &structs.Plan{ NodeAllocation: map[string][]*structs.Allocation{ @@ -159,14 +160,14 @@ func TestPlanApply_EvalPlan_Partial(t *testing.T) { func TestPlanApply_EvalPlan_Partial_AllAtOnce(t *testing.T) { state := testStateStore(t) - node := mockNode() + node := mock.Node() state.RegisterNode(1000, node) - node2 := mockNode() + node2 := mock.Node() state.RegisterNode(1001, node2) snap, _ := state.Snapshot() - alloc := mockAlloc() - alloc2 := mockAlloc() // Ensure alloc2 does not fit + alloc := mock.Alloc() + alloc2 := mock.Alloc() // Ensure alloc2 does not fit alloc2.Resources = node2.Resources plan := &structs.Plan{ AllAtOnce: true, // Require all to make progress @@ -191,11 +192,11 @@ func TestPlanApply_EvalPlan_Partial_AllAtOnce(t *testing.T) { func TestPlanApply_EvalNodePlan_Simple(t *testing.T) { state := testStateStore(t) - node := mockNode() + node := mock.Node() state.RegisterNode(1000, node) snap, _ := state.Snapshot() - alloc := mockAlloc() + alloc := mock.Alloc() plan := &structs.Plan{ NodeAllocation: map[string][]*structs.Allocation{ node.ID: []*structs.Allocation{alloc}, @@ -213,12 +214,12 @@ func TestPlanApply_EvalNodePlan_Simple(t *testing.T) { func TestPlanApply_EvalNodePlan_NodeNotReady(t *testing.T) { state := testStateStore(t) - node := mockNode() + node := mock.Node() node.Status = structs.NodeStatusInit state.RegisterNode(1000, node) snap, _ := state.Snapshot() - alloc := mockAlloc() + alloc := mock.Alloc() plan := &structs.Plan{ NodeAllocation: map[string][]*structs.Allocation{ node.ID: []*structs.Allocation{alloc}, @@ -239,7 +240,7 @@ func TestPlanApply_EvalNodePlan_NodeNotExist(t *testing.T) { snap, _ := state.Snapshot() nodeID := "foo" - alloc := mockAlloc() + alloc := mock.Alloc() plan := &structs.Plan{ NodeAllocation: map[string][]*structs.Allocation{ nodeID: []*structs.Allocation{alloc}, @@ -256,9 +257,9 @@ func TestPlanApply_EvalNodePlan_NodeNotExist(t *testing.T) { } func TestPlanApply_EvalNodePlan_NodeFull(t *testing.T) { - alloc := mockAlloc() + alloc := mock.Alloc() state := testStateStore(t) - node := mockNode() + node := mock.Node() alloc.NodeID = node.ID node.Resources = alloc.Resources node.Reserved = nil @@ -283,9 +284,9 @@ func TestPlanApply_EvalNodePlan_NodeFull(t *testing.T) { } func TestPlanApply_EvalNodePlan_NodeFull_Evict(t *testing.T) { - alloc := mockAlloc() + alloc := mock.Alloc() state := testStateStore(t) - node := mockNode() + node := mock.Node() alloc.NodeID = node.ID node.Resources = alloc.Resources node.Reserved = nil @@ -294,7 +295,7 @@ func TestPlanApply_EvalNodePlan_NodeFull_Evict(t *testing.T) { []*structs.Allocation{alloc}) snap, _ := state.Snapshot() - alloc2 := mockAlloc() + alloc2 := mock.Alloc() plan := &structs.Plan{ NodeEvict: map[string][]string{ node.ID: []string{alloc.ID}, @@ -314,9 +315,9 @@ func TestPlanApply_EvalNodePlan_NodeFull_Evict(t *testing.T) { } func TestPlanApply_EvalNodePlan_NodeMaint_EvictOnly(t *testing.T) { - alloc := mockAlloc() + alloc := mock.Alloc() state := testStateStore(t) - node := mockNode() + node := mock.Node() alloc.NodeID = node.ID node.Resources = alloc.Resources node.Reserved = nil diff --git a/nomad/plan_endpoint_test.go b/nomad/plan_endpoint_test.go index 704cfdb8f..6e872aa90 100644 --- a/nomad/plan_endpoint_test.go +++ b/nomad/plan_endpoint_test.go @@ -4,6 +4,7 @@ import ( "testing" "github.com/hashicorp/net-rpc-msgpackrpc" + "github.com/hashicorp/nomad/nomad/mock" "github.com/hashicorp/nomad/nomad/structs" "github.com/hashicorp/nomad/testutil" ) @@ -15,7 +16,7 @@ func TestPlanEndpoint_Submit(t *testing.T) { testutil.WaitForLeader(t, s1.RPC) // Submit a plan - plan := mockPlan() + plan := mock.Plan() req := &structs.PlanRequest{ Plan: plan, WriteRequest: structs.WriteRequest{Region: "region1"}, diff --git a/nomad/plan_queue_test.go b/nomad/plan_queue_test.go index fe1e30b3b..941e1454b 100644 --- a/nomad/plan_queue_test.go +++ b/nomad/plan_queue_test.go @@ -4,6 +4,7 @@ import ( "testing" "time" + "github.com/hashicorp/nomad/nomad/mock" "github.com/hashicorp/nomad/nomad/structs" ) @@ -15,16 +16,6 @@ func testPlanQueue(t *testing.T) *PlanQueue { return pq } -func mockPlan() *structs.Plan { - return &structs.Plan{ - Priority: 50, - } -} - -func mockPlanResult() *structs.PlanResult { - return &structs.PlanResult{} -} - func TestPlanQueue_Enqueue_Dequeue(t *testing.T) { pq := testPlanQueue(t) if pq.Enabled() { @@ -35,7 +26,7 @@ func TestPlanQueue_Enqueue_Dequeue(t *testing.T) { t.Fatalf("should be enabled") } - plan := mockPlan() + plan := mock.Plan() future, err := pq.Enqueue(plan) if err != nil { t.Fatalf("err: %v", err) @@ -69,7 +60,7 @@ func TestPlanQueue_Enqueue_Dequeue(t *testing.T) { t.Fatalf("bad: %#v", pending) } - result := mockPlanResult() + result := mock.PlanResult() pending.respond(result, nil) select { @@ -86,7 +77,7 @@ func TestPlanQueue_Enqueue_Disable(t *testing.T) { pq := testPlanQueue(t) // Enqueue - plan := mockPlan() + plan := mock.Plan() pq.SetEnabled(true) future, err := pq.Enqueue(plan) if err != nil { @@ -137,15 +128,15 @@ func TestPlanQueue_Dequeue_Priority(t *testing.T) { pq := testPlanQueue(t) pq.SetEnabled(true) - plan1 := mockPlan() + plan1 := mock.Plan() plan1.Priority = 10 pq.Enqueue(plan1) - plan2 := mockPlan() + plan2 := mock.Plan() plan2.Priority = 30 pq.Enqueue(plan2) - plan3 := mockPlan() + plan3 := mock.Plan() plan3.Priority = 20 pq.Enqueue(plan3) @@ -173,7 +164,7 @@ func TestPlanQueue_Dequeue_FIFO(t *testing.T) { plans := make([]*structs.Plan, NUM) for i := 0; i < NUM; i++ { - plan := mockPlan() + plan := mock.Plan() pq.Enqueue(plan) plans[i] = plan } diff --git a/nomad/schema.go b/nomad/state/schema.go similarity index 99% rename from nomad/schema.go rename to nomad/state/schema.go index 5a53100f1..434ad733b 100644 --- a/nomad/schema.go +++ b/nomad/state/schema.go @@ -1,4 +1,4 @@ -package nomad +package state import ( "fmt" diff --git a/nomad/schema_test.go b/nomad/state/schema_test.go similarity index 93% rename from nomad/schema_test.go rename to nomad/state/schema_test.go index 79fcab693..93c6d5872 100644 --- a/nomad/schema_test.go +++ b/nomad/state/schema_test.go @@ -1,4 +1,4 @@ -package nomad +package state import ( "testing" diff --git a/nomad/state_store.go b/nomad/state/state_store.go similarity index 99% rename from nomad/state_store.go rename to nomad/state/state_store.go index 056740de9..b1042dbab 100644 --- a/nomad/state_store.go +++ b/nomad/state/state_store.go @@ -1,4 +1,4 @@ -package nomad +package state import ( "fmt" diff --git a/nomad/state_store_test.go b/nomad/state/state_store_test.go similarity index 82% rename from nomad/state_store_test.go rename to nomad/state/state_store_test.go index e9f87b8b6..4b521eaee 100644 --- a/nomad/state_store_test.go +++ b/nomad/state/state_store_test.go @@ -1,4 +1,4 @@ -package nomad +package state import ( "os" @@ -6,6 +6,7 @@ import ( "sort" "testing" + "github.com/hashicorp/nomad/nomad/mock" "github.com/hashicorp/nomad/nomad/structs" ) @@ -20,134 +21,9 @@ func testStateStore(t *testing.T) *StateStore { return state } -func mockNode() *structs.Node { - node := &structs.Node{ - ID: generateUUID(), - Datacenter: "dc1", - Name: "foobar", - Attributes: map[string]string{ - "os": "linux", - "arch": "x86", - "version": "0.1.0", - "driver.docker": "1.0.0", - }, - Resources: &structs.Resources{ - CPU: 4.0, - MemoryMB: 8192, - DiskMB: 100 * 1024, - IOPS: 150, - Networks: []*structs.NetworkResource{ - &structs.NetworkResource{ - Public: true, - CIDR: "192.168.0.100/32", - ReservedPorts: []int{22}, - MBits: 1000, - }, - }, - }, - Reserved: &structs.Resources{ - CPU: 0.1, - MemoryMB: 256, - DiskMB: 4 * 1024, - }, - Links: map[string]string{ - "consul": "foobar.dc1", - }, - Meta: map[string]string{ - "pci-dss": "true", - }, - NodeClass: "linux-medium-pci", - Status: structs.NodeStatusReady, - } - return node -} - -func mockJob() *structs.Job { - job := &structs.Job{ - ID: generateUUID(), - Name: "my-job", - Type: structs.JobTypeService, - Priority: 50, - AllAtOnce: false, - Constraints: []*structs.Constraint{ - &structs.Constraint{ - Hard: true, - LTarget: "attr.os", - RTarget: "linux", - Operand: "=", - }, - }, - TaskGroups: []*structs.TaskGroup{ - &structs.TaskGroup{ - Name: "web", - Count: 10, - Tasks: []*structs.Task{ - &structs.Task{ - Name: "web", - Driver: "docker", - Config: map[string]string{ - "image": "hashicorp/web", - "version": "v1.2.3", - }, - Resources: &structs.Resources{ - CPU: 0.5, - MemoryMB: 256, - }, - }, - }, - Meta: map[string]string{ - "elb_check_type": "http", - "elb_check_interval": "30s", - "elb_check_min": "3", - }, - }, - }, - Meta: map[string]string{ - "owner": "armon", - }, - Status: structs.JobStatusPending, - } - return job -} - -func mockEval() *structs.Evaluation { - eval := &structs.Evaluation{ - ID: generateUUID(), - Priority: 50, - Type: structs.JobTypeService, - JobID: generateUUID(), - Status: structs.EvalStatusPending, - } - return eval -} - -func mockAlloc() *structs.Allocation { - alloc := &structs.Allocation{ - ID: generateUUID(), - NodeID: "foo", - Resources: &structs.Resources{ - CPU: 1.0, - MemoryMB: 1024, - DiskMB: 1024, - IOPS: 10, - Networks: []*structs.NetworkResource{ - &structs.NetworkResource{ - Public: true, - CIDR: "192.168.0.100/32", - ReservedPorts: []int{12345}, - MBits: 100, - }, - }, - }, - Job: mockJob(), - } - alloc.JobID = alloc.Job.ID - return alloc -} - func TestStateStore_RegisterNode_GetNode(t *testing.T) { state := testStateStore(t) - node := mockNode() + node := mock.Node() err := state.RegisterNode(1000, node) if err != nil { @@ -174,7 +50,7 @@ func TestStateStore_RegisterNode_GetNode(t *testing.T) { func TestStateStore_DeregisterNode_GetNode(t *testing.T) { state := testStateStore(t) - node := mockNode() + node := mock.Node() err := state.RegisterNode(1000, node) if err != nil { @@ -206,7 +82,7 @@ func TestStateStore_DeregisterNode_GetNode(t *testing.T) { func TestStateStore_UpdateNode_GetNode(t *testing.T) { state := testStateStore(t) - node := mockNode() + node := mock.Node() err := state.RegisterNode(1000, node) if err != nil { @@ -244,7 +120,7 @@ func TestStateStore_Nodes(t *testing.T) { var nodes []*structs.Node for i := 0; i < 10; i++ { - node := mockNode() + node := mock.Node() nodes = append(nodes, node) err := state.RegisterNode(1000+uint64(i), node) @@ -283,7 +159,7 @@ func TestStateStore_RestoreNode(t *testing.T) { t.Fatalf("err: %v", err) } - node := mockNode() + node := mock.Node() err = restore.NodeRestore(node) if err != nil { t.Fatalf("err: %v", err) @@ -303,7 +179,7 @@ func TestStateStore_RestoreNode(t *testing.T) { func TestStateStore_RegisterJob_GetJob(t *testing.T) { state := testStateStore(t) - job := mockJob() + job := mock.Job() err := state.RegisterJob(1000, job) if err != nil { @@ -330,14 +206,14 @@ func TestStateStore_RegisterJob_GetJob(t *testing.T) { func TestStateStore_UpdateRegisterJob_GetJob(t *testing.T) { state := testStateStore(t) - job := mockJob() + job := mock.Job() err := state.RegisterJob(1000, job) if err != nil { t.Fatalf("err: %v", err) } - job2 := mockJob() + job2 := mock.Job() job2.ID = job.ID err = state.RegisterJob(1001, job2) if err != nil { @@ -371,7 +247,7 @@ func TestStateStore_UpdateRegisterJob_GetJob(t *testing.T) { func TestStateStore_DeregisterJob_GetJob(t *testing.T) { state := testStateStore(t) - job := mockJob() + job := mock.Job() err := state.RegisterJob(1000, job) if err != nil { @@ -406,7 +282,7 @@ func TestStateStore_Jobs(t *testing.T) { var jobs []*structs.Job for i := 0; i < 10; i++ { - job := mockJob() + job := mock.Job() jobs = append(jobs, job) err := state.RegisterJob(1000+uint64(i), job) @@ -445,7 +321,7 @@ func TestStateStore_RestoreJob(t *testing.T) { t.Fatalf("err: %v", err) } - job := mockJob() + job := mock.Job() err = restore.JobRestore(job) if err != nil { t.Fatalf("err: %v", err) @@ -465,7 +341,7 @@ func TestStateStore_RestoreJob(t *testing.T) { func TestStateStore_Indexes(t *testing.T) { state := testStateStore(t) - node := mockNode() + node := mock.Node() err := state.RegisterNode(1000, node) if err != nil { @@ -523,7 +399,7 @@ func TestStateStore_RestoreIndex(t *testing.T) { func TestStateStore_UpsertEvals_GetEval(t *testing.T) { state := testStateStore(t) - eval := mockEval() + eval := mock.Eval() err := state.UpsertEvals(1000, []*structs.Evaluation{eval}) if err != nil { @@ -550,14 +426,14 @@ func TestStateStore_UpsertEvals_GetEval(t *testing.T) { func TestStateStore_Update_UpsertEvals_GetEval(t *testing.T) { state := testStateStore(t) - eval := mockEval() + eval := mock.Eval() err := state.UpsertEvals(1000, []*structs.Evaluation{eval}) if err != nil { t.Fatalf("err: %v", err) } - eval2 := mockEval() + eval2 := mock.Eval() eval2.ID = eval.ID err = state.UpsertEvals(1001, []*structs.Evaluation{eval2}) if err != nil { @@ -591,7 +467,7 @@ func TestStateStore_Update_UpsertEvals_GetEval(t *testing.T) { func TestStateStore_DeleteEval_GetEval(t *testing.T) { state := testStateStore(t) - eval := mockEval() + eval := mock.Eval() err := state.UpsertEvals(1000, []*structs.Evaluation{eval}) if err != nil { @@ -626,7 +502,7 @@ func TestStateStore_Evals(t *testing.T) { var evals []*structs.Evaluation for i := 0; i < 10; i++ { - eval := mockEval() + eval := mock.Eval() evals = append(evals, eval) err := state.UpsertEvals(1000+uint64(i), []*structs.Evaluation{eval}) @@ -665,7 +541,7 @@ func TestStateStore_RestoreEval(t *testing.T) { t.Fatalf("err: %v", err) } - job := mockEval() + job := mock.Eval() err = restore.EvalRestore(job) if err != nil { t.Fatalf("err: %v", err) @@ -686,7 +562,7 @@ func TestStateStore_RestoreEval(t *testing.T) { func TestStateStore_UpsertAlloc_GetAlloc(t *testing.T) { state := testStateStore(t) - alloc := mockAlloc() + alloc := mock.Alloc() err := state.UpdateAllocations(1000, nil, []*structs.Allocation{alloc}) if err != nil { @@ -713,7 +589,7 @@ func TestStateStore_UpsertAlloc_GetAlloc(t *testing.T) { func TestStateStore_UpdateAlloc_GetAlloc(t *testing.T) { state := testStateStore(t) - alloc := mockAlloc() + alloc := mock.Alloc() err := state.UpdateAllocations(1000, nil, []*structs.Allocation{alloc}) @@ -721,7 +597,7 @@ func TestStateStore_UpdateAlloc_GetAlloc(t *testing.T) { t.Fatalf("err: %v", err) } - alloc2 := mockAlloc() + alloc2 := mock.Alloc() alloc2.ID = alloc.ID alloc2.NodeID = alloc.NodeID + ".new" err = state.UpdateAllocations(1001, nil, @@ -757,7 +633,7 @@ func TestStateStore_UpdateAlloc_GetAlloc(t *testing.T) { func TestStateStore_EvictAlloc_GetAlloc(t *testing.T) { state := testStateStore(t) - alloc := mockAlloc() + alloc := mock.Alloc() err := state.UpdateAllocations(1001, nil, []*structs.Allocation{alloc}) if err != nil { @@ -792,7 +668,7 @@ func TestStateStore_AllocsByNode(t *testing.T) { var allocs []*structs.Allocation for i := 0; i < 10; i++ { - alloc := mockAlloc() + alloc := mock.Alloc() alloc.NodeID = "foo" allocs = append(allocs, alloc) } @@ -820,7 +696,7 @@ func TestStateStore_AllocsByJob(t *testing.T) { var allocs []*structs.Allocation for i := 0; i < 10; i++ { - alloc := mockAlloc() + alloc := mock.Alloc() alloc.JobID = "foo" allocs = append(allocs, alloc) } @@ -848,7 +724,7 @@ func TestStateStore_Allocs(t *testing.T) { var allocs []*structs.Allocation for i := 0; i < 10; i++ { - alloc := mockAlloc() + alloc := mock.Alloc() allocs = append(allocs, alloc) } @@ -887,7 +763,7 @@ func TestStateStore_RestoreAlloc(t *testing.T) { t.Fatalf("err: %v", err) } - alloc := mockAlloc() + alloc := mock.Alloc() err = restore.AllocRestore(alloc) if err != nil { t.Fatalf("err: %v", err) diff --git a/nomad/system_sched.go b/nomad/system_sched.go index 57de8550b..93689c6eb 100644 --- a/nomad/system_sched.go +++ b/nomad/system_sched.go @@ -1,6 +1,7 @@ package nomad import ( + "github.com/hashicorp/nomad/nomad/state" "github.com/hashicorp/nomad/nomad/structs" "github.com/hashicorp/nomad/scheduler" ) @@ -10,11 +11,11 @@ import ( // across the cluster. type SystemScheduler struct { srv *Server - snap *StateSnapshot + snap *state.StateSnapshot } // NewSystemScheduler is used to return a new system scheduler instance -func NewSystemScheduler(srv *Server, snap *StateSnapshot) scheduler.Scheduler { +func NewSystemScheduler(srv *Server, snap *state.StateSnapshot) scheduler.Scheduler { s := &SystemScheduler{ srv: srv, snap: snap, diff --git a/nomad/worker_test.go b/nomad/worker_test.go index 1df8d73f1..f7b9597a1 100644 --- a/nomad/worker_test.go +++ b/nomad/worker_test.go @@ -7,6 +7,7 @@ import ( "testing" "time" + "github.com/hashicorp/nomad/nomad/mock" "github.com/hashicorp/nomad/nomad/structs" "github.com/hashicorp/nomad/scheduler" "github.com/hashicorp/nomad/testutil" @@ -49,7 +50,7 @@ func TestWorker_dequeueEvaluation(t *testing.T) { testutil.WaitForLeader(t, s1.RPC) // Create the evaluation - eval1 := mockEval() + eval1 := mock.Eval() s1.evalBroker.Enqueue(eval1) // Create a worker @@ -104,7 +105,7 @@ func TestWorker_sendAck(t *testing.T) { testutil.WaitForLeader(t, s1.RPC) // Create the evaluation - eval1 := mockEval() + eval1 := mock.Eval() s1.evalBroker.Enqueue(eval1) // Create a worker @@ -180,7 +181,7 @@ func TestWorker_invokeScheduler(t *testing.T) { defer s1.Shutdown() w := &Worker{srv: s1, logger: s1.logger} - eval := mockEval() + eval := mock.Eval() eval.Type = "noop" err := w.invokeScheduler(eval) @@ -198,11 +199,11 @@ func TestWorker_SubmitPlan(t *testing.T) { testutil.WaitForLeader(t, s1.RPC) // Register node - node := mockNode() + node := mock.Node() testRegisterNode(t, s1, node) // Create an allocation plan - alloc := mockAlloc() + alloc := mock.Alloc() plan := &structs.Plan{ NodeAllocation: map[string][]*structs.Allocation{ node.ID: []*structs.Allocation{alloc}, @@ -243,12 +244,12 @@ func TestWorker_SubmitPlan_MissingNodeRefresh(t *testing.T) { testutil.WaitForLeader(t, s1.RPC) // Register node - node := mockNode() + node := mock.Node() testRegisterNode(t, s1, node) // Create an allocation plan, with unregistered node - node2 := mockNode() - alloc := mockAlloc() + node2 := mock.Node() + alloc := mock.Alloc() plan := &structs.Plan{ NodeAllocation: map[string][]*structs.Allocation{ node2.ID: []*structs.Allocation{alloc},