func TestChannelTooLong(t *testing.T) { channelId, err := generateIdSize(32) 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.Dial(origin) if err != nil { t.Fatalf("Error dialing origin: %#v", err) } defer conn.Close() defer conn.Purge() _, err = conn.Register(channelId) if err != io.EOF { t.Fatalf("Error writing registration request with large channel ID: got %#v; want io.EOF", err) } err = conn.Close() if clientErr, ok := err.(client.Error); ok && clientErr.Status() != 401 { t.Errorf("Unexpected close error status: got %#v; want 401", clientErr.Status()) } else if !ok { t.Fatalf("Type assertion failed for close error: %#v", err) } }
func TestRegisterSeparate(t *testing.T) { origin, err := testServer.Origin() if err != nil { t.Fatalf("Error initializing test server: %#v", err) } conn, _, err := client.Dial(origin) if err != nil { t.Fatalf("Error dialing origin: %#v", err) } var registerWait sync.WaitGroup registerOne := func(channelId string) { defer registerWait.Done() endpoint, err := conn.Register(channelId) if err != nil { t.Errorf("On test %v, error writing registration request: %#v", channelId, err) return } if !isValidEndpoint(endpoint) { t.Errorf("On test %v, invalid push endpoint: %#v", channelId, endpoint) } } defer conn.Close() defer conn.Purge() registerWait.Add(len(channelIds)) for _, channelId := range channelIds { go registerOne(channelId) } registerWait.Wait() }
func TestUnregister(t *testing.T) { origin, err := testServer.Origin() if err != nil { t.Fatalf("Error initializing test server: %#v", err) } conn, _, err := client.Dial(origin) if err != nil { t.Fatalf("Error dialing origin: %#v", err) } defer conn.Close() defer conn.Purge() channelId, _, err := conn.Subscribe() if err != nil { t.Fatalf("Error subscribing to channel: %#v", err) } conn.RegisterDecoder("unregister", client.DecoderFunc(decodeUnregisterReply)) for index := 0; index < 2; index++ { request := client.NewUnregister(channelId, true) reply, err := conn.WriteRequest(request) if err != nil { t.Fatalf("Error writing deregistration request (attempt %d): %#v", index, err) } if reply.Status() != 200 { t.Errorf("Unexpected status code for deregistration attempt %d: got %#v, want 200", index, reply.Status()) } } }
func TestMultiRegister(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.Dial(origin) if err != nil { t.Fatalf("Error dialing origin: %#v", err) } defer conn.Close() defer conn.Purge() endpoint, err := conn.Register(channelId) if err != nil { t.Fatalf("Error writing registration request: %#v", err) } if !isValidEndpoint(endpoint) { t.Errorf("Invalid push endpoint: %#v", endpoint) } _, err = conn.Register("") if err != io.EOF { t.Fatalf("Error writing malformed registration request: got %#v; want io.EOF", err) } err = conn.Close() if clientErr, ok := err.(client.Error); ok && clientErr.Status() != 401 { t.Errorf("Unexpected close error status: got %#v; want 401", clientErr.Status()) } else if !ok { t.Fatalf("Type assertion failed for close error: %#v", err) } }
func TestMultipleRegister(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.Dial(origin) if err != nil { t.Fatalf("Error dialing origin: %#v", err) } defer conn.Close() defer conn.Purge() request := MultipleRegister{client.NewRegister(channelId).(client.ClientRegister)} _, err = conn.WriteRequest(request) if err != io.EOF { t.Fatalf("Error writing registration 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 TestDuplicateRegister(t *testing.T) { if !AllowDupes { t.Log("Duplicate channel IDs not supported; skipping test") return } origin, err := testServer.Origin() if err != nil { t.Fatalf("Error initializing test server: %#v", err) } conn, _, err := client.Dial(origin) if err != nil { t.Fatalf("Error dialing origin: %#v", err) } defer conn.Close() defer conn.Purge() channelId, endpoint, err := conn.Subscribe() if err != nil { t.Fatalf("Error subscribing to channel: %#v", err) } if !isValidEndpoint(endpoint) { t.Errorf("Invalid push endpoint for channel %#v: %#v", channelId, endpoint) } nextEndpoint, err := conn.Register(channelId) if err != nil { t.Fatalf("Error writing duplicate registration request: %#v", err) } if !isValidEndpoint(nextEndpoint) { t.Errorf("Invalid push endpoint for duplicate registration: %#v", nextEndpoint) } }
func (t *TestServer) Dial(channelIds ...string) ( app *Application, conn *client.Conn, err error) { if app, err = t.Listen(); err != nil { return } origin, err := t.Origin() if err != nil { return } if conn, _, err = client.Dial(origin, channelIds...); err != nil { return } return }
func TestACK(t *testing.T) { origin, err := testServer.Origin() if err != nil { t.Fatalf("Error initializing test server: %#v", err) } conn, _, err := client.Dial(origin) if err != nil { t.Fatalf("Error dialing origin: %#v", err) } defer conn.Close() defer conn.Purge() err = client.PushThrough(conn, 1, 1) if err != nil { t.Fatalf("Error sending and acknowledge update: %#v", err) } }
func TestDupeDisconnect(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: %s", err) } conn, deviceId, err := client.Dial(origin, channelId) if err != nil { t.Fatalf("Error dialing origin: %s", err) } defer conn.Close() stopChan := make(chan bool) defer close(stopChan) errChan := make(chan error) go func() { var err error select { case <-conn.CloseNotify(): case <-time.After(5 * time.Second): err = fmt.Errorf("Initial connection for %q not closed", deviceId) } select { case <-stopChan: case errChan <- err: } }() go func(dupeId string) { dupeConn, err := client.DialId(origin, &dupeId, channelId) if err != nil { err = fmt.Errorf("Error reconnecting to origin: %s", err) } defer dupeConn.Close() select { case <-stopChan: case errChan <- err: } }(deviceId) for i := 0; i < 2; i++ { if err := <-errChan; err != nil { t.Fatal(err) } } }
func TestPing(t *testing.T) { origin, err := testServer.Origin() if err != nil { t.Fatalf("Error initializing test server: %#v", err) } conn, _, err := client.Dial(origin) if err != nil { t.Fatalf("Error dialing origin: %#v", err) } defer conn.Close() defer conn.Purge() conn.RegisterDecoder("ping", client.DecoderFunc(decodePing)) var pingWait sync.WaitGroup writePing := func() { defer pingWait.Done() reply, err := conn.WriteRequest(client.NewPing(true)) if err != nil { t.Errorf("Error writing ping request: %#v", err) return } if reply.Status() != 200 { t.Errorf("Unexpected ping reply status code: got %#v; want 200", reply.Status()) } } writeRegister := func() { defer pingWait.Done() channelId, endpoint, err := conn.Subscribe() if err != nil { t.Errorf("Error subscribing to channel: %#v", err) } if !isValidEndpoint(endpoint) { t.Errorf("Invalid push endpoint for channel %#v: %#v", channelId, endpoint) } } pingWait.Add(2) go writeRegister() go writePing() pingWait.Wait() }
func (t idTest) TestRegister() error { origin, err := testServer.Origin() if err != nil { return fmt.Errorf("On registration test %v, error initializing test server: %#v", t.name, err) } conn, _, err := client.Dial(origin) if err != nil { return fmt.Errorf("On registration test %v, error dialing origin: %#v", t.name, err) } defer conn.Close() defer conn.Purge() request := CustomRegister{ ChannelId: 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 registration test %v, error writing request: %#v", t.name, err) } if reply.Status() != t.statusCode { return fmt.Errorf("On registration test %v, unexpected status code: got %#v; want %#v", t.name, reply.Status(), t.statusCode) } return nil } if err != io.EOF { return fmt.Errorf("On registration 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 registration test %v, type assertion failed for close error: %#v", t.name, err) } if clientErr.Status() != t.statusCode { return fmt.Errorf("On registration test %v, unexpected close error status: got %#v; want %#v", t.name, clientErr.Status(), t.statusCode) } return nil }
func connect(origin string) (deviceId, channelId, endpoint string, err error) { if channelId, err = id.Generate(); err != nil { err = fmt.Errorf("Error generating channel ID: %s", err) return } conn, deviceId, err := client.Dial(origin) if err != nil { err = fmt.Errorf("Error dialing origin: %s", err) return } defer conn.Close() defer conn.Purge() if endpoint, err = conn.Register(channelId); err != nil { err = fmt.Errorf("Error subscribing to channel %q: %s", channelId, err) return } if err = roundTrip(conn, deviceId, channelId, endpoint, 1); err != nil { err = fmt.Errorf("Error sending initial notification: %s", err) return } return }
func TestMissingKey(t *testing.T) { origin, err := Server.Origin() if err != nil { t.Fatalf("Error initializing test server: %#v", err) } conn, deviceId, err := client.Dial(origin) if err != nil { t.Fatalf("Error dialing origin: %#v", err) } defer conn.Close() channelId, endpoint, err := conn.Subscribe() if err != nil { t.Fatalf("Error subscribing to channel: %#v", err) } uri, err := url.ParseRequestURI(endpoint) if err != nil { t.Fatalf("Error parsing push endpoint %#v: %#v", endpoint, err) } keyDevice, keyChannel, ok := endpointIds(uri) if !ok { t.Errorf("Incomplete push endpoint: %#v", endpoint) } if keyDevice != deviceId { t.Errorf("Mismatched device IDs: got %#v; want %#v", keyDevice, deviceId) } if keyChannel != channelId { t.Errorf("Mismatched channel IDs: got %#v; want %#v", keyChannel, channelId) } newURI, _ := uri.Parse(fmt.Sprintf("/update/%s.", keyDevice)) err = client.Notify(newURI.String(), 1) clientErr, ok := err.(client.Error) if !ok { t.Errorf("Type assertion failed for endpoint error: %#v", err) } else if clientErr.Status() != 404 { t.Errorf("Unexpected endpoint status: got %#v; want 404", clientErr.Status()) } }