package host import ( "testing" "time" "github.com/stretchr/testify/assert" ) type helper interface { Helper() } func EqualError(message string) assert.ErrorAssertionFunc { return func(t assert.TestingT, err error, i ...interface{}) bool { if help, ok := t.(helper); ok { help.Helper() } return assert.EqualError(t, err, message, i...) } } type TimeAssertionFunc func(t assert.TestingT, actual time.Time, msgAndArgs ...interface{}) bool func TimeEqual(expected time.Time) TimeAssertionFunc { return func(t assert.TestingT, actual time.Time, msgAndArgs ...interface{}) bool { return assert.Equal(t, expected, actual, msgAndArgs...) } } func WithinRange(start, end time.Time) TimeAssertionFunc { return func(t assert.TestingT, actual time.Time, msgAndArgs ...interface{}) bool { return assert.WithinRange(t, actual, start, end, msgAndArgs...) } } func TestUpdateStateVNC(t *testing.T) { t.Parallel() // We need to round testTime to the nearest second because otherwise we will be testing // against some extra values that get lost in time.RFC3339 format, like milliseconds. // Timezone is set to UTC to avoid pipeline errors. testTime := time.Now().Add(48 * time.Hour).Round(time.Second).UTC() tests := map[string]struct { state *State payload postVNCPayload want *State timeAssert TimeAssertionFunc }{ "Update Status": { state: &State{ VNC: VNCStates{ { RequestID: "1", Status: Requested, TimeStamp: time.Now().Format(time.RFC3339), }, }, }, payload: postVNCPayload{ RequestID: "1", Status: Accepted, }, want: &State{ VNC: VNCStates{ { RequestID: "1", Status: Accepted, }, }, }, timeAssert: WithinRange(time.Now().Add(-(10 * time.Second)), time.Now()), }, "Add New VNC State": { state: &State{ VNC: VNCStates{ { RequestID: "1", Status: Requested, TimeStamp: time.Now().Format(time.RFC3339), }, }, }, payload: postVNCPayload{ RequestID: "2", Status: Accepted, }, want: &State{ VNC: VNCStates{ { RequestID: "1", Status: Requested, }, { RequestID: "2", Status: Accepted, }, }, }, timeAssert: WithinRange(time.Now().Add(-(10 * time.Second)), time.Now()), }, "Rejected VNC State": { state: &State{ VNC: VNCStates{ { RequestID: "1", Status: Requested, TimeStamp: time.Now().Format(time.RFC3339), }, }, }, payload: postVNCPayload{ RequestID: "1", Status: Rejected, }, want: &State{ VNC: VNCStates{ { RequestID: "1", Status: Rejected, }, }, }, timeAssert: WithinRange(time.Now().Add(-(10 * time.Second)), time.Now()), }, "Connected VNC State": { state: &State{ VNC: VNCStates{ { RequestID: "1", Status: Accepted, TimeStamp: time.Now().Format(time.RFC3339), }, }, }, payload: postVNCPayload{ RequestID: "1", Status: Connected, Connections: 1, TimeStamp: testTime, }, want: &State{ VNC: VNCStates{ { RequestID: "1", Status: Connected, Connections: 1, TimeStamp: testTime.Format(time.RFC3339), }, }, }, timeAssert: TimeEqual(testTime), }, "Dropped VNC State": { state: &State{ VNC: VNCStates{ { RequestID: "1", Status: Requested, TimeStamp: time.Now().Format(time.RFC3339), }, }, }, payload: postVNCPayload{ RequestID: "1", Status: Dropped, }, want: &State{ VNC: VNCStates{}, }, timeAssert: TimeEqual(time.Time{}), }, "Remove VNC State Not Found": { state: &State{ VNC: VNCStates{ { RequestID: "1", Status: Requested, TimeStamp: time.Now().Format(time.RFC3339), }, }, }, payload: postVNCPayload{ RequestID: "2", Status: Dropped, }, want: &State{ VNC: VNCStates{ { RequestID: "1", Status: Requested, }, }, }, timeAssert: WithinRange(time.Now().Add(-(10 * time.Second)), time.Now()), }, "Payload With Timestamp": { state: &State{ VNC: VNCStates{ { RequestID: "1", Status: Requested, TimeStamp: time.Now().Format(time.RFC3339), }, }, }, payload: postVNCPayload{ RequestID: "1", Status: Accepted, TimeStamp: testTime, }, want: &State{ VNC: VNCStates{ { RequestID: "1", Status: Accepted, TimeStamp: testTime.Format(time.RFC3339), }, }, }, timeAssert: TimeEqual(testTime), }, "New Payload With Timestamp": { state: &State{ VNC: VNCStates{}, }, payload: postVNCPayload{ RequestID: "1", Status: Accepted, TimeStamp: testTime, }, want: &State{ VNC: VNCStates{ { RequestID: "1", Status: Accepted, TimeStamp: testTime.Format(time.RFC3339), }, }, }, timeAssert: TimeEqual(testTime), }, } for name, tc := range tests { tc := tc t.Run(name, func(t *testing.T) { t.Parallel() updateStateVNC(tc.state, tc.payload) for i := range tc.state.VNC { assert.Equal(t, tc.state.VNC[i].RequestID, tc.want.VNC[i].RequestID) assert.Equal(t, tc.state.VNC[i].Status, tc.want.VNC[i].Status) actualTime, err := time.Parse(time.RFC3339, tc.state.VNC[i].TimeStamp) assert.NoError(t, err) tc.timeAssert(t, actualTime) } }) } }