func (t caseTest) TestACK() error { origin, err := testServer.Origin() if err != nil { return fmt.Errorf("On test %v, error initializing test server: %#v", t.CaseTestType, err) } conn, err := client.DialOrigin(origin) if err != nil { return fmt.Errorf("On test %v, error dialing origin: %#v", t.CaseTestType, err) } defer conn.Close() defer conn.Purge() conn.RegisterDecoder("ack", client.DecoderFunc(decodeCaseACK)) request := CaseACK{t.CaseTestType, client.NewACK(nil, true)} _, err = conn.WriteRequest(request) if t.statusCode >= 200 && t.statusCode < 300 { if err != nil { return fmt.Errorf("On test %v, error writing acknowledgement: %#v", t.CaseTestType, err) } return nil } if err != io.EOF { return fmt.Errorf("On test %v, error writing acknowledgement: got %#v; want io.EOF", t.CaseTestType, err) } err = conn.Close() clientErr, ok := err.(client.Error) if !ok { return fmt.Errorf("On test %v, type assertion failed for close error: %#v", t.CaseTestType, err) } if clientErr.Status() != t.statusCode { return fmt.Errorf("On test %v, unexpected close error status: got %#v; want %#v", t.CaseTestType, clientErr.Status(), t.statusCode) } return nil }
func TestPrematureUnregister(t *testing.T) { channelId, err := id.Generate() if err != nil { t.Fatalf("Error generating channel ID: %#v", err) } origin, err := testServer.Origin() if err != nil { t.Fatalf("Error initializing test server: %#v", err) } conn, err := client.DialOrigin(origin) if err != nil { t.Fatalf("Error dialing origin: %#v", err) } defer conn.Close() defer conn.Purge() conn.RegisterDecoder("unregister", client.DecoderFunc(decodeUnregisterReply)) request := client.NewUnregister(channelId, true) _, err = conn.WriteRequest(request) if err != io.EOF { t.Fatalf("Error writing deregistration request: got %#v; want io.EOF", err) } err = conn.Close() clientErr, ok := err.(client.Error) if !ok { t.Fatalf("Type assertion failed for close error: %#v", err) } if clientErr.Status() != 401 { t.Errorf("Unexpected close error status: got %#v; want 401", clientErr.Status()) } }
func TestNilDeviceId(t *testing.T) { origin, err := testServer.Origin() if err != nil { t.Fatalf("Error initializing test server: %#v", err) } conn, err := client.DialOrigin(origin) if err != nil { t.Fatalf("Error dialing origin: %#v", err) } defer conn.Close() defer conn.Purge() request := CustomHelo{ MessageType: "hello", DeviceId: NilId, ChannelIds: []interface{}{}, Extra: "extra field", replies: make(chan client.Reply), errors: make(chan error), } reply, err := conn.WriteRequest(request) if err != nil { t.Fatalf("Error writing handshake request: %#v", err) } helo, ok := reply.(client.ServerHelo) if !ok { t.Errorf("Type assertion failed for handshake reply: %#v", reply) } if !id.Valid(helo.DeviceId) { t.Errorf("Got invalid device ID: %#v", helo.DeviceId) } }
func (t caseTest) TestHelo() error { deviceId, err := id.Generate() if err != nil { return fmt.Errorf("On test %v, error generating device ID: %#v", t.CaseTestType, err) } addExistsHook(deviceId, true) defer removeExistsHook(deviceId) channelId, err := id.Generate() if err != nil { return fmt.Errorf("On test %v, error generating channel ID: %#v", t.CaseTestType, err) } origin, err := testServer.Origin() if err != nil { return fmt.Errorf("On test %v, error initializing test server: %#v", t.CaseTestType, err) } conn, err := client.DialOrigin(origin) if err != nil { return fmt.Errorf("On test %v, error dialing origin: %#v", t.CaseTestType, err) } defer conn.Close() defer conn.Purge() request := CaseHelo{t.CaseTestType, client.NewHelo(deviceId, []string{channelId}).(client.ClientHelo)} reply, err := conn.WriteRequest(request) if t.statusCode >= 200 && t.statusCode < 300 { if err != nil { return fmt.Errorf("On test %v, error writing handshake request: %#v", t.CaseTestType, err) } helo, ok := reply.(client.ServerHelo) if !ok { return fmt.Errorf("On test %v, type assertion failed for handshake reply: %#v", t.CaseTestType, reply) } if helo.StatusCode != t.statusCode { return fmt.Errorf("On test %v, unexpected reply status: got %#v; want %#v", t.CaseTestType, helo.StatusCode, t.statusCode) } if t.shouldReset { if helo.DeviceId == deviceId { return fmt.Errorf("On test %v, want new device ID; got %#v", t.CaseTestType, deviceId) } return nil } if helo.DeviceId != deviceId { return fmt.Errorf("On test %v, mismatched device ID: got %#v; want %#v", t.CaseTestType, helo.DeviceId, deviceId) } return nil } if err != io.EOF { return fmt.Errorf("On test %v, error writing handshake: got %#v; want io.EOF", t.CaseTestType, err) } err = conn.Close() clientErr, ok := err.(client.Error) if !ok { return fmt.Errorf("On test %v, type assertion failed for close error: %#v", t.CaseTestType, err) } if clientErr.Status() != t.statusCode { return fmt.Errorf("On test %v, unexpected close error status: got %#v; want %#v", t.CaseTestType, clientErr.Status(), t.statusCode) } return nil }
func (t idTest) TestHelo() error { deviceId, err := id.Generate() if err != nil { return fmt.Errorf("On handshake test %v, error generating device ID: %#v", t.name, err) } addExistsHook(deviceId, true) defer removeExistsHook(deviceId) origin, err := testServer.Origin() if err != nil { return fmt.Errorf("On handshake test %v, error initializing test server: %#v", t.name, err) } conn, err := client.DialOrigin(origin) if err != nil { return fmt.Errorf("On handshake test %v, error dialing origin: %#v", t.name, err) } defer conn.Close() defer conn.Purge() request := CustomHelo{ MessageType: "hello", DeviceId: deviceId, ChannelIds: []interface{}{t.channelId}, replies: make(chan client.Reply), errors: make(chan error), } reply, err := conn.WriteRequest(request) if t.statusCode >= 200 && t.statusCode < 300 { if err != nil { return fmt.Errorf("On handshake test %v, error writing request: %#v", t.name, err) } helo, ok := reply.(client.ServerHelo) if !ok { return fmt.Errorf("On handshake test %v, type assertion failed for reply: %#v", t.name, reply) } if helo.StatusCode != 200 { return fmt.Errorf("On handshake test %v, unexpected status code: got %#v; want 200", t.name, helo.StatusCode) } // The Simple Push server requires the channelIDs field to be present in // the handshake, but does not validate its contents, since any queued // messages will be immediately flushed to the client. if helo.DeviceId != deviceId { return fmt.Errorf("On handshake test %v, mismatched device ID: got %#v; want %#v", t.name, helo.DeviceId, deviceId) } return nil } if err != io.EOF { return fmt.Errorf("On handshake test %v, error writing request: got %#v; want io.EOF", t.name, err) } err = conn.Close() clientErr, ok := err.(client.Error) if !ok { return fmt.Errorf("On handshake test %v, type assertion failed for close error: %#v", t.name, err) } if clientErr.Status() != t.statusCode { return fmt.Errorf("On handshake test %v, unexpected close error status: got %#v; want %#v", t.name, clientErr.Status(), t.statusCode) } return nil }
func (t typeTest) Run() error { origin, err := testServer.Origin() if err != nil { return fmt.Errorf("On test %v, error initializing test server: %#v", t.name, err) } conn, err := client.DialOrigin(origin) if err != nil { return fmt.Errorf("On test %v, error dialing origin: %#v", t.name, err) } defer conn.Close() defer conn.Purge() request := CustomHelo{ MessageType: t.messageType, DeviceId: t.deviceId, ChannelIds: []interface{}{"1", "2"}, Extra: "custom value", replies: make(chan client.Reply), errors: make(chan error), } reply, err := conn.WriteRequest(request) if t.statusCode >= 200 && t.statusCode < 300 { if err != nil { return fmt.Errorf("On test %v, error writing handshake request: %#v", t.name, err) } helo, ok := reply.(client.ServerHelo) if !ok { return fmt.Errorf("On test %v, type assertion failed for handshake reply: %#v", t.name, reply) } if helo.StatusCode != t.statusCode { return fmt.Errorf("On test %v, unexpected reply status: got %#v; want %#v", t.name, helo.StatusCode, t.statusCode) } deviceId, _ := t.deviceId.(string) if len(deviceId) == 0 && !id.Valid(helo.DeviceId) { return fmt.Errorf("On test %v, got invalid device ID: %#v", t.name, helo.DeviceId) } else if !t.shouldReset && deviceId != helo.DeviceId { return fmt.Errorf("On test %v, mismatched device ID: got %#v; want %#v", t.name, helo.DeviceId, deviceId) } else if t.shouldReset && deviceId == helo.DeviceId { return fmt.Errorf("On test %v, want new device ID; got %#v", t.name, deviceId) } return nil } if err != io.EOF { return fmt.Errorf("On test %v, error writing handshake: got %#v; want io.EOF", t.name, err) } err = conn.Close() clientErr, ok := err.(client.Error) if !ok { return fmt.Errorf("On test %v, type assertion failed for close error: %#v", t.name, err) } if clientErr.Status() != t.statusCode { return fmt.Errorf("On test %v, unexpected close error status: got %#v; want %#v", t.name, clientErr.Status(), t.statusCode) } return nil }
func TestPrematureACK(t *testing.T) { channelId, err := id.Generate() if err != nil { t.Fatalf("Error generating channel ID: %#v", err) } origin, err := testServer.Origin() if err != nil { t.Fatalf("Error initializing test server: %#v", err) } conn, err := client.DialOrigin(origin) if err != nil { t.Fatalf("Error dialing origin: %#v", err) } defer conn.Close() defer conn.Purge() conn.RegisterDecoder("ack", client.DecoderFunc(decodeServerInvalidACK)) updates := []client.Update{ client.Update{ ChannelId: channelId, Version: time.Now().UTC().Unix(), }, } request := ClientInvalidACK{client.NewACK(updates, true)} reply, err := conn.WriteRequest(request) if err != nil { t.Fatalf("Error writing acknowledgement: %#v", err) } if reply.Status() != 401 { t.Errorf("Incorrect status code: got %#v, wanted 401", reply.Status()) } if r, ok := reply.(ServerInvalidACK); ok { if len(r.Updates) != len(updates) { t.Errorf("Incorrect update count: got %#v; want %#v", len(r.Updates), len(updates)) } else { for index, update := range r.Updates { if update != updates[index] { t.Errorf("On update %#v, got %#v; want %#v", index, update, updates[index]) } } } } else { t.Errorf("Type assertion failed for reply: %#v", reply) } // The connection should be closed by the push server after sending // the error response. if err = conn.Close(); err != io.EOF { t.Fatalf("Unexpected close error: got %#v; want io.EOF", err) } }
func (t caseTest) TestPing() error { origin, err := testServer.Origin() if err != nil { return fmt.Errorf("On test %v, error initializing test server: %#v", t.CaseTestType, err) } conn, err := client.DialOrigin(origin) if err != nil { return fmt.Errorf("On test %v, error dialing origin: %#v", t.CaseTestType, err) } defer conn.Close() defer conn.Purge() conn.RegisterDecoder("ping", client.DecoderFunc(decodePing)) request := CaseClientPing{t.CaseTestType, client.NewPing(true)} reply, err := conn.WriteRequest(request) if err != nil { return fmt.Errorf("On test %v, error writing ping packet: %#v", t.CaseTestType, err) } if reply.Status() != t.statusCode { return fmt.Errorf("On test %v, unexpected status code: got %#v; want %#v", t.CaseTestType, reply.Status(), t.statusCode) } return nil }
func TestDuplicateRegisterHandshake(t *testing.T) { deviceId, err := id.Generate() if err != nil { t.Fatalf("Error generating device ID: %#v", err) } addExistsHook(deviceId, true) defer removeExistsHook(deviceId) channelId, err := id.Generate() if err != nil { t.Fatalf("Error generating channel ID: %#v", err) } origin, err := testServer.Origin() if err != nil { t.Fatalf("Error initializing test server: %#v", err) } conn, err := client.DialOrigin(origin) if err != nil { t.Fatalf("Error dialing origin: %#v", err) } defer conn.Close() defer conn.Purge() actualId, err := conn.WriteHelo(deviceId, channelId) if err != nil { t.Fatalf("Error writing handshake request: %#v", err) } if actualId != deviceId { t.Errorf("Mismatched device ID: got %#v; want %#v", actualId, deviceId) } if !AllowDupes { return } endpoint, err := conn.Register(channelId) if err != nil { t.Fatalf("Error writing duplicate registration request: %#v", err) } if !isValidEndpoint(endpoint) { t.Errorf("Invalid push endpoint for channel %#v: %#v", channelId, endpoint) } }
func TestTooManyChannels(t *testing.T) { deviceId, err := id.Generate() if err != nil { t.Fatalf("Error generating device ID: %#v", err) } origin, err := testServer.Origin() if err != nil { t.Fatalf("Error initializing test server: %#v", err) } conn, err := client.DialOrigin(origin) if err != nil { t.Fatalf("Error dialing origin: %#v", err) } defer conn.Close() defer conn.Purge() actualId, err := conn.WriteHelo(deviceId, channelIds...) if err != nil { t.Fatalf("Error writing large handshake request: %#v", err) } if actualId == deviceId { t.Errorf("Want new device ID; got %#v", actualId) } }
func TestHandshakeWithId(t *testing.T) { origin, err := testServer.Origin() if err != nil { t.Fatalf("Error initializing test server: %#v", err) } deviceId, err := id.Generate() if err != nil { t.Fatalf("Error generating device ID: %#v", err) } conn, err := client.DialOrigin(origin) if err != nil { t.Fatalf("Error dialing origin: %#v", err) } defer conn.Close() defer conn.Purge() actualId, err := conn.WriteHelo(deviceId) if err != nil { t.Fatalf("Error writing handshake request: %#v", err) } if actualId != deviceId { t.Errorf("Mismatched device IDs: got %#v; want %#v", actualId, deviceId) } }
func TestDuplicateHandshake(t *testing.T) { deviceId, err := id.Generate() if err != nil { t.Fatalf("Error generating device ID: %#v", err) } origin, err := testServer.Origin() if err != nil { t.Fatalf("Error initializing test server: %#v", err) } conn, err := client.DialOrigin(origin) if err != nil { t.Fatalf("Error dialing origin: %#v", err) } defer conn.Close() defer conn.Purge() firstId, err := conn.WriteHelo(deviceId) if err != nil { t.Fatalf("Error writing initial handshake request: %#v", err) } if firstId != deviceId { t.Errorf("Mismatched device ID for initial handshake: got %#v; want %#v", firstId, deviceId) } secondId, err := conn.WriteHelo(firstId) if err != nil { t.Fatalf("Error writing duplicate handshake request: %#v", err) } if secondId != firstId { t.Errorf("Mismatched device ID for duplicate handshake: got %#v; want %#v", secondId, firstId) } thirdId, err := conn.WriteHelo("") if err != nil { t.Fatalf("Error writing implicit handshake request: %#v", err) } if thirdId != secondId { t.Errorf("Mismatched device ID for implicit handshake: got %#v; want %#v", thirdId, secondId) } }