github.com/hspak/nomad@v0.7.2-0.20180309000617-bc4ae22a39a5/api/nodes_test.go (about)

     1  package api
     2  
     3  import (
     4  	"fmt"
     5  	"reflect"
     6  	"sort"
     7  	"strings"
     8  	"testing"
     9  	"time"
    10  
    11  	"github.com/hashicorp/nomad/helper/uuid"
    12  	"github.com/hashicorp/nomad/nomad/structs"
    13  	"github.com/hashicorp/nomad/testutil"
    14  	"github.com/stretchr/testify/require"
    15  )
    16  
    17  func TestNodes_List(t *testing.T) {
    18  	t.Parallel()
    19  	c, s := makeClient(t, nil, func(c *testutil.TestServerConfig) {
    20  		c.DevMode = true
    21  	})
    22  	defer s.Stop()
    23  	nodes := c.Nodes()
    24  
    25  	var qm *QueryMeta
    26  	var out []*NodeListStub
    27  	var err error
    28  
    29  	testutil.WaitForResult(func() (bool, error) {
    30  		out, qm, err = nodes.List(nil)
    31  		if err != nil {
    32  			return false, err
    33  		}
    34  		if n := len(out); n != 1 {
    35  			return false, fmt.Errorf("expected 1 node, got: %d", n)
    36  		}
    37  		return true, nil
    38  	}, func(err error) {
    39  		t.Fatalf("err: %s", err)
    40  	})
    41  
    42  	// Check that we got valid QueryMeta.
    43  	assertQueryMeta(t, qm)
    44  }
    45  
    46  func TestNodes_PrefixList(t *testing.T) {
    47  	t.Parallel()
    48  	c, s := makeClient(t, nil, func(c *testutil.TestServerConfig) {
    49  		c.DevMode = true
    50  	})
    51  	defer s.Stop()
    52  	nodes := c.Nodes()
    53  
    54  	var qm *QueryMeta
    55  	var out []*NodeListStub
    56  	var err error
    57  
    58  	// Get the node ID
    59  	var nodeID string
    60  	testutil.WaitForResult(func() (bool, error) {
    61  		out, _, err := nodes.List(nil)
    62  		if err != nil {
    63  			return false, err
    64  		}
    65  		if n := len(out); n != 1 {
    66  			return false, fmt.Errorf("expected 1 node, got: %d", n)
    67  		}
    68  		nodeID = out[0].ID
    69  		return true, nil
    70  	}, func(err error) {
    71  		t.Fatalf("err: %s", err)
    72  	})
    73  
    74  	// Find node based on four character prefix
    75  	out, qm, err = nodes.PrefixList(nodeID[:4])
    76  	if err != nil {
    77  		t.Fatalf("err: %s", err)
    78  	}
    79  	if n := len(out); n != 1 {
    80  		t.Fatalf("expected 1 node, got: %d ", n)
    81  	}
    82  
    83  	// Check that we got valid QueryMeta.
    84  	assertQueryMeta(t, qm)
    85  }
    86  
    87  func TestNodes_Info(t *testing.T) {
    88  	t.Parallel()
    89  	startTime := time.Now().Unix()
    90  	c, s := makeClient(t, nil, func(c *testutil.TestServerConfig) {
    91  		c.DevMode = true
    92  	})
    93  	defer s.Stop()
    94  	nodes := c.Nodes()
    95  
    96  	// Retrieving a non-existent node returns error
    97  	_, _, err := nodes.Info("12345678-abcd-efab-cdef-123456789abc", nil)
    98  	if err == nil || !strings.Contains(err.Error(), "not found") {
    99  		t.Fatalf("expected not found error, got: %#v", err)
   100  	}
   101  
   102  	// Get the node ID
   103  	var nodeID, dc string
   104  	testutil.WaitForResult(func() (bool, error) {
   105  		out, _, err := nodes.List(nil)
   106  		if err != nil {
   107  			return false, err
   108  		}
   109  		if n := len(out); n != 1 {
   110  			return false, fmt.Errorf("expected 1 node, got: %d", n)
   111  		}
   112  		nodeID = out[0].ID
   113  		dc = out[0].Datacenter
   114  		return true, nil
   115  	}, func(err error) {
   116  		t.Fatalf("err: %s", err)
   117  	})
   118  
   119  	// Querying for existing nodes returns properly
   120  	result, qm, err := nodes.Info(nodeID, nil)
   121  	if err != nil {
   122  		t.Fatalf("err: %s", err)
   123  	}
   124  	assertQueryMeta(t, qm)
   125  
   126  	// Check that the result is what we expect
   127  	if result.ID != nodeID || result.Datacenter != dc {
   128  		t.Fatalf("expected %s (%s), got: %s (%s)",
   129  			nodeID, dc,
   130  			result.ID, result.Datacenter)
   131  	}
   132  
   133  	// Check that the StatusUpdatedAt field is being populated correctly
   134  	if result.StatusUpdatedAt < startTime {
   135  		t.Fatalf("start time: %v, status updated: %v", startTime, result.StatusUpdatedAt)
   136  	}
   137  }
   138  
   139  func TestNodes_ToggleDrain(t *testing.T) {
   140  	t.Parallel()
   141  	c, s := makeClient(t, nil, func(c *testutil.TestServerConfig) {
   142  		c.DevMode = true
   143  	})
   144  	defer s.Stop()
   145  	nodes := c.Nodes()
   146  
   147  	// Wait for node registration and get the ID
   148  	var nodeID string
   149  	testutil.WaitForResult(func() (bool, error) {
   150  		out, _, err := nodes.List(nil)
   151  		if err != nil {
   152  			return false, err
   153  		}
   154  		if n := len(out); n != 1 {
   155  			return false, fmt.Errorf("expected 1 node, got: %d", n)
   156  		}
   157  		nodeID = out[0].ID
   158  		return true, nil
   159  	}, func(err error) {
   160  		t.Fatalf("err: %s", err)
   161  	})
   162  
   163  	// Check for drain mode
   164  	out, _, err := nodes.Info(nodeID, nil)
   165  	if err != nil {
   166  		t.Fatalf("err: %s", err)
   167  	}
   168  	if out.Drain {
   169  		t.Fatalf("drain mode should be off")
   170  	}
   171  
   172  	// Toggle it on
   173  	wm, err := nodes.ToggleDrain(nodeID, true, nil)
   174  	if err != nil {
   175  		t.Fatalf("err: %s", err)
   176  	}
   177  	assertWriteMeta(t, wm)
   178  
   179  	// Check again
   180  	out, _, err = nodes.Info(nodeID, nil)
   181  	if err != nil {
   182  		t.Fatalf("err: %s", err)
   183  	}
   184  	if !out.Drain {
   185  		t.Fatalf("drain mode should be on")
   186  	}
   187  
   188  	// Toggle off again
   189  	wm, err = nodes.ToggleDrain(nodeID, false, nil)
   190  	if err != nil {
   191  		t.Fatalf("err: %s", err)
   192  	}
   193  	assertWriteMeta(t, wm)
   194  
   195  	// Check again
   196  	out, _, err = nodes.Info(nodeID, nil)
   197  	if err != nil {
   198  		t.Fatalf("err: %s", err)
   199  	}
   200  	if out.Drain {
   201  		t.Fatalf("drain mode should be off")
   202  	}
   203  }
   204  
   205  func TestNodes_Allocations(t *testing.T) {
   206  	t.Parallel()
   207  	c, s := makeClient(t, nil, nil)
   208  	defer s.Stop()
   209  	nodes := c.Nodes()
   210  
   211  	// Looking up by a non-existent node returns nothing. We
   212  	// don't check the index here because it's possible the node
   213  	// has already registered, in which case we will get a non-
   214  	// zero result anyways.
   215  	allocs, _, err := nodes.Allocations("nope", nil)
   216  	if err != nil {
   217  		t.Fatalf("err: %s", err)
   218  	}
   219  	if n := len(allocs); n != 0 {
   220  		t.Fatalf("expected 0 allocs, got: %d", n)
   221  	}
   222  }
   223  
   224  func TestNodes_ForceEvaluate(t *testing.T) {
   225  	t.Parallel()
   226  	c, s := makeClient(t, nil, func(c *testutil.TestServerConfig) {
   227  		c.DevMode = true
   228  	})
   229  	defer s.Stop()
   230  	nodes := c.Nodes()
   231  
   232  	// Force-eval on a non-existent node fails
   233  	_, _, err := nodes.ForceEvaluate("12345678-abcd-efab-cdef-123456789abc", nil)
   234  	if err == nil || !strings.Contains(err.Error(), "not found") {
   235  		t.Fatalf("expected not found error, got: %#v", err)
   236  	}
   237  
   238  	// Wait for node registration and get the ID
   239  	var nodeID string
   240  	testutil.WaitForResult(func() (bool, error) {
   241  		out, _, err := nodes.List(nil)
   242  		if err != nil {
   243  			return false, err
   244  		}
   245  		if n := len(out); n != 1 {
   246  			return false, fmt.Errorf("expected 1 node, got: %d", n)
   247  		}
   248  		nodeID = out[0].ID
   249  		return true, nil
   250  	}, func(err error) {
   251  		t.Fatalf("err: %s", err)
   252  	})
   253  
   254  	// Try force-eval again. We don't check the WriteMeta because
   255  	// there are no allocations to process, so we would get an index
   256  	// of zero. Same goes for the eval ID.
   257  	_, _, err = nodes.ForceEvaluate(nodeID, nil)
   258  	if err != nil {
   259  		t.Fatalf("err: %s", err)
   260  	}
   261  }
   262  
   263  func TestNodes_Sort(t *testing.T) {
   264  	t.Parallel()
   265  	nodes := []*NodeListStub{
   266  		{CreateIndex: 2},
   267  		{CreateIndex: 1},
   268  		{CreateIndex: 5},
   269  	}
   270  	sort.Sort(NodeIndexSort(nodes))
   271  
   272  	expect := []*NodeListStub{
   273  		{CreateIndex: 5},
   274  		{CreateIndex: 2},
   275  		{CreateIndex: 1},
   276  	}
   277  	if !reflect.DeepEqual(nodes, expect) {
   278  		t.Fatalf("\n\n%#v\n\n%#v", nodes, expect)
   279  	}
   280  }
   281  
   282  func TestNodes_GC(t *testing.T) {
   283  	t.Parallel()
   284  	require := require.New(t)
   285  	c, s := makeClient(t, nil, nil)
   286  	defer s.Stop()
   287  	nodes := c.Nodes()
   288  
   289  	err := nodes.GC(uuid.Generate(), nil)
   290  	require.NotNil(err)
   291  	require.True(structs.IsErrUnknownNode(err))
   292  }
   293  
   294  func TestNodes_GcAlloc(t *testing.T) {
   295  	t.Parallel()
   296  	require := require.New(t)
   297  	c, s := makeClient(t, nil, nil)
   298  	defer s.Stop()
   299  	nodes := c.Nodes()
   300  
   301  	err := nodes.GcAlloc(uuid.Generate(), nil)
   302  	require.NotNil(err)
   303  	require.True(structs.IsErrUnknownAllocation(err))
   304  }