github.com/huiliang/nomad@v0.2.1-0.20151124023127-7a8b664699ff/nomad/structs/structs_test.go (about)

     1  package structs
     2  
     3  import (
     4  	"github.com/hashicorp/go-multierror"
     5  	"reflect"
     6  	"strings"
     7  	"testing"
     8  	"time"
     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  				RestartPolicy: &RestartPolicy{
    48  					Interval: 5 * time.Minute,
    49  					Delay:    10 * time.Second,
    50  					Attempts: 10,
    51  				},
    52  			},
    53  			&TaskGroup{
    54  				Name: "web",
    55  				RestartPolicy: &RestartPolicy{
    56  					Interval: 5 * time.Minute,
    57  					Delay:    10 * time.Second,
    58  					Attempts: 10,
    59  				},
    60  			},
    61  			&TaskGroup{
    62  				RestartPolicy: &RestartPolicy{
    63  					Interval: 5 * time.Minute,
    64  					Delay:    10 * time.Second,
    65  					Attempts: 10,
    66  				},
    67  			},
    68  		},
    69  	}
    70  	err = j.Validate()
    71  	mErr = err.(*multierror.Error)
    72  	if !strings.Contains(mErr.Errors[0].Error(), "2 redefines 'web' from group 1") {
    73  		t.Fatalf("err: %s", err)
    74  	}
    75  	if !strings.Contains(mErr.Errors[1].Error(), "group 3 missing name") {
    76  		t.Fatalf("err: %s", err)
    77  	}
    78  	if !strings.Contains(mErr.Errors[2].Error(), "Task group 1 validation failed") {
    79  		t.Fatalf("err: %s", err)
    80  	}
    81  }
    82  
    83  func TestTaskGroup_Validate(t *testing.T) {
    84  	tg := &TaskGroup{
    85  		RestartPolicy: &RestartPolicy{
    86  			Interval: 5 * time.Minute,
    87  			Delay:    10 * time.Second,
    88  			Attempts: 10,
    89  		},
    90  	}
    91  	err := tg.Validate()
    92  	mErr := err.(*multierror.Error)
    93  	if !strings.Contains(mErr.Errors[0].Error(), "group name") {
    94  		t.Fatalf("err: %s", err)
    95  	}
    96  	if !strings.Contains(mErr.Errors[1].Error(), "count must be positive") {
    97  		t.Fatalf("err: %s", err)
    98  	}
    99  	if !strings.Contains(mErr.Errors[2].Error(), "Missing tasks") {
   100  		t.Fatalf("err: %s", err)
   101  	}
   102  
   103  	tg = &TaskGroup{
   104  		Name:  "web",
   105  		Count: 1,
   106  		Tasks: []*Task{
   107  			&Task{Name: "web"},
   108  			&Task{Name: "web"},
   109  			&Task{},
   110  		},
   111  		RestartPolicy: &RestartPolicy{
   112  			Interval: 5 * time.Minute,
   113  			Delay:    10 * time.Second,
   114  			Attempts: 10,
   115  		},
   116  	}
   117  	err = tg.Validate()
   118  	mErr = err.(*multierror.Error)
   119  	if !strings.Contains(mErr.Errors[0].Error(), "2 redefines 'web' from task 1") {
   120  		t.Fatalf("err: %s", err)
   121  	}
   122  	if !strings.Contains(mErr.Errors[1].Error(), "Task 3 missing name") {
   123  		t.Fatalf("err: %s", err)
   124  	}
   125  	if !strings.Contains(mErr.Errors[2].Error(), "Task 1 validation failed") {
   126  		t.Fatalf("err: %s", err)
   127  	}
   128  }
   129  
   130  func TestTask_Validate(t *testing.T) {
   131  	task := &Task{}
   132  	err := task.Validate()
   133  	mErr := err.(*multierror.Error)
   134  	if !strings.Contains(mErr.Errors[0].Error(), "task name") {
   135  		t.Fatalf("err: %s", err)
   136  	}
   137  	if !strings.Contains(mErr.Errors[1].Error(), "task driver") {
   138  		t.Fatalf("err: %s", err)
   139  	}
   140  	if !strings.Contains(mErr.Errors[2].Error(), "task resources") {
   141  		t.Fatalf("err: %s", err)
   142  	}
   143  
   144  	task = &Task{
   145  		Name:      "web",
   146  		Driver:    "docker",
   147  		Resources: &Resources{},
   148  	}
   149  	err = task.Validate()
   150  	if err != nil {
   151  		t.Fatalf("err: %s", err)
   152  	}
   153  }
   154  
   155  func TestConstraint_Validate(t *testing.T) {
   156  	c := &Constraint{}
   157  	err := c.Validate()
   158  	mErr := err.(*multierror.Error)
   159  	if !strings.Contains(mErr.Errors[0].Error(), "Missing constraint operand") {
   160  		t.Fatalf("err: %s", err)
   161  	}
   162  
   163  	c = &Constraint{
   164  		LTarget: "$attr.kernel.name",
   165  		RTarget: "linux",
   166  		Operand: "=",
   167  	}
   168  	err = c.Validate()
   169  	if err != nil {
   170  		t.Fatalf("err: %v", err)
   171  	}
   172  
   173  	// Perform additional regexp validation
   174  	c.Operand = ConstraintRegex
   175  	c.RTarget = "(foo"
   176  	err = c.Validate()
   177  	mErr = err.(*multierror.Error)
   178  	if !strings.Contains(mErr.Errors[0].Error(), "missing closing") {
   179  		t.Fatalf("err: %s", err)
   180  	}
   181  
   182  	// Perform version validation
   183  	c.Operand = ConstraintVersion
   184  	c.RTarget = "~> foo"
   185  	err = c.Validate()
   186  	mErr = err.(*multierror.Error)
   187  	if !strings.Contains(mErr.Errors[0].Error(), "Malformed constraint") {
   188  		t.Fatalf("err: %s", err)
   189  	}
   190  }
   191  
   192  func TestResource_NetIndex(t *testing.T) {
   193  	r := &Resources{
   194  		Networks: []*NetworkResource{
   195  			&NetworkResource{Device: "eth0"},
   196  			&NetworkResource{Device: "lo0"},
   197  			&NetworkResource{Device: ""},
   198  		},
   199  	}
   200  	if idx := r.NetIndex(&NetworkResource{Device: "eth0"}); idx != 0 {
   201  		t.Fatalf("Bad: %d", idx)
   202  	}
   203  	if idx := r.NetIndex(&NetworkResource{Device: "lo0"}); idx != 1 {
   204  		t.Fatalf("Bad: %d", idx)
   205  	}
   206  	if idx := r.NetIndex(&NetworkResource{Device: "eth1"}); idx != -1 {
   207  		t.Fatalf("Bad: %d", idx)
   208  	}
   209  }
   210  
   211  func TestResource_Superset(t *testing.T) {
   212  	r1 := &Resources{
   213  		CPU:      2000,
   214  		MemoryMB: 2048,
   215  		DiskMB:   10000,
   216  		IOPS:     100,
   217  	}
   218  	r2 := &Resources{
   219  		CPU:      2000,
   220  		MemoryMB: 1024,
   221  		DiskMB:   5000,
   222  		IOPS:     50,
   223  	}
   224  
   225  	if s, _ := r1.Superset(r1); !s {
   226  		t.Fatalf("bad")
   227  	}
   228  	if s, _ := r1.Superset(r2); !s {
   229  		t.Fatalf("bad")
   230  	}
   231  	if s, _ := r2.Superset(r1); s {
   232  		t.Fatalf("bad")
   233  	}
   234  	if s, _ := r2.Superset(r2); !s {
   235  		t.Fatalf("bad")
   236  	}
   237  }
   238  
   239  func TestResource_Add(t *testing.T) {
   240  	r1 := &Resources{
   241  		CPU:      2000,
   242  		MemoryMB: 2048,
   243  		DiskMB:   10000,
   244  		IOPS:     100,
   245  		Networks: []*NetworkResource{
   246  			&NetworkResource{
   247  				CIDR:          "10.0.0.0/8",
   248  				MBits:         100,
   249  				ReservedPorts: []Port{{"ssh", 22}},
   250  			},
   251  		},
   252  	}
   253  	r2 := &Resources{
   254  		CPU:      2000,
   255  		MemoryMB: 1024,
   256  		DiskMB:   5000,
   257  		IOPS:     50,
   258  		Networks: []*NetworkResource{
   259  			&NetworkResource{
   260  				IP:            "10.0.0.1",
   261  				MBits:         50,
   262  				ReservedPorts: []Port{{"web", 80}},
   263  			},
   264  		},
   265  	}
   266  
   267  	err := r1.Add(r2)
   268  	if err != nil {
   269  		t.Fatalf("Err: %v", err)
   270  	}
   271  
   272  	expect := &Resources{
   273  		CPU:      3000,
   274  		MemoryMB: 3072,
   275  		DiskMB:   15000,
   276  		IOPS:     150,
   277  		Networks: []*NetworkResource{
   278  			&NetworkResource{
   279  				CIDR:          "10.0.0.0/8",
   280  				MBits:         150,
   281  				ReservedPorts: []Port{{"ssh", 22}, {"web", 80}},
   282  			},
   283  		},
   284  	}
   285  
   286  	if !reflect.DeepEqual(expect.Networks, r1.Networks) {
   287  		t.Fatalf("bad: %#v %#v", expect, r1)
   288  	}
   289  }
   290  
   291  func TestResource_Add_Network(t *testing.T) {
   292  	r1 := &Resources{}
   293  	r2 := &Resources{
   294  		Networks: []*NetworkResource{
   295  			&NetworkResource{
   296  				MBits:        50,
   297  				DynamicPorts: []Port{{"http", 0}, {"https", 0}},
   298  			},
   299  		},
   300  	}
   301  	r3 := &Resources{
   302  		Networks: []*NetworkResource{
   303  			&NetworkResource{
   304  				MBits:        25,
   305  				DynamicPorts: []Port{{"admin", 0}},
   306  			},
   307  		},
   308  	}
   309  
   310  	err := r1.Add(r2)
   311  	if err != nil {
   312  		t.Fatalf("Err: %v", err)
   313  	}
   314  	err = r1.Add(r3)
   315  	if err != nil {
   316  		t.Fatalf("Err: %v", err)
   317  	}
   318  
   319  	expect := &Resources{
   320  		Networks: []*NetworkResource{
   321  			&NetworkResource{
   322  				MBits:        75,
   323  				DynamicPorts: []Port{{"http", 0}, {"https", 0}, {"admin", 0}},
   324  			},
   325  		},
   326  	}
   327  
   328  	if !reflect.DeepEqual(expect.Networks, r1.Networks) {
   329  		t.Fatalf("bad: %#v %#v", expect.Networks[0], r1.Networks[0])
   330  	}
   331  }
   332  
   333  func TestEncodeDecode(t *testing.T) {
   334  	type FooRequest struct {
   335  		Foo string
   336  		Bar int
   337  		Baz bool
   338  	}
   339  	arg := &FooRequest{
   340  		Foo: "test",
   341  		Bar: 42,
   342  		Baz: true,
   343  	}
   344  	buf, err := Encode(1, arg)
   345  	if err != nil {
   346  		t.Fatalf("err: %v", err)
   347  	}
   348  
   349  	var out FooRequest
   350  	err = Decode(buf[1:], &out)
   351  	if err != nil {
   352  		t.Fatalf("err: %v", err)
   353  	}
   354  
   355  	if !reflect.DeepEqual(arg, &out) {
   356  		t.Fatalf("bad: %#v %#v", arg, out)
   357  	}
   358  }
   359  
   360  func TestInvalidServiceCheck(t *testing.T) {
   361  	s := Service{
   362  		Id:        "service-id",
   363  		Name:      "service-name",
   364  		PortLabel: "bar",
   365  		Checks: []ServiceCheck{
   366  			{
   367  
   368  				Id:   "check-id",
   369  				Name: "check-name",
   370  				Type: "lol",
   371  			},
   372  		},
   373  	}
   374  	if err := s.Validate(); err == nil {
   375  		t.Fatalf("Service should be invalid")
   376  	}
   377  }