github.com/kardianos/nomad@v0.1.3-0.20151022182107-b13df73ee850/nomad/structs/structs_test.go (about)

     1  package structs
     2  
     3  import (
     4  	"reflect"
     5  	"strings"
     6  	"testing"
     7  
     8  	"github.com/hashicorp/go-multierror"
     9  )
    10  
    11  func TestJob_Validate(t *testing.T) {
    12  	j := &Job{}
    13  	err := j.Validate()
    14  	mErr := err.(*multierror.Error)
    15  	if !strings.Contains(mErr.Errors[0].Error(), "job region") {
    16  		t.Fatalf("err: %s", err)
    17  	}
    18  	if !strings.Contains(mErr.Errors[1].Error(), "job ID") {
    19  		t.Fatalf("err: %s", err)
    20  	}
    21  	if !strings.Contains(mErr.Errors[2].Error(), "job name") {
    22  		t.Fatalf("err: %s", err)
    23  	}
    24  	if !strings.Contains(mErr.Errors[3].Error(), "job type") {
    25  		t.Fatalf("err: %s", err)
    26  	}
    27  	if !strings.Contains(mErr.Errors[4].Error(), "priority") {
    28  		t.Fatalf("err: %s", err)
    29  	}
    30  	if !strings.Contains(mErr.Errors[5].Error(), "datacenters") {
    31  		t.Fatalf("err: %s", err)
    32  	}
    33  	if !strings.Contains(mErr.Errors[6].Error(), "task groups") {
    34  		t.Fatalf("err: %s", err)
    35  	}
    36  
    37  	j = &Job{
    38  		Region:      "global",
    39  		ID:          GenerateUUID(),
    40  		Name:        "my-job",
    41  		Type:        JobTypeService,
    42  		Priority:    50,
    43  		Datacenters: []string{"dc1"},
    44  		TaskGroups: []*TaskGroup{
    45  			&TaskGroup{
    46  				Name: "web",
    47  			},
    48  			&TaskGroup{
    49  				Name: "web",
    50  			},
    51  			&TaskGroup{},
    52  		},
    53  	}
    54  	err = j.Validate()
    55  	mErr = err.(*multierror.Error)
    56  	if !strings.Contains(mErr.Errors[0].Error(), "2 redefines 'web' from group 1") {
    57  		t.Fatalf("err: %s", err)
    58  	}
    59  	if !strings.Contains(mErr.Errors[1].Error(), "group 3 missing name") {
    60  		t.Fatalf("err: %s", err)
    61  	}
    62  	if !strings.Contains(mErr.Errors[2].Error(), "Task group 1 validation failed") {
    63  		t.Fatalf("err: %s", err)
    64  	}
    65  }
    66  
    67  func TestTaskGroup_Validate(t *testing.T) {
    68  	tg := &TaskGroup{}
    69  	err := tg.Validate()
    70  	mErr := err.(*multierror.Error)
    71  	if !strings.Contains(mErr.Errors[0].Error(), "group name") {
    72  		t.Fatalf("err: %s", err)
    73  	}
    74  	if !strings.Contains(mErr.Errors[1].Error(), "count must be positive") {
    75  		t.Fatalf("err: %s", err)
    76  	}
    77  	if !strings.Contains(mErr.Errors[2].Error(), "Missing tasks") {
    78  		t.Fatalf("err: %s", err)
    79  	}
    80  
    81  	tg = &TaskGroup{
    82  		Name:  "web",
    83  		Count: 1,
    84  		Tasks: []*Task{
    85  			&Task{Name: "web"},
    86  			&Task{Name: "web"},
    87  			&Task{},
    88  		},
    89  	}
    90  	err = tg.Validate()
    91  	mErr = err.(*multierror.Error)
    92  	if !strings.Contains(mErr.Errors[0].Error(), "2 redefines 'web' from task 1") {
    93  		t.Fatalf("err: %s", err)
    94  	}
    95  	if !strings.Contains(mErr.Errors[1].Error(), "Task 3 missing name") {
    96  		t.Fatalf("err: %s", err)
    97  	}
    98  	if !strings.Contains(mErr.Errors[2].Error(), "Task 1 validation failed") {
    99  		t.Fatalf("err: %s", err)
   100  	}
   101  }
   102  
   103  func TestTask_Validate(t *testing.T) {
   104  	task := &Task{}
   105  	err := task.Validate()
   106  	mErr := err.(*multierror.Error)
   107  	if !strings.Contains(mErr.Errors[0].Error(), "task name") {
   108  		t.Fatalf("err: %s", err)
   109  	}
   110  	if !strings.Contains(mErr.Errors[1].Error(), "task driver") {
   111  		t.Fatalf("err: %s", err)
   112  	}
   113  	if !strings.Contains(mErr.Errors[2].Error(), "task resources") {
   114  		t.Fatalf("err: %s", err)
   115  	}
   116  
   117  	task = &Task{
   118  		Name:      "web",
   119  		Driver:    "docker",
   120  		Resources: &Resources{},
   121  	}
   122  	err = task.Validate()
   123  	if err != nil {
   124  		t.Fatalf("err: %s", err)
   125  	}
   126  }
   127  
   128  func TestConstraint_Validate(t *testing.T) {
   129  	c := &Constraint{}
   130  	err := c.Validate()
   131  	mErr := err.(*multierror.Error)
   132  	if !strings.Contains(mErr.Errors[0].Error(), "Missing constraint operand") {
   133  		t.Fatalf("err: %s", err)
   134  	}
   135  
   136  	c = &Constraint{
   137  		LTarget: "$attr.kernel.name",
   138  		RTarget: "linux",
   139  		Operand: "=",
   140  	}
   141  	err = c.Validate()
   142  	if err != nil {
   143  		t.Fatalf("err: %v", err)
   144  	}
   145  
   146  	// Perform additional regexp validation
   147  	c.Operand = "regexp"
   148  	c.RTarget = "(foo"
   149  	err = c.Validate()
   150  	mErr = err.(*multierror.Error)
   151  	if !strings.Contains(mErr.Errors[0].Error(), "missing closing") {
   152  		t.Fatalf("err: %s", err)
   153  	}
   154  
   155  	// Perform version validation
   156  	c.Operand = "version"
   157  	c.RTarget = "~> foo"
   158  	err = c.Validate()
   159  	mErr = err.(*multierror.Error)
   160  	if !strings.Contains(mErr.Errors[0].Error(), "Malformed constraint") {
   161  		t.Fatalf("err: %s", err)
   162  	}
   163  }
   164  
   165  func TestResource_NetIndex(t *testing.T) {
   166  	r := &Resources{
   167  		Networks: []*NetworkResource{
   168  			&NetworkResource{Device: "eth0"},
   169  			&NetworkResource{Device: "lo0"},
   170  			&NetworkResource{Device: ""},
   171  		},
   172  	}
   173  	if idx := r.NetIndex(&NetworkResource{Device: "eth0"}); idx != 0 {
   174  		t.Fatalf("Bad: %d", idx)
   175  	}
   176  	if idx := r.NetIndex(&NetworkResource{Device: "lo0"}); idx != 1 {
   177  		t.Fatalf("Bad: %d", idx)
   178  	}
   179  	if idx := r.NetIndex(&NetworkResource{Device: "eth1"}); idx != -1 {
   180  		t.Fatalf("Bad: %d", idx)
   181  	}
   182  }
   183  
   184  func TestResource_Superset(t *testing.T) {
   185  	r1 := &Resources{
   186  		CPU:      2000,
   187  		MemoryMB: 2048,
   188  		DiskMB:   10000,
   189  		IOPS:     100,
   190  	}
   191  	r2 := &Resources{
   192  		CPU:      2000,
   193  		MemoryMB: 1024,
   194  		DiskMB:   5000,
   195  		IOPS:     50,
   196  	}
   197  
   198  	if s, _ := r1.Superset(r1); !s {
   199  		t.Fatalf("bad")
   200  	}
   201  	if s, _ := r1.Superset(r2); !s {
   202  		t.Fatalf("bad")
   203  	}
   204  	if s, _ := r2.Superset(r1); s {
   205  		t.Fatalf("bad")
   206  	}
   207  	if s, _ := r2.Superset(r2); !s {
   208  		t.Fatalf("bad")
   209  	}
   210  }
   211  
   212  func TestResource_Add(t *testing.T) {
   213  	r1 := &Resources{
   214  		CPU:      2000,
   215  		MemoryMB: 2048,
   216  		DiskMB:   10000,
   217  		IOPS:     100,
   218  		Networks: []*NetworkResource{
   219  			&NetworkResource{
   220  				CIDR:          "10.0.0.0/8",
   221  				MBits:         100,
   222  				ReservedPorts: []int{22},
   223  			},
   224  		},
   225  	}
   226  	r2 := &Resources{
   227  		CPU:      2000,
   228  		MemoryMB: 1024,
   229  		DiskMB:   5000,
   230  		IOPS:     50,
   231  		Networks: []*NetworkResource{
   232  			&NetworkResource{
   233  				IP:            "10.0.0.1",
   234  				MBits:         50,
   235  				ReservedPorts: []int{80},
   236  			},
   237  		},
   238  	}
   239  
   240  	err := r1.Add(r2)
   241  	if err != nil {
   242  		t.Fatalf("Err: %v", err)
   243  	}
   244  
   245  	expect := &Resources{
   246  		CPU:      3000,
   247  		MemoryMB: 3072,
   248  		DiskMB:   15000,
   249  		IOPS:     150,
   250  		Networks: []*NetworkResource{
   251  			&NetworkResource{
   252  				CIDR:          "10.0.0.0/8",
   253  				MBits:         150,
   254  				ReservedPorts: []int{22, 80},
   255  			},
   256  		},
   257  	}
   258  
   259  	if !reflect.DeepEqual(expect.Networks, r1.Networks) {
   260  		t.Fatalf("bad: %#v %#v", expect, r1)
   261  	}
   262  }
   263  
   264  func TestResource_Add_Network(t *testing.T) {
   265  	r1 := &Resources{}
   266  	r2 := &Resources{
   267  		Networks: []*NetworkResource{
   268  			&NetworkResource{
   269  				MBits:        50,
   270  				DynamicPorts: []string{"http", "https"},
   271  			},
   272  		},
   273  	}
   274  	r3 := &Resources{
   275  		Networks: []*NetworkResource{
   276  			&NetworkResource{
   277  				MBits:        25,
   278  				DynamicPorts: []string{"admin"},
   279  			},
   280  		},
   281  	}
   282  
   283  	err := r1.Add(r2)
   284  	if err != nil {
   285  		t.Fatalf("Err: %v", err)
   286  	}
   287  	err = r1.Add(r3)
   288  	if err != nil {
   289  		t.Fatalf("Err: %v", err)
   290  	}
   291  
   292  	expect := &Resources{
   293  		Networks: []*NetworkResource{
   294  			&NetworkResource{
   295  				MBits:        75,
   296  				DynamicPorts: []string{"http", "https", "admin"},
   297  			},
   298  		},
   299  	}
   300  
   301  	if !reflect.DeepEqual(expect.Networks, r1.Networks) {
   302  		t.Fatalf("bad: %#v %#v", expect.Networks[0], r1.Networks[0])
   303  	}
   304  }
   305  
   306  func TestMapDynamicPorts(t *testing.T) {
   307  	resources := &NetworkResource{
   308  		ReservedPorts: []int{80, 443, 3306, 8080},
   309  		DynamicPorts:  []string{"mysql", "admin"},
   310  	}
   311  
   312  	expected := map[string]int{
   313  		"mysql": 3306,
   314  		"admin": 8080,
   315  	}
   316  	actual := resources.MapDynamicPorts()
   317  
   318  	if !reflect.DeepEqual(expected, actual) {
   319  		t.Fatalf("Expected %#v; found %#v", expected, actual)
   320  	}
   321  }
   322  
   323  func TestMapDynamicPortsEmpty(t *testing.T) {
   324  	resources := &NetworkResource{
   325  		ReservedPorts: []int{},
   326  		DynamicPorts:  []string{},
   327  	}
   328  
   329  	expected := map[string]int{}
   330  	actual := resources.MapDynamicPorts()
   331  
   332  	if !reflect.DeepEqual(expected, actual) {
   333  		t.Fatalf("Expected %#v; found %#v", expected, actual)
   334  	}
   335  }
   336  
   337  func TestMapDynamicPortsStaticOnly(t *testing.T) {
   338  	resources := &NetworkResource{
   339  		ReservedPorts: []int{80, 443},
   340  		DynamicPorts:  []string{},
   341  	}
   342  
   343  	expected := map[string]int{}
   344  	actual := resources.MapDynamicPorts()
   345  
   346  	if !reflect.DeepEqual(expected, actual) {
   347  		t.Fatalf("Expected %#v; found %#v", expected, actual)
   348  	}
   349  }
   350  
   351  func TestMapDynamicPortsOnly(t *testing.T) {
   352  	resources := &NetworkResource{
   353  		ReservedPorts: []int{3306, 8080},
   354  		DynamicPorts:  []string{"mysql", "admin"},
   355  	}
   356  
   357  	expected := map[string]int{
   358  		"mysql": 3306,
   359  		"admin": 8080,
   360  	}
   361  	actual := resources.MapDynamicPorts()
   362  
   363  	if !reflect.DeepEqual(expected, actual) {
   364  		t.Fatalf("Expected %#v; found %#v", expected, actual)
   365  	}
   366  }
   367  
   368  func TestListStaticPorts(t *testing.T) {
   369  	resources := &NetworkResource{
   370  		ReservedPorts: []int{80, 443, 3306, 8080},
   371  		DynamicPorts:  []string{"mysql", "admin"},
   372  	}
   373  
   374  	expected := []int{80, 443}
   375  	actual := resources.ListStaticPorts()
   376  
   377  	if !reflect.DeepEqual(expected, actual) {
   378  		t.Fatalf("Expected %#v; found %#v", expected, actual)
   379  	}
   380  }
   381  
   382  func TestListStaticPortsEmpty(t *testing.T) {
   383  	resources := &NetworkResource{
   384  		ReservedPorts: []int{},
   385  		DynamicPorts:  []string{},
   386  	}
   387  
   388  	expected := []int{}
   389  	actual := resources.ListStaticPorts()
   390  
   391  	if !reflect.DeepEqual(expected, actual) {
   392  		t.Fatalf("Expected %#v; found %#v", expected, actual)
   393  	}
   394  }
   395  
   396  func TestListStaticPortsOnly(t *testing.T) {
   397  	resources := &NetworkResource{
   398  		ReservedPorts: []int{80, 443},
   399  		DynamicPorts:  []string{},
   400  	}
   401  
   402  	expected := []int{80, 443}
   403  	actual := resources.ListStaticPorts()
   404  
   405  	if !reflect.DeepEqual(expected, actual) {
   406  		t.Fatalf("Expected %#v; found %#v", expected, actual)
   407  	}
   408  }
   409  
   410  func TestListStaticPortsDynamicOnly(t *testing.T) {
   411  	resources := &NetworkResource{
   412  		ReservedPorts: []int{3306, 8080},
   413  		DynamicPorts:  []string{"mysql", "admin"},
   414  	}
   415  
   416  	expected := []int{}
   417  	actual := resources.ListStaticPorts()
   418  
   419  	if !reflect.DeepEqual(expected, actual) {
   420  		t.Fatalf("Expected %#v; found %#v", expected, actual)
   421  	}
   422  }
   423  
   424  func TestEncodeDecode(t *testing.T) {
   425  	type FooRequest struct {
   426  		Foo string
   427  		Bar int
   428  		Baz bool
   429  	}
   430  	arg := &FooRequest{
   431  		Foo: "test",
   432  		Bar: 42,
   433  		Baz: true,
   434  	}
   435  	buf, err := Encode(1, arg)
   436  	if err != nil {
   437  		t.Fatalf("err: %v", err)
   438  	}
   439  
   440  	var out FooRequest
   441  	err = Decode(buf[1:], &out)
   442  	if err != nil {
   443  		t.Fatalf("err: %v", err)
   444  	}
   445  
   446  	if !reflect.DeepEqual(arg, &out) {
   447  		t.Fatalf("bad: %#v %#v", arg, out)
   448  	}
   449  }