github.com/ncodes/nomad@v0.5.7-0.20170403112158-97adf4a74fb3/nomad/structs/funcs_test.go (about)

     1  package structs
     2  
     3  import (
     4  	"fmt"
     5  	"regexp"
     6  	"testing"
     7  )
     8  
     9  func TestRemoveAllocs(t *testing.T) {
    10  	l := []*Allocation{
    11  		&Allocation{ID: "foo"},
    12  		&Allocation{ID: "bar"},
    13  		&Allocation{ID: "baz"},
    14  		&Allocation{ID: "zip"},
    15  	}
    16  
    17  	out := RemoveAllocs(l, []*Allocation{l[1], l[3]})
    18  	if len(out) != 2 {
    19  		t.Fatalf("bad: %#v", out)
    20  	}
    21  	if out[0].ID != "foo" && out[1].ID != "baz" {
    22  		t.Fatalf("bad: %#v", out)
    23  	}
    24  }
    25  
    26  func TestFilterTerminalAllocs(t *testing.T) {
    27  	l := []*Allocation{
    28  		&Allocation{
    29  			ID:            "bar",
    30  			Name:          "myname1",
    31  			DesiredStatus: AllocDesiredStatusEvict,
    32  		},
    33  		&Allocation{ID: "baz", DesiredStatus: AllocDesiredStatusStop},
    34  		&Allocation{
    35  			ID:            "foo",
    36  			DesiredStatus: AllocDesiredStatusRun,
    37  			ClientStatus:  AllocClientStatusPending,
    38  		},
    39  		&Allocation{
    40  			ID:            "bam",
    41  			Name:          "myname",
    42  			DesiredStatus: AllocDesiredStatusRun,
    43  			ClientStatus:  AllocClientStatusComplete,
    44  			CreateIndex:   5,
    45  		},
    46  		&Allocation{
    47  			ID:            "lol",
    48  			Name:          "myname",
    49  			DesiredStatus: AllocDesiredStatusRun,
    50  			ClientStatus:  AllocClientStatusComplete,
    51  			CreateIndex:   2,
    52  		},
    53  	}
    54  
    55  	out, terminalAllocs := FilterTerminalAllocs(l)
    56  	if len(out) != 1 {
    57  		t.Fatalf("bad: %#v", out)
    58  	}
    59  	if out[0].ID != "foo" {
    60  		t.Fatalf("bad: %#v", out)
    61  	}
    62  
    63  	if len(terminalAllocs) != 3 {
    64  		for _, o := range terminalAllocs {
    65  			fmt.Printf("%#v \n", o)
    66  		}
    67  
    68  		t.Fatalf("bad: %#v", terminalAllocs)
    69  	}
    70  
    71  	if terminalAllocs["myname"].ID != "bam" {
    72  		t.Fatalf("bad: %#v", terminalAllocs["myname"])
    73  	}
    74  }
    75  
    76  func TestAllocsFit_PortsOvercommitted(t *testing.T) {
    77  	n := &Node{
    78  		Resources: &Resources{
    79  			Networks: []*NetworkResource{
    80  				&NetworkResource{
    81  					Device: "eth0",
    82  					CIDR:   "10.0.0.0/8",
    83  					MBits:  100,
    84  				},
    85  			},
    86  		},
    87  	}
    88  
    89  	a1 := &Allocation{
    90  		Job: &Job{
    91  			TaskGroups: []*TaskGroup{
    92  				{
    93  					Name:          "web",
    94  					EphemeralDisk: DefaultEphemeralDisk(),
    95  				},
    96  			},
    97  		},
    98  		TaskResources: map[string]*Resources{
    99  			"web": &Resources{
   100  				Networks: []*NetworkResource{
   101  					&NetworkResource{
   102  						Device:        "eth0",
   103  						IP:            "10.0.0.1",
   104  						MBits:         50,
   105  						ReservedPorts: []Port{{"main", 8000}},
   106  					},
   107  				},
   108  			},
   109  		},
   110  	}
   111  
   112  	// Should fit one allocation
   113  	fit, dim, _, err := AllocsFit(n, []*Allocation{a1}, nil)
   114  	if err != nil {
   115  		t.Fatalf("err: %v", err)
   116  	}
   117  	if !fit {
   118  		t.Fatalf("Bad: %s", dim)
   119  	}
   120  
   121  	// Should not fit second allocation
   122  	fit, _, _, err = AllocsFit(n, []*Allocation{a1, a1}, nil)
   123  	if err != nil {
   124  		t.Fatalf("err: %v", err)
   125  	}
   126  	if fit {
   127  		t.Fatalf("Bad")
   128  	}
   129  }
   130  
   131  func TestAllocsFit(t *testing.T) {
   132  	n := &Node{
   133  		Resources: &Resources{
   134  			CPU:      2000,
   135  			MemoryMB: 2048,
   136  			DiskMB:   10000,
   137  			IOPS:     100,
   138  			Networks: []*NetworkResource{
   139  				&NetworkResource{
   140  					Device: "eth0",
   141  					CIDR:   "10.0.0.0/8",
   142  					MBits:  100,
   143  				},
   144  			},
   145  		},
   146  		Reserved: &Resources{
   147  			CPU:      1000,
   148  			MemoryMB: 1024,
   149  			DiskMB:   5000,
   150  			IOPS:     50,
   151  			Networks: []*NetworkResource{
   152  				&NetworkResource{
   153  					Device:        "eth0",
   154  					IP:            "10.0.0.1",
   155  					MBits:         50,
   156  					ReservedPorts: []Port{{"main", 80}},
   157  				},
   158  			},
   159  		},
   160  	}
   161  
   162  	a1 := &Allocation{
   163  		Resources: &Resources{
   164  			CPU:      1000,
   165  			MemoryMB: 1024,
   166  			DiskMB:   5000,
   167  			IOPS:     50,
   168  			Networks: []*NetworkResource{
   169  				&NetworkResource{
   170  					Device:        "eth0",
   171  					IP:            "10.0.0.1",
   172  					MBits:         50,
   173  					ReservedPorts: []Port{{"main", 8000}},
   174  				},
   175  			},
   176  		},
   177  	}
   178  
   179  	// Should fit one allocation
   180  	fit, _, used, err := AllocsFit(n, []*Allocation{a1}, nil)
   181  	if err != nil {
   182  		t.Fatalf("err: %v", err)
   183  	}
   184  	if !fit {
   185  		t.Fatalf("Bad")
   186  	}
   187  
   188  	// Sanity check the used resources
   189  	if used.CPU != 2000 {
   190  		t.Fatalf("bad: %#v", used)
   191  	}
   192  	if used.MemoryMB != 2048 {
   193  		t.Fatalf("bad: %#v", used)
   194  	}
   195  
   196  	// Should not fit second allocation
   197  	fit, _, used, err = AllocsFit(n, []*Allocation{a1, a1}, nil)
   198  	if err != nil {
   199  		t.Fatalf("err: %v", err)
   200  	}
   201  	if fit {
   202  		t.Fatalf("Bad")
   203  	}
   204  
   205  	// Sanity check the used resources
   206  	if used.CPU != 3000 {
   207  		t.Fatalf("bad: %#v", used)
   208  	}
   209  	if used.MemoryMB != 3072 {
   210  		t.Fatalf("bad: %#v", used)
   211  	}
   212  
   213  }
   214  
   215  func TestScoreFit(t *testing.T) {
   216  	node := &Node{}
   217  	node.Resources = &Resources{
   218  		CPU:      4096,
   219  		MemoryMB: 8192,
   220  	}
   221  	node.Reserved = &Resources{
   222  		CPU:      2048,
   223  		MemoryMB: 4096,
   224  	}
   225  
   226  	// Test a perfect fit
   227  	util := &Resources{
   228  		CPU:      2048,
   229  		MemoryMB: 4096,
   230  	}
   231  	score := ScoreFit(node, util)
   232  	if score != 18.0 {
   233  		t.Fatalf("bad: %v", score)
   234  	}
   235  
   236  	// Test the worst fit
   237  	util = &Resources{
   238  		CPU:      0,
   239  		MemoryMB: 0,
   240  	}
   241  	score = ScoreFit(node, util)
   242  	if score != 0.0 {
   243  		t.Fatalf("bad: %v", score)
   244  	}
   245  
   246  	// Test a mid-case scenario
   247  	util = &Resources{
   248  		CPU:      1024,
   249  		MemoryMB: 2048,
   250  	}
   251  	score = ScoreFit(node, util)
   252  	if score < 10.0 || score > 16.0 {
   253  		t.Fatalf("bad: %v", score)
   254  	}
   255  }
   256  
   257  func TestGenerateUUID(t *testing.T) {
   258  	prev := GenerateUUID()
   259  	for i := 0; i < 100; i++ {
   260  		id := GenerateUUID()
   261  		if prev == id {
   262  			t.Fatalf("Should get a new ID!")
   263  		}
   264  
   265  		matched, err := regexp.MatchString(
   266  			"[\\da-f]{8}-[\\da-f]{4}-[\\da-f]{4}-[\\da-f]{4}-[\\da-f]{12}", id)
   267  		if !matched || err != nil {
   268  			t.Fatalf("expected match %s %v %s", id, matched, err)
   269  		}
   270  	}
   271  }