github.com/ryanslade/nomad@v0.2.4-0.20160128061903-fc95782f2089/nomad/core_sched_test.go (about)

     1  package nomad
     2  
     3  import (
     4  	"testing"
     5  	"time"
     6  
     7  	"github.com/hashicorp/nomad/nomad/mock"
     8  	"github.com/hashicorp/nomad/nomad/structs"
     9  	"github.com/hashicorp/nomad/testutil"
    10  )
    11  
    12  func TestCoreScheduler_EvalGC(t *testing.T) {
    13  	s1 := testServer(t, nil)
    14  	defer s1.Shutdown()
    15  	testutil.WaitForLeader(t, s1.RPC)
    16  
    17  	// Insert "dead" eval
    18  	state := s1.fsm.State()
    19  	eval := mock.Eval()
    20  	eval.Status = structs.EvalStatusFailed
    21  	err := state.UpsertEvals(1000, []*structs.Evaluation{eval})
    22  	if err != nil {
    23  		t.Fatalf("err: %v", err)
    24  	}
    25  
    26  	// Insert "dead" alloc
    27  	alloc := mock.Alloc()
    28  	alloc.EvalID = eval.ID
    29  	alloc.DesiredStatus = structs.AllocDesiredStatusFailed
    30  	err = state.UpsertAllocs(1001, []*structs.Allocation{alloc})
    31  	if err != nil {
    32  		t.Fatalf("err: %v", err)
    33  	}
    34  
    35  	// Update the time tables to make this work
    36  	tt := s1.fsm.TimeTable()
    37  	tt.Witness(2000, time.Now().UTC().Add(-1*s1.config.EvalGCThreshold))
    38  
    39  	// Create a core scheduler
    40  	snap, err := state.Snapshot()
    41  	if err != nil {
    42  		t.Fatalf("err: %v", err)
    43  	}
    44  	core := NewCoreScheduler(s1, snap)
    45  
    46  	// Attempt the GC
    47  	gc := s1.coreJobEval(structs.CoreJobEvalGC)
    48  	gc.ModifyIndex = 2000
    49  	err = core.Process(gc)
    50  	if err != nil {
    51  		t.Fatalf("err: %v", err)
    52  	}
    53  
    54  	// Should be gone
    55  	out, err := state.EvalByID(eval.ID)
    56  	if err != nil {
    57  		t.Fatalf("err: %v", err)
    58  	}
    59  	if out != nil {
    60  		t.Fatalf("bad: %v", out)
    61  	}
    62  
    63  	outA, err := state.AllocByID(alloc.ID)
    64  	if err != nil {
    65  		t.Fatalf("err: %v", err)
    66  	}
    67  	if outA != nil {
    68  		t.Fatalf("bad: %v", outA)
    69  	}
    70  }
    71  
    72  func TestCoreScheduler_NodeGC(t *testing.T) {
    73  	s1 := testServer(t, nil)
    74  	defer s1.Shutdown()
    75  	testutil.WaitForLeader(t, s1.RPC)
    76  
    77  	// Insert "dead" node
    78  	state := s1.fsm.State()
    79  	node := mock.Node()
    80  	node.Status = structs.NodeStatusDown
    81  	err := state.UpsertNode(1000, node)
    82  	if err != nil {
    83  		t.Fatalf("err: %v", err)
    84  	}
    85  
    86  	// Update the time tables to make this work
    87  	tt := s1.fsm.TimeTable()
    88  	tt.Witness(2000, time.Now().UTC().Add(-1*s1.config.NodeGCThreshold))
    89  
    90  	// Create a core scheduler
    91  	snap, err := state.Snapshot()
    92  	if err != nil {
    93  		t.Fatalf("err: %v", err)
    94  	}
    95  	core := NewCoreScheduler(s1, snap)
    96  
    97  	// Attempt the GC
    98  	gc := s1.coreJobEval(structs.CoreJobNodeGC)
    99  	gc.ModifyIndex = 2000
   100  	err = core.Process(gc)
   101  	if err != nil {
   102  		t.Fatalf("err: %v", err)
   103  	}
   104  
   105  	// Should be gone
   106  	out, err := state.NodeByID(node.ID)
   107  	if err != nil {
   108  		t.Fatalf("err: %v", err)
   109  	}
   110  	if out != nil {
   111  		t.Fatalf("bad: %v", out)
   112  	}
   113  }
   114  
   115  func TestCoreScheduler_JobGC(t *testing.T) {
   116  	tests := []struct {
   117  		test, evalStatus, allocStatus string
   118  		shouldExist                   bool
   119  	}{
   120  		{
   121  			test:        "Terminal",
   122  			evalStatus:  structs.EvalStatusFailed,
   123  			allocStatus: structs.AllocDesiredStatusFailed,
   124  			shouldExist: false,
   125  		},
   126  		{
   127  			test:        "Has Alloc",
   128  			evalStatus:  structs.EvalStatusFailed,
   129  			allocStatus: structs.AllocDesiredStatusRun,
   130  			shouldExist: true,
   131  		},
   132  		{
   133  			test:        "Has Eval",
   134  			evalStatus:  structs.EvalStatusPending,
   135  			allocStatus: structs.AllocDesiredStatusFailed,
   136  			shouldExist: true,
   137  		},
   138  	}
   139  
   140  	for _, test := range tests {
   141  		s1 := testServer(t, nil)
   142  		defer s1.Shutdown()
   143  		testutil.WaitForLeader(t, s1.RPC)
   144  
   145  		// Insert job.
   146  		state := s1.fsm.State()
   147  		job := mock.Job()
   148  		job.GC = true
   149  		err := state.UpsertJob(1000, job)
   150  		if err != nil {
   151  			t.Fatalf("test(%s) err: %v", test.test, err)
   152  		}
   153  
   154  		// Insert eval
   155  		eval := mock.Eval()
   156  		eval.JobID = job.ID
   157  		eval.Status = test.evalStatus
   158  		err = state.UpsertEvals(1001, []*structs.Evaluation{eval})
   159  		if err != nil {
   160  			t.Fatalf("test(%s) err: %v", test.test, err)
   161  		}
   162  
   163  		// Insert alloc
   164  		alloc := mock.Alloc()
   165  		alloc.JobID = job.ID
   166  		alloc.EvalID = eval.ID
   167  		alloc.DesiredStatus = test.allocStatus
   168  		err = state.UpsertAllocs(1002, []*structs.Allocation{alloc})
   169  		if err != nil {
   170  			t.Fatalf("test(%s) err: %v", test.test, err)
   171  		}
   172  
   173  		// Update the time tables to make this work
   174  		tt := s1.fsm.TimeTable()
   175  		tt.Witness(2000, time.Now().UTC().Add(-1*s1.config.JobGCThreshold))
   176  
   177  		// Create a core scheduler
   178  		snap, err := state.Snapshot()
   179  		if err != nil {
   180  			t.Fatalf("test(%s) err: %v", test.test, err)
   181  		}
   182  		core := NewCoreScheduler(s1, snap)
   183  
   184  		// Attempt the GC
   185  		gc := s1.coreJobEval(structs.CoreJobJobGC)
   186  		gc.ModifyIndex = 2000
   187  		err = core.Process(gc)
   188  		if err != nil {
   189  			t.Fatalf("test(%s) err: %v", test.test, err)
   190  		}
   191  
   192  		// Should still exist
   193  		out, err := state.JobByID(job.ID)
   194  		if err != nil {
   195  			t.Fatalf("test(%s) err: %v", test.test, err)
   196  		}
   197  		if (test.shouldExist && out == nil) || (!test.shouldExist && out != nil) {
   198  			t.Fatalf("test(%s) bad: %v", test.test, out)
   199  		}
   200  
   201  		outE, err := state.EvalByID(eval.ID)
   202  		if err != nil {
   203  			t.Fatalf("test(%s) err: %v", test.test, err)
   204  		}
   205  		if (test.shouldExist && outE == nil) || (!test.shouldExist && outE != nil) {
   206  			t.Fatalf("test(%s) bad: %v", test.test, out)
   207  		}
   208  
   209  		outA, err := state.AllocByID(alloc.ID)
   210  		if err != nil {
   211  			t.Fatalf("test(%s) err: %v", test.test, err)
   212  		}
   213  		if (test.shouldExist && outA == nil) || (!test.shouldExist && outA != nil) {
   214  			t.Fatalf("test(%s) bad: %v", test.test, outA)
   215  		}
   216  	}
   217  }