From 0fb33f61d52cce0bf5ec8d11d98aaf2f96088c5f Mon Sep 17 00:00:00 2001 From: Andrea Luzzardi Date: Tue, 26 May 2015 19:01:09 -0700 Subject: [PATCH] update testify Signed-off-by: Andrea Luzzardi --- Godeps/Godeps.json | 4 +- .../stretchr/testify/assert/assertions.go | 88 ++++++++- .../testify/assert/assertions_test.go | 63 +++++-- .../github.com/stretchr/testify/assert/doc.go | 10 +- .../testify/assert/forward_assertions.go | 17 +- .../testify/assert/forward_assertions_test.go | 27 +-- .../testify/assert/http_assertions.go | 12 +- .../github.com/stretchr/testify/mock/mock.go | 64 ++++++- .../stretchr/testify/mock/mock_test.go | 176 +++++++++++++++++- cluster/engine_test.go | 12 +- cluster/options_test.go | 24 +-- scheduler/strategy/binpack_test.go | 6 +- scheduler/strategy/spread_test.go | 6 +- 13 files changed, 430 insertions(+), 79 deletions(-) diff --git a/Godeps/Godeps.json b/Godeps/Godeps.json index 23667e0b92..b6b1dec00a 100644 --- a/Godeps/Godeps.json +++ b/Godeps/Godeps.json @@ -118,11 +118,11 @@ }, { "ImportPath": "github.com/stretchr/testify/assert", - "Rev": "43d0eed2455ed136d33e9426cf52119371ca4596" + "Rev": "dab07ac62d4905d3e48d17dc549c684ac3b7c15a" }, { "ImportPath": "github.com/stretchr/testify/mock", - "Rev": "43d0eed2455ed136d33e9426cf52119371ca4596" + "Rev": "dab07ac62d4905d3e48d17dc549c684ac3b7c15a" }, { "ImportPath": "golang.org/x/net/context", diff --git a/Godeps/_workspace/src/github.com/stretchr/testify/assert/assertions.go b/Godeps/_workspace/src/github.com/stretchr/testify/assert/assertions.go index a60b38ebdb..818cd7b0e4 100644 --- a/Godeps/_workspace/src/github.com/stretchr/testify/assert/assertions.go +++ b/Godeps/_workspace/src/github.com/stretchr/testify/assert/assertions.go @@ -4,6 +4,7 @@ import ( "bufio" "bytes" "fmt" + "math" "reflect" "regexp" "runtime" @@ -36,13 +37,27 @@ func ObjectsAreEqual(expected, actual interface{}) bool { return true } - // Last ditch effort - if fmt.Sprintf("%#v", expected) == fmt.Sprintf("%#v", actual) { + return false + +} + +// ObjectsAreEqualValues gets whether two objects are equal, or if their +// values are equal. +func ObjectsAreEqualValues(expected, actual interface{}) bool { + if ObjectsAreEqual(expected, actual) { return true } - return false + actualType := reflect.TypeOf(actual) + expectedValue := reflect.ValueOf(expected) + if expectedValue.Type().ConvertibleTo(actualType) { + // Attempt comparison after type conversion + if reflect.DeepEqual(actual, expectedValue.Convert(actualType).Interface()) { + return true + } + } + return false } /* CallerInfo is necessary because the assert functions use the testing object @@ -189,6 +204,23 @@ func Equal(t TestingT, expected, actual interface{}, msgAndArgs ...interface{}) } +// EqualValues asserts that two objects are equal or convertable to the same types +// and equal. +// +// assert.EqualValues(t, uint32(123), int32(123), "123 and 123 should be equal") +// +// Returns whether the assertion was successful (true) or not (false). +func EqualValues(t TestingT, expected, actual interface{}, msgAndArgs ...interface{}) bool { + + if !ObjectsAreEqualValues(expected, actual) { + return Fail(t, fmt.Sprintf("Not equal: %#v (expected)\n"+ + " != %#v (actual)", expected, actual), msgAndArgs...) + } + + return true + +} + // Exactly asserts that two objects are equal is value and type. // // assert.Exactly(t, int32(123), int64(123), "123 and 123 should NOT be equal") @@ -625,6 +657,14 @@ func InDelta(t TestingT, expected, actual interface{}, delta float64, msgAndArgs return Fail(t, fmt.Sprintf("Parameters must be numerical"), msgAndArgs...) } + if math.IsNaN(af) { + return Fail(t, fmt.Sprintf("Actual must not be NaN"), msgAndArgs...) + } + + if math.IsNaN(bf) { + return Fail(t, fmt.Sprintf("Expected %v with delta %v, but was NaN", expected, delta), msgAndArgs...) + } + dt := af - bf if dt < -delta || dt > delta { return Fail(t, fmt.Sprintf("Max difference between %v and %v allowed is %v, but difference was %v", expected, actual, delta, dt), msgAndArgs...) @@ -633,6 +673,27 @@ func InDelta(t TestingT, expected, actual interface{}, delta float64, msgAndArgs return true } +// InDeltaSlice is the same as InDelta, except it compares two slices. +func InDeltaSlice(t TestingT, expected, actual interface{}, delta float64, msgAndArgs ...interface{}) bool { + if expected == nil || actual == nil || + reflect.TypeOf(actual).Kind() != reflect.Slice || + reflect.TypeOf(expected).Kind() != reflect.Slice { + return Fail(t, fmt.Sprintf("Parameters must be slice"), msgAndArgs...) + } + + actualSlice := reflect.ValueOf(actual) + expectedSlice := reflect.ValueOf(expected) + + for i := 0; i < actualSlice.Len(); i++ { + result := InDelta(t, actualSlice.Index(i).Interface(), expectedSlice.Index(i).Interface(), delta) + if !result { + return result + } + } + + return true +} + // min(|expected|, |actual|) * epsilon func calcEpsilonDelta(expected, actual interface{}, epsilon float64) float64 { af, aok := toFloat(expected) @@ -667,6 +728,27 @@ func InEpsilon(t TestingT, expected, actual interface{}, epsilon float64, msgAnd return InDelta(t, expected, actual, delta, msgAndArgs...) } +// InEpsilonSlice is the same as InEpsilon, except it compares two slices. +func InEpsilonSlice(t TestingT, expected, actual interface{}, delta float64, msgAndArgs ...interface{}) bool { + if expected == nil || actual == nil || + reflect.TypeOf(actual).Kind() != reflect.Slice || + reflect.TypeOf(expected).Kind() != reflect.Slice { + return Fail(t, fmt.Sprintf("Parameters must be slice"), msgAndArgs...) + } + + actualSlice := reflect.ValueOf(actual) + expectedSlice := reflect.ValueOf(expected) + + for i := 0; i < actualSlice.Len(); i++ { + result := InEpsilon(t, actualSlice.Index(i).Interface(), expectedSlice.Index(i).Interface(), delta) + if !result { + return result + } + } + + return true +} + /* Errors */ diff --git a/Godeps/_workspace/src/github.com/stretchr/testify/assert/assertions_test.go b/Godeps/_workspace/src/github.com/stretchr/testify/assert/assertions_test.go index 4c45174375..d859c77b91 100644 --- a/Godeps/_workspace/src/github.com/stretchr/testify/assert/assertions_test.go +++ b/Godeps/_workspace/src/github.com/stretchr/testify/assert/assertions_test.go @@ -2,6 +2,7 @@ package assert import ( "errors" + "math" "regexp" "testing" "time" @@ -55,6 +56,12 @@ func TestObjectsAreEqual(t *testing.T) { if ObjectsAreEqual(0.1, 0) { t.Error("objectsAreEqual should return false") } + if ObjectsAreEqual(uint32(10), int32(10)) { + t.Error("objectsAreEqual should return false") + } + if !ObjectsAreEqualValues(uint32(10), int32(10)) { + t.Error("ObjectsAreEqualValues should return true") + } } @@ -109,10 +116,6 @@ func TestEqual(t *testing.T) { if !Equal(mockT, uint64(123), uint64(123)) { t.Error("Equal should return true") } - funcA := func() int { return 42 } - if !Equal(mockT, funcA, funcA) { - t.Error("Equal should return true") - } } @@ -400,19 +403,6 @@ func TestNotPanics(t *testing.T) { } -func TestEqual_Funcs(t *testing.T) { - - type f func() int - f1 := func() int { return 1 } - f2 := func() int { return 2 } - - f1Copy := f1 - - Equal(t, f1Copy, f1, "Funcs are the same and should be considered equal") - NotEqual(t, f1, f2, "f1 and f2 are different") - -} - func TestNoError(t *testing.T) { mockT := new(testing.T) @@ -663,6 +653,8 @@ func TestInDelta(t *testing.T) { False(t, InDelta(mockT, 1, 2, 0.5), "Expected |1 - 2| <= 0.5 to fail") False(t, InDelta(mockT, 2, 1, 0.5), "Expected |2 - 1| <= 0.5 to fail") False(t, InDelta(mockT, "", nil, 1), "Expected non numerals to fail") + False(t, InDelta(mockT, 42, math.NaN(), 0.01), "Expected NaN for actual to fail") + False(t, InDelta(mockT, math.NaN(), 42, 0.01), "Expected NaN for expected to fail") cases := []struct { a, b interface{} @@ -688,6 +680,27 @@ func TestInDelta(t *testing.T) { } } +func TestInDeltaSlice(t *testing.T) { + mockT := new(testing.T) + + True(t, InDeltaSlice(mockT, + []float64{1.001, 0.999}, + []float64{1, 1}, + 0.1), "{1.001, 0.009} is element-wise close to {1, 1} in delta=0.1") + + True(t, InDeltaSlice(mockT, + []float64{1, 2}, + []float64{0, 3}, + 1), "{1, 2} is element-wise close to {0, 3} in delta=1") + + False(t, InDeltaSlice(mockT, + []float64{1, 2}, + []float64{0, 3}, + 0.1), "{1, 2} is not element-wise close to {0, 3} in delta=0.1") + + False(t, InDeltaSlice(mockT, "", nil, 1), "Expected non numeral slices to fail") +} + func TestInEpsilon(t *testing.T) { mockT := new(testing.T) @@ -727,6 +740,22 @@ func TestInEpsilon(t *testing.T) { } +func TestInEpsilonSlice(t *testing.T) { + mockT := new(testing.T) + + True(t, InEpsilonSlice(mockT, + []float64{2.2, 2.0}, + []float64{2.1, 2.1}, + 0.06), "{2.2, 2.0} is element-wise close to {2.1, 2.1} in espilon=0.06") + + False(t, InEpsilonSlice(mockT, + []float64{2.2, 2.0}, + []float64{2.1, 2.1}, + 0.04), "{2.2, 2.0} is not element-wise close to {2.1, 2.1} in espilon=0.04") + + False(t, InEpsilonSlice(mockT, "", nil, 1), "Expected non numeral slices to fail") +} + func TestRegexp(t *testing.T) { mockT := new(testing.T) diff --git a/Godeps/_workspace/src/github.com/stretchr/testify/assert/doc.go b/Godeps/_workspace/src/github.com/stretchr/testify/assert/doc.go index 1c6de283d0..f678106287 100644 --- a/Godeps/_workspace/src/github.com/stretchr/testify/assert/doc.go +++ b/Godeps/_workspace/src/github.com/stretchr/testify/assert/doc.go @@ -1,4 +1,4 @@ -// A set of comprehensive testing tools for use with the normal Go testing system. +// Package assert provides a set of comprehensive testing tools for use with the normal Go testing system. // // Example Usage // @@ -45,7 +45,9 @@ // // Here is an overview of the assert functions: // -// assert.Equal(t, expected, actual [, message [, format-args]) +// assert.Equal(t, expected, actual [, message [, format-args]]) +// +// assert.EqualValues(t, expected, actual [, message [, format-args]]) // // assert.NotEqual(t, notExpected, actual [, message [, format-args]]) // @@ -98,7 +100,9 @@ // assert package contains Assertions object. it has assertion methods. // // Here is an overview of the assert functions: -// assert.Equal(expected, actual [, message [, format-args]) +// assert.Equal(expected, actual [, message [, format-args]]) +// +// assert.EqualValues(expected, actual [, message [, format-args]]) // // assert.NotEqual(notExpected, actual [, message [, format-args]]) // diff --git a/Godeps/_workspace/src/github.com/stretchr/testify/assert/forward_assertions.go b/Godeps/_workspace/src/github.com/stretchr/testify/assert/forward_assertions.go index 6a988487ee..d8d3f531ea 100644 --- a/Godeps/_workspace/src/github.com/stretchr/testify/assert/forward_assertions.go +++ b/Godeps/_workspace/src/github.com/stretchr/testify/assert/forward_assertions.go @@ -2,10 +2,13 @@ package assert import "time" +// Assertions provides assertion methods around the +// TestingT interface. type Assertions struct { t TestingT } +// New makes a new Assertions object for the specified TestingT. func New(t TestingT) *Assertions { return &Assertions{ t: t, @@ -38,6 +41,16 @@ func (a *Assertions) Equal(expected, actual interface{}, msgAndArgs ...interface return Equal(a.t, expected, actual, msgAndArgs...) } +// EqualValues asserts that two objects are equal or convertable to the same types +// and equal. +// +// assert.EqualValues(uint32(123), int32(123), "123 and 123 should be equal") +// +// Returns whether the assertion was successful (true) or not (false). +func (a *Assertions) EqualValues(expected, actual interface{}, msgAndArgs ...interface{}) bool { + return EqualValues(a.t, expected, actual, msgAndArgs...) +} + // Exactly asserts that two objects are equal is value and type. // // assert.Exactly(int32(123), int64(123), "123 and 123 should NOT be equal") @@ -75,7 +88,7 @@ func (a *Assertions) Empty(object interface{}, msgAndArgs ...interface{}) bool { return Empty(a.t, object, msgAndArgs...) } -// Empty asserts that the specified object is NOT empty. I.e. not nil, "", false, 0 or a +// NotEmpty asserts that the specified object is NOT empty. I.e. not nil, "", false, 0 or a // slice with len == 0. // // if assert.NotEmpty(obj) { @@ -142,7 +155,7 @@ func (a *Assertions) NotContains(s, contains interface{}, msgAndArgs ...interfac return NotContains(a.t, s, contains, msgAndArgs...) } -// Uses a Comparison to assert a complex condition. +// Condition uses a Comparison to assert a complex condition. func (a *Assertions) Condition(comp Comparison, msgAndArgs ...interface{}) bool { return Condition(a.t, comp, msgAndArgs...) } diff --git a/Godeps/_workspace/src/github.com/stretchr/testify/assert/forward_assertions_test.go b/Godeps/_workspace/src/github.com/stretchr/testify/assert/forward_assertions_test.go index 20cca6e21e..3df3f3917a 100644 --- a/Godeps/_workspace/src/github.com/stretchr/testify/assert/forward_assertions_test.go +++ b/Godeps/_workspace/src/github.com/stretchr/testify/assert/forward_assertions_test.go @@ -50,6 +50,14 @@ func TestEqualWrapper(t *testing.T) { } } +func TestEqualValuesWrapper(t *testing.T) { + assert := New(new(testing.T)) + + if !assert.EqualValues(uint32(10), int32(10)) { + t.Error("EqualValues should return true") + } +} + func TestNotNilWrapper(t *testing.T) { assert := New(new(testing.T)) @@ -251,27 +259,12 @@ func TestNotPanicsWrapper(t *testing.T) { } -func TestEqualWrapper_Funcs(t *testing.T) { - - assert := New(t) - - type f func() int - var f1 f = func() int { return 1 } - var f2 f = func() int { return 2 } - - var f1_copy f = f1 - - assert.Equal(f1_copy, f1, "Funcs are the same and should be considered equal") - assert.NotEqual(f1, f2, "f1 and f2 are different") - -} - func TestNoErrorWrapper(t *testing.T) { assert := New(t) mockAssert := New(new(testing.T)) // start with a nil error - var err error = nil + var err error assert.True(mockAssert.NoError(err), "NoError should return True for nil arg") @@ -287,7 +280,7 @@ func TestErrorWrapper(t *testing.T) { mockAssert := New(new(testing.T)) // start with a nil error - var err error = nil + var err error assert.False(mockAssert.Error(err), "Error should return False for nil arg") diff --git a/Godeps/_workspace/src/github.com/stretchr/testify/assert/http_assertions.go b/Godeps/_workspace/src/github.com/stretchr/testify/assert/http_assertions.go index 0bcb6db9b8..1246e58e0e 100644 --- a/Godeps/_workspace/src/github.com/stretchr/testify/assert/http_assertions.go +++ b/Godeps/_workspace/src/github.com/stretchr/testify/assert/http_assertions.go @@ -22,7 +22,7 @@ func httpCode(handler http.HandlerFunc, mode, url string, values url.Values) int // HTTPSuccess asserts that a specified handler returns a success status code. // -// assert.HTTPSuccess(t, myHandler, "POST", http://www.google.com", nil) +// assert.HTTPSuccess(t, myHandler, "POST", "http://www.google.com", nil) // // Returns whether the assertion was successful (true) or not (false). func HTTPSuccess(t TestingT, handler http.HandlerFunc, mode, url string, values url.Values) bool { @@ -59,9 +59,9 @@ func HTTPError(t TestingT, handler http.HandlerFunc, mode, url string, values ur return code >= http.StatusBadRequest } -// HttpBody is a helper that returns HTTP body of the response. It returns +// HTTPBody is a helper that returns HTTP body of the response. It returns // empty string if building a new request fails. -func HttpBody(handler http.HandlerFunc, mode, url string, values url.Values) string { +func HTTPBody(handler http.HandlerFunc, mode, url string, values url.Values) string { w := httptest.NewRecorder() req, err := http.NewRequest(mode, url+"?"+values.Encode(), nil) if err != nil { @@ -78,7 +78,7 @@ func HttpBody(handler http.HandlerFunc, mode, url string, values url.Values) str // // Returns whether the assertion was successful (true) or not (false). func HTTPBodyContains(t TestingT, handler http.HandlerFunc, mode, url string, values url.Values, str interface{}) bool { - body := HttpBody(handler, mode, url, values) + body := HTTPBody(handler, mode, url, values) contains := strings.Contains(body, fmt.Sprint(str)) if !contains { @@ -95,7 +95,7 @@ func HTTPBodyContains(t TestingT, handler http.HandlerFunc, mode, url string, va // // Returns whether the assertion was successful (true) or not (false). func HTTPBodyNotContains(t TestingT, handler http.HandlerFunc, mode, url string, values url.Values, str interface{}) bool { - body := HttpBody(handler, mode, url, values) + body := HTTPBody(handler, mode, url, values) contains := strings.Contains(body, fmt.Sprint(str)) if contains { @@ -111,7 +111,7 @@ func HTTPBodyNotContains(t TestingT, handler http.HandlerFunc, mode, url string, // HTTPSuccess asserts that a specified handler returns a success status code. // -// assert.HTTPSuccess(myHandler, "POST", http://www.google.com", nil) +// assert.HTTPSuccess(myHandler, "POST", "http://www.google.com", nil) // // Returns whether the assertion was successful (true) or not (false). func (a *Assertions) HTTPSuccess(handler http.HandlerFunc, mode, url string, values url.Values) bool { diff --git a/Godeps/_workspace/src/github.com/stretchr/testify/mock/mock.go b/Godeps/_workspace/src/github.com/stretchr/testify/mock/mock.go index f73fa2516b..fa8747e29f 100644 --- a/Godeps/_workspace/src/github.com/stretchr/testify/mock/mock.go +++ b/Godeps/_workspace/src/github.com/stretchr/testify/mock/mock.go @@ -8,6 +8,7 @@ import ( "runtime" "strings" "sync" + "time" ) // TestingT is an interface wrapper around *testing.T @@ -37,6 +38,15 @@ type Call struct { // The number of times to return the return arguments when setting // expectations. 0 means to always return the value. Repeatability int + + // Holds a channel that will be used to block the Return until it either + // recieves a message or is closed. nil means it returns immediately. + WaitFor <-chan time.Time + + // Holds a handler used to manipulate arguments content that are passed by + // reference. It's useful when mocking methods such as unmarshalers or + // decoders. + Run func(Arguments) } // Mock is the workhorse used to track activity on another object. @@ -87,6 +97,13 @@ func (m *Mock) TestData() objx.Map { func (m *Mock) On(methodName string, arguments ...interface{}) *Mock { m.onMethodName = methodName m.onMethodArguments = arguments + + for _, arg := range arguments { + if v := reflect.ValueOf(arg); v.Kind() == reflect.Func { + panic(fmt.Sprintf("cannot use Func in expectations. Use mock.AnythingOfType(\"%T\")", arg)) + } + } + return m } @@ -95,7 +112,7 @@ func (m *Mock) On(methodName string, arguments ...interface{}) *Mock { // // Mock.On("MyMethod", arg1, arg2).Return(returnArg1, returnArg2) func (m *Mock) Return(returnArguments ...interface{}) *Mock { - m.ExpectedCalls = append(m.ExpectedCalls, Call{m.onMethodName, m.onMethodArguments, returnArguments, 0}) + m.ExpectedCalls = append(m.ExpectedCalls, Call{m.onMethodName, m.onMethodArguments, returnArguments, 0, nil, nil}) return m } @@ -121,6 +138,35 @@ func (m *Mock) Times(i int) { m.ExpectedCalls[len(m.ExpectedCalls)-1].Repeatability = i } +// WaitUntil sets the channel that will block the mock's return until its closed +// or a message is received. +// +// Mock.On("MyMethod", arg1, arg2).WaitUntil(time.After(time.Second)) +func (m *Mock) WaitUntil(w <-chan time.Time) *Mock { + m.ExpectedCalls[len(m.ExpectedCalls)-1].WaitFor = w + return m +} + +// After sets how long to block until the call returns +// +// Mock.On("MyMethod", arg1, arg2).After(time.Second) +func (m *Mock) After(d time.Duration) *Mock { + return m.WaitUntil(time.After(d)) +} + +// Run sets a handler to be called before returning. It can be used when +// mocking a method such as unmarshalers that takes a pointer to a struct and +// sets properties in such struct +// +// Mock.On("Unmarshal", AnythingOfType("*map[string]interface{}").Return().Run(function(args Arguments) { +// arg := args.Get(0).(*map[string]interface{}) +// arg["foo"] = "bar" +// }) +func (m *Mock) Run(fn func(Arguments)) *Mock { + m.ExpectedCalls[len(m.ExpectedCalls)-1].Run = fn + return m +} + /* Recording and responding to activity */ @@ -180,6 +226,7 @@ func callString(method string, arguments Arguments, includeArgumentValues bool) // Called tells the mock object that a method has been called, and gets an array // of arguments to return. Panics if the call is unexpected (i.e. not preceeded by // appropriate .On .Return() calls) +// If Call.WaitFor is set, blocks until the channel is closed or receives a message. func (m *Mock) Called(arguments ...interface{}) Arguments { defer m.mutex.Unlock() m.mutex.Lock() @@ -220,7 +267,16 @@ func (m *Mock) Called(arguments ...interface{}) Arguments { } // add the call - m.Calls = append(m.Calls, Call{functionName, arguments, make([]interface{}, 0), 0}) + m.Calls = append(m.Calls, Call{functionName, arguments, make([]interface{}, 0), 0, nil, nil}) + + // block if specified + if call.WaitFor != nil { + <-call.WaitFor + } + + if call.Run != nil { + call.Run(arguments) + } return call.ReturnArguments @@ -286,7 +342,7 @@ func (m *Mock) AssertNumberOfCalls(t TestingT, methodName string, expectedCalls // AssertCalled asserts that the method was called. func (m *Mock) AssertCalled(t TestingT, methodName string, arguments ...interface{}) bool { if !assert.True(t, m.methodWasCalled(methodName, arguments), fmt.Sprintf("The \"%s\" method should have been called with %d argument(s), but was not.", methodName, len(arguments))) { - t.Logf("%s", m.ExpectedCalls) + t.Logf("%v", m.ExpectedCalls) return false } return true @@ -295,7 +351,7 @@ func (m *Mock) AssertCalled(t TestingT, methodName string, arguments ...interfac // AssertNotCalled asserts that the method was not called. func (m *Mock) AssertNotCalled(t TestingT, methodName string, arguments ...interface{}) bool { if !assert.False(t, m.methodWasCalled(methodName, arguments), fmt.Sprintf("The \"%s\" method was called with %d argument(s), but should NOT have been.", methodName, len(arguments))) { - t.Logf("%s", m.ExpectedCalls) + t.Logf("%v", m.ExpectedCalls) return false } return true diff --git a/Godeps/_workspace/src/github.com/stretchr/testify/mock/mock_test.go b/Godeps/_workspace/src/github.com/stretchr/testify/mock/mock_test.go index a4457e0710..b7446accb4 100644 --- a/Godeps/_workspace/src/github.com/stretchr/testify/mock/mock_test.go +++ b/Godeps/_workspace/src/github.com/stretchr/testify/mock/mock_test.go @@ -4,6 +4,7 @@ import ( "errors" "github.com/stretchr/testify/assert" "testing" + "time" ) /* @@ -29,13 +30,27 @@ func (i *TestExampleImplementation) TheExampleMethod2(yesorno bool) { i.Called(yesorno) } -type ExampleType struct{} +type ExampleType struct { + ran bool +} func (i *TestExampleImplementation) TheExampleMethod3(et *ExampleType) error { args := i.Called(et) return args.Error(0) } +func (i *TestExampleImplementation) TheExampleMethodFunc(fn func(string) error) error { + args := i.Called(fn) + return args.Error(0) +} + +type ExampleFuncType func(string) error + +func (i *TestExampleImplementation) TheExampleMethodFuncType(fn ExampleFuncType) error { + args := i.Called(fn) + return args.Error(0) +} + /* Mock */ @@ -76,6 +91,43 @@ func Test_Mock_On_WithArgs(t *testing.T) { } +func Test_Mock_On_WithFuncArg(t *testing.T) { + + // make a test impl object + var mockedService *TestExampleImplementation = new(TestExampleImplementation) + + assert.Equal(t, mockedService.On("TheExampleMethodFunc", AnythingOfType("func(string) error")).Return(nil), &mockedService.Mock) + assert.Equal(t, "TheExampleMethodFunc", mockedService.onMethodName) + assert.Equal(t, AnythingOfType("func(string) error"), mockedService.onMethodArguments[0]) + + fn := func(string) error { return nil } + mockedService.TheExampleMethodFunc(fn) + +} + +func Test_Mock_On_WithFuncPanics(t *testing.T) { + // make a test impl object + var mockedService *TestExampleImplementation = new(TestExampleImplementation) + + assert.Panics(t, func() { + mockedService.On("TheExampleMethodFunc", func(string) error { return nil }) + }) +} + +func Test_Mock_On_WithFuncTypeArg(t *testing.T) { + + // make a test impl object + var mockedService *TestExampleImplementation = new(TestExampleImplementation) + + assert.Equal(t, mockedService.On("TheExampleMethodFuncType", AnythingOfType("mock.ExampleFuncType")).Return(nil), &mockedService.Mock) + assert.Equal(t, "TheExampleMethodFuncType", mockedService.onMethodName) + assert.Equal(t, AnythingOfType("mock.ExampleFuncType"), mockedService.onMethodArguments[0]) + + fn := func(string) error { return nil } + mockedService.TheExampleMethodFuncType(fn) + +} + func Test_Mock_Return(t *testing.T) { // make a test impl object @@ -95,11 +147,93 @@ func Test_Mock_Return(t *testing.T) { assert.Equal(t, "two", call.ReturnArguments[1]) assert.Equal(t, true, call.ReturnArguments[2]) assert.Equal(t, 0, call.Repeatability) + assert.Nil(t, call.WaitFor) } } +func Test_Mock_Return_WaitUntil(t *testing.T) { + + // make a test impl object + var mockedService *TestExampleImplementation = new(TestExampleImplementation) + ch := time.After(time.Second) + + assert.Equal(t, mockedService.Mock.On("TheExampleMethod", "A", "B", true).Return(1, "two", true).WaitUntil(ch), &mockedService.Mock) + + // ensure the call was created + if assert.Equal(t, 1, len(mockedService.Mock.ExpectedCalls)) { + call := mockedService.Mock.ExpectedCalls[0] + + assert.Equal(t, "TheExampleMethod", call.Method) + assert.Equal(t, "A", call.Arguments[0]) + assert.Equal(t, "B", call.Arguments[1]) + assert.Equal(t, true, call.Arguments[2]) + assert.Equal(t, 1, call.ReturnArguments[0]) + assert.Equal(t, "two", call.ReturnArguments[1]) + assert.Equal(t, true, call.ReturnArguments[2]) + assert.Equal(t, 0, call.Repeatability) + assert.Equal(t, ch, call.WaitFor) + + } + +} + +func Test_Mock_Return_After(t *testing.T) { + + // make a test impl object + var mockedService *TestExampleImplementation = new(TestExampleImplementation) + + assert.Equal(t, mockedService.Mock.On("TheExampleMethod", "A", "B", true).Return(1, "two", true).After(time.Second), &mockedService.Mock) + + // ensure the call was created + if assert.Equal(t, 1, len(mockedService.Mock.ExpectedCalls)) { + call := mockedService.Mock.ExpectedCalls[0] + + assert.Equal(t, "TheExampleMethod", call.Method) + assert.Equal(t, "A", call.Arguments[0]) + assert.Equal(t, "B", call.Arguments[1]) + assert.Equal(t, true, call.Arguments[2]) + assert.Equal(t, 1, call.ReturnArguments[0]) + assert.Equal(t, "two", call.ReturnArguments[1]) + assert.Equal(t, true, call.ReturnArguments[2]) + assert.Equal(t, 0, call.Repeatability) + assert.NotEqual(t, nil, call.WaitFor) + + } + +} + +func Test_Mock_Return_Run(t *testing.T) { + + // make a test impl object + var mockedService *TestExampleImplementation = new(TestExampleImplementation) + + assert.Equal(t, mockedService.Mock.On("TheExampleMethod3", AnythingOfType("*mock.ExampleType")).Return(nil).Run(func(args Arguments) { + arg := args.Get(0).(*ExampleType) + arg.ran = true + }), &mockedService.Mock) + + // ensure the call was created + if assert.Equal(t, 1, len(mockedService.Mock.ExpectedCalls)) { + call := mockedService.Mock.ExpectedCalls[0] + + assert.Equal(t, "TheExampleMethod3", call.Method) + assert.Equal(t, AnythingOfType("*mock.ExampleType"), call.Arguments[0]) + assert.Equal(t, nil, call.ReturnArguments[0]) + assert.Equal(t, 0, call.Repeatability) + assert.NotEqual(t, nil, call.WaitFor) + assert.NotNil(t, call.Run) + + } + + et := ExampleType{} + assert.Equal(t, false, et.ran) + mockedService.TheExampleMethod3(&et) + assert.Equal(t, true, et.ran) + +} + func Test_Mock_Return_Once(t *testing.T) { // make a test impl object @@ -119,6 +253,7 @@ func Test_Mock_Return_Once(t *testing.T) { assert.Equal(t, "two", call.ReturnArguments[1]) assert.Equal(t, true, call.ReturnArguments[2]) assert.Equal(t, 1, call.Repeatability) + assert.Nil(t, call.WaitFor) } @@ -143,6 +278,7 @@ func Test_Mock_Return_Twice(t *testing.T) { assert.Equal(t, "two", call.ReturnArguments[1]) assert.Equal(t, true, call.ReturnArguments[2]) assert.Equal(t, 2, call.Repeatability) + assert.Nil(t, call.WaitFor) } @@ -167,6 +303,7 @@ func Test_Mock_Return_Times(t *testing.T) { assert.Equal(t, "two", call.ReturnArguments[1]) assert.Equal(t, true, call.ReturnArguments[2]) assert.Equal(t, 5, call.Repeatability) + assert.Nil(t, call.WaitFor) } @@ -274,6 +411,43 @@ func Test_Mock_Called(t *testing.T) { } +func asyncCall(m *Mock, ch chan Arguments) { + ch <- m.Called(1, 2, 3) +} + +func Test_Mock_Called_blocks(t *testing.T) { + + var mockedService *TestExampleImplementation = new(TestExampleImplementation) + + mockedService.Mock.On("asyncCall", 1, 2, 3).Return(5, "6", true).After(2 * time.Millisecond) + + ch := make(chan Arguments) + + go asyncCall(&mockedService.Mock, ch) + + select { + case <-ch: + t.Fatal("should have waited") + case <-time.After(1 * time.Millisecond): + } + + returnArguments := <-ch + + if assert.Equal(t, 1, len(mockedService.Mock.Calls)) { + assert.Equal(t, "asyncCall", mockedService.Mock.Calls[0].Method) + assert.Equal(t, 1, mockedService.Mock.Calls[0].Arguments[0]) + assert.Equal(t, 2, mockedService.Mock.Calls[0].Arguments[1]) + assert.Equal(t, 3, mockedService.Mock.Calls[0].Arguments[2]) + } + + if assert.Equal(t, 3, len(returnArguments)) { + assert.Equal(t, 5, returnArguments[0]) + assert.Equal(t, "6", returnArguments[1]) + assert.Equal(t, true, returnArguments[2]) + } + +} + func Test_Mock_Called_For_Bounded_Repeatability(t *testing.T) { var mockedService *TestExampleImplementation = new(TestExampleImplementation) diff --git a/cluster/engine_test.go b/cluster/engine_test.go index 202179ae1c..1e68f22ff8 100644 --- a/cluster/engine_test.go +++ b/cluster/engine_test.go @@ -65,8 +65,8 @@ func TestEngineCpusMemory(t *testing.T) { assert.True(t, engine.isConnected()) assert.True(t, engine.IsHealthy()) - assert.Equal(t, engine.UsedCpus(), 0) - assert.Equal(t, engine.UsedMemory(), 0) + assert.Equal(t, engine.UsedCpus(), int64(0)) + assert.Equal(t, engine.UsedMemory(), int64(0)) client.Mock.AssertExpectations(t) } @@ -196,19 +196,19 @@ func TestCreateContainer(t *testing.T) { func TestTotalMemory(t *testing.T) { engine := NewEngine("test", 0.05) engine.Memory = 1024 - assert.Equal(t, engine.TotalMemory(), 1024+1024*5/100) + assert.Equal(t, engine.TotalMemory(), int64(1024+1024*5/100)) engine = NewEngine("test", 0) engine.Memory = 1024 - assert.Equal(t, engine.TotalMemory(), 1024) + assert.Equal(t, engine.TotalMemory(), int64(1024)) } func TestTotalCpus(t *testing.T) { engine := NewEngine("test", 0.05) engine.Cpus = 2 - assert.Equal(t, engine.TotalCpus(), 2+2*5/100) + assert.Equal(t, engine.TotalCpus(), int64(2+2*5/100)) engine = NewEngine("test", 0) engine.Cpus = 2 - assert.Equal(t, engine.TotalCpus(), 2) + assert.Equal(t, engine.TotalCpus(), int64(2)) } diff --git a/cluster/options_test.go b/cluster/options_test.go index 7ca0653ce2..a3ed26f15c 100644 --- a/cluster/options_test.go +++ b/cluster/options_test.go @@ -46,27 +46,27 @@ func TestInt(t *testing.T) { val, ok := opts.Int("foo1", "") assert.True(t, ok) - assert.Equal(t, val, 0) + assert.Equal(t, val, int64(0)) val, ok = opts.Int("foo2", "") assert.True(t, ok) - assert.Equal(t, val, -5) + assert.Equal(t, val, int64(-5)) val, ok = opts.Int("foo3", "") assert.True(t, ok) - assert.Equal(t, val, 7) + assert.Equal(t, val, int64(7)) val, ok = opts.Int("foo4", "") assert.True(t, ok) - assert.Equal(t, val, 0) + assert.Equal(t, val, int64(0)) val, ok = opts.Int("", "FOO_4") assert.True(t, ok) - assert.Equal(t, val, 0) + assert.Equal(t, val, int64(0)) val, ok = opts.Int("invalid", "") assert.False(t, ok) - assert.Equal(t, val, 0) + assert.Equal(t, val, int64(0)) } func TestUint(t *testing.T) { @@ -75,27 +75,27 @@ func TestUint(t *testing.T) { val, ok := opts.Uint("foo1", "") assert.True(t, ok) - assert.Equal(t, val, uint(0)) + assert.Equal(t, val, uint64(0)) val, ok = opts.Uint("foo2", "") assert.True(t, ok) - assert.Equal(t, val, uint(0)) + assert.Equal(t, val, uint64(0)) val, ok = opts.Uint("foo3", "") assert.True(t, ok) - assert.Equal(t, val, uint(7)) + assert.Equal(t, val, uint64(7)) val, ok = opts.Uint("foo4", "") assert.True(t, ok) - assert.Equal(t, val, uint(0)) + assert.Equal(t, val, uint64(0)) val, ok = opts.Uint("", "FOO_4") assert.True(t, ok) - assert.Equal(t, val, uint(0)) + assert.Equal(t, val, uint64(0)) val, ok = opts.Uint("invalid", "") assert.False(t, ok) - assert.Equal(t, val, uint(0)) + assert.Equal(t, val, uint64(0)) } func TestFloat(t *testing.T) { diff --git a/scheduler/strategy/binpack_test.go b/scheduler/strategy/binpack_test.go index a6711d13a6..bf614c02d7 100644 --- a/scheduler/strategy/binpack_test.go +++ b/scheduler/strategy/binpack_test.go @@ -79,7 +79,7 @@ func TestPlaceContainerMemory(t *testing.T) { node1, err := s.PlaceContainer(config, nodes) assert.NoError(t, err) assert.NoError(t, node1.AddContainer(createContainer("c1", config))) - assert.Equal(t, node1.UsedMemory, 1024*1024*1024) + assert.Equal(t, node1.UsedMemory, int64(1024*1024*1024)) // add another container 1G config = createConfig(1, 0) @@ -106,14 +106,14 @@ func TestPlaceContainerCPU(t *testing.T) { node1, err := s.PlaceContainer(config, nodes) assert.NoError(t, err) assert.NoError(t, node1.AddContainer(createContainer("c1", config))) - assert.Equal(t, node1.UsedCpus, 1) + assert.Equal(t, node1.UsedCpus, int64(1)) // add another container 1CPU config = createConfig(0, 1) node2, err := s.PlaceContainer(config, nodes) assert.NoError(t, err) assert.NoError(t, node2.AddContainer(createContainer("c2", config))) - assert.Equal(t, node2.UsedCpus, 2) + assert.Equal(t, node2.UsedCpus, int64(2)) // check that both containers ended on the same node assert.Equal(t, node1.ID, node2.ID) diff --git a/scheduler/strategy/spread_test.go b/scheduler/strategy/spread_test.go index 45977627d1..7c01647f3c 100644 --- a/scheduler/strategy/spread_test.go +++ b/scheduler/strategy/spread_test.go @@ -53,7 +53,7 @@ func TestSpreadPlaceContainerMemory(t *testing.T) { node1, err := s.PlaceContainer(config, nodes) assert.NoError(t, err) assert.NoError(t, node1.AddContainer(createContainer("c1", config))) - assert.Equal(t, node1.UsedMemory, 1024*1024*1024) + assert.Equal(t, node1.UsedMemory, int64(1024*1024*1024)) // add another container 1G config = createConfig(1, 0) @@ -80,14 +80,14 @@ func TestSpreadPlaceContainerCPU(t *testing.T) { node1, err := s.PlaceContainer(config, nodes) assert.NoError(t, err) assert.NoError(t, node1.AddContainer(createContainer("c1", config))) - assert.Equal(t, node1.UsedCpus, 1) + assert.Equal(t, node1.UsedCpus, int64(1)) // add another container 1CPU config = createConfig(0, 1) node2, err := s.PlaceContainer(config, nodes) assert.NoError(t, err) assert.NoError(t, node2.AddContainer(createContainer("c2", config))) - assert.Equal(t, node2.UsedCpus, 1) + assert.Equal(t, node2.UsedCpus, int64(1)) // check that both containers ended on different node assert.NotEqual(t, node1.ID, node2.ID)