lib/src/test/java/io/ably/lib/test/realtime/RealtimePresenceTest.java
/**
     * Test if presence sync works as it should
     * Tests RTP18a, RTP18b, RTP2f
     */
Test if presence sync works as it should
Tests RTP18a, RTP18b, RTP2f
Test if presence sync works as it should Tests RTP18a RTP18b RTP2f
@Test
    public void presence_sync() {
        AblyRealtime ably = null;
        try {
            ClientOptions opts = createOptions(testVars.keys[0].keyStr);
            ably = new AblyRealtime(opts);
            final String channelName = "presence_sync_test" + testParams.name;
            final Channel channel = ably.channels.get(channelName);
            channel.attach();
            ChannelWaiter channelWaiter = new ChannelWaiter(channel);
            channelWaiter.waitFor(ChannelState.attached);
            final ArrayList<PresenceMessage> presenceHistory = new ArrayList<>();
            channel.presence.subscribe(new Presence.PresenceListener() {
                @Override
                public void onPresenceMessage(PresenceMessage message) {
                    presenceHistory.add(message);
                }
            });
            final PresenceMessage[] testPresence1 = new PresenceMessage[] {
                    /* Will be discarded because we'll start new sync with different channelSerial */
                    new PresenceMessage() {{
                        clientId = "1";
                        action = Action.enter;
                        connectionId = "1";
                        id = "1:0";
                    }}
            };
            final PresenceMessage[] testPresence2 = new PresenceMessage[] {
                    new PresenceMessage() {{
                        clientId = "2";
                        action = Action.enter;
                        connectionId = "2";
                        id = "2:1:0";
                    }},
                    /* Enter presence message here is newer than leave in the subsequent message */
                    new PresenceMessage() {{
                        clientId = "3";
                        action = Action.enter;
                        connectionId = "3";
                        id = "3:1:0";
                    }}
            };
            final PresenceMessage[] testPresence3 = new PresenceMessage[] {
                    new PresenceMessage() {{
                        clientId = "3";
                        action = Action.leave;
                        connectionId = "3";
                        id = "3:0:0";
                    }},
                    new PresenceMessage() {{
                        clientId = "4";
                        action = Action.enter;
                        connectionId = "4";
                        id = "4:1:1";
                    }},
                    new PresenceMessage() {{
                        clientId = "4";
                        action = Action.leave;
                        connectionId = "4";
                        id = "4:2:2";
                    }}
            };
            final boolean[] seenLeaveMessageAsAbsentForClient4 = new boolean[] {false};
            channel.presence.subscribe(Action.leave, new Presence.PresenceListener() {
                @Override
                public void onPresenceMessage(PresenceMessage message) {
                    try {
                        /*
                         * Do not call it in states other than ATTACHED because of presence.get() side
                         * effect of attaching channel
                         */
                        if (message.clientId.equals("4") && message.action == Action.leave && channel.state == ChannelState.attached) {
                            /*
                             * Client library won't return a presence message if it is stored as ABSENT
                             * so the result of the presence.get() call should be empty. This is the
                             * only case when get() called from PresenceListener.onPresenceMessage results
                             * in an empty answer.
                             */
                            seenLeaveMessageAsAbsentForClient4[0] = channel.presence.get("4", false).length == 0;
                        }
                    } catch (AblyException e) {}
                }
            });
            ably.connection.connectionManager.onMessage(null, new ProtocolMessage() {{
                action = Action.sync;
                channel = channelName;
                channelSerial = "1:1";
                presence = testPresence1;
            }});
            ably.connection.connectionManager.onMessage(null, new ProtocolMessage() {{
                action = Action.sync;
                channel = channelName;
                channelSerial = "2:1";
                presence = testPresence2;
            }});
            ably.connection.connectionManager.onMessage(null, new ProtocolMessage() {{
                action = Action.sync;
                channel = channelName;
                channelSerial = "2:";
                presence = testPresence3;
            }});
            assertEquals("Verify incomplete sync was discarded", channel.presence.get("1", false).length, 0);
            assertEquals("Verify client with id==2 is in presence map", channel.presence.get("2", false).length, 1);
            assertEquals("Verify client with id==3 is in presence map", channel.presence.get("3", false).length, 1);
            assertEquals("Verify nothing else is in presence map", channel.presence.get(false).length, 2);
            assertTrue("Verify LEAVE message for client with id==4 was stored as ABSENT", seenLeaveMessageAsAbsentForClient4[0]);
            PresenceMessage[] correctPresenceHistory = new PresenceMessage[] {
                    /* client 1 enters (will later be discarded) */
                    new PresenceMessage(Action.enter, "1"),
                    /* client 2 enters */
                    new PresenceMessage(Action.enter, "2"),
                    /* client 3 enters and never leaves because of newness comparison for LEAVE fails */
                    new PresenceMessage(Action.enter, "3"),
                    /* client 4 enters and leaves */
                    new PresenceMessage(Action.enter, "4"),
                    new PresenceMessage(Action.leave, "4"),
                    /* client 1 is eliminated from the presence map because the first portion of SYNC is discarded */
                    new PresenceMessage(Action.leave, "1")
            };
            assertEquals("Verify number of presence messages", presenceHistory.size(), correctPresenceHistory.length);
            for (int i=0; i<correctPresenceHistory.length; i++) {
                PresenceMessage factualMsg = presenceHistory.get(i);
                PresenceMessage correctMsg = correctPresenceHistory[i];
                assertTrue("Verify presence message correctness",
                        factualMsg.clientId.equals(correctMsg.clientId) && factualMsg.action == correctMsg.action);
            }
        } catch (AblyException e) {
            e.printStackTrace();
            fail("Unexpected exception running test: " + e.getMessage());
        } finally {
            if (ably != null)
                ably.close();
        }
    }
@ Test public void presence_sync ( ) { AblyRealtime ably = null ; try { ClientOptions opts = createOptions ( testVars . keys [ 0 ] . keyStr ) ; ably = new AblyRealtime ( opts ) ; final String channelName = "presence_sync_test" + testParams . name ; final Channel channel = ably . channels . get ( channelName ) ; channel . attach ( ) ; ChannelWaiter channelWaiter = new ChannelWaiter ( channel ) ; channelWaiter . waitFor ( ChannelState . attached ) ; final ArrayList < PresenceMessage > presenceHistory = new ArrayList < > ( ) ; channel . presence . subscribe ( new Presence . PresenceListener ( ) { @ Override public void onPresenceMessage ( PresenceMessage message ) { presenceHistory . add ( message ) ; } } ) ; final PresenceMessage [ ] testPresence1 = new PresenceMessage [ ] { /* Will be discarded because we'll start new sync with different channelSerial */ new PresenceMessage ( ) { { clientId = "1" ; action = Action . enter ; connectionId = "1" ; id = "1:0" ; } } } ; final PresenceMessage [ ] testPresence2 = new PresenceMessage [ ] { new PresenceMessage ( ) { { clientId = "2" ; action = Action . enter ; connectionId = "2" ; id = "2:1:0" ; } } , /* Enter presence message here is newer than leave in the subsequent message */ new PresenceMessage ( ) { { clientId = "3" ; action = Action . enter ; connectionId = "3" ; id = "3:1:0" ; } } } ; final PresenceMessage [ ] testPresence3 = new PresenceMessage [ ] { new PresenceMessage ( ) { { clientId = "3" ; action = Action . leave ; connectionId = "3" ; id = "3:0:0" ; } } , new PresenceMessage ( ) { { clientId = "4" ; action = Action . enter ; connectionId = "4" ; id = "4:1:1" ; } } , new PresenceMessage ( ) { { clientId = "4" ; action = Action . leave ; connectionId = "4" ; id = "4:2:2" ; } } } ; final boolean [ ] seenLeaveMessageAsAbsentForClient4 = new boolean [ ] { false } ; channel . presence . subscribe ( Action . leave , new Presence . PresenceListener ( ) { @ Override public void onPresenceMessage ( PresenceMessage message ) { try { /*
                         * Do not call it in states other than ATTACHED because of presence.get() side
                         * effect of attaching channel
                         */ if ( message . clientId . equals ( "4" ) && message . action == Action . leave && channel . state == ChannelState . attached ) { /*
                             * Client library won't return a presence message if it is stored as ABSENT
                             * so the result of the presence.get() call should be empty. This is the
                             * only case when get() called from PresenceListener.onPresenceMessage results
                             * in an empty answer.
                             */ seenLeaveMessageAsAbsentForClient4 [ 0 ] = channel . presence . get ( "4" , false ) . length == 0 ; } } catch ( AblyException e ) { } } } ) ; ably . connection . connectionManager . onMessage ( null , new ProtocolMessage ( ) { { action = Action . sync ; channel = channelName ; channelSerial = "1:1" ; presence = testPresence1 ; } } ) ; ably . connection . connectionManager . onMessage ( null , new ProtocolMessage ( ) { { action = Action . sync ; channel = channelName ; channelSerial = "2:1" ; presence = testPresence2 ; } } ) ; ably . connection . connectionManager . onMessage ( null , new ProtocolMessage ( ) { { action = Action . sync ; channel = channelName ; channelSerial = "2:" ; presence = testPresence3 ; } } ) ; assertEquals ( "Verify incomplete sync was discarded" , channel . presence . get ( "1" , false ) . length , 0 ) ; assertEquals ( "Verify client with id==2 is in presence map" , channel . presence . get ( "2" , false ) . length , 1 ) ; assertEquals ( "Verify client with id==3 is in presence map" , channel . presence . get ( "3" , false ) . length , 1 ) ; assertEquals ( "Verify nothing else is in presence map" , channel . presence . get ( false ) . length , 2 ) ; assertTrue ( "Verify LEAVE message for client with id==4 was stored as ABSENT" , seenLeaveMessageAsAbsentForClient4 [ 0 ] ) ; PresenceMessage [ ] correctPresenceHistory = new PresenceMessage [ ] { /* client 1 enters (will later be discarded) */ new PresenceMessage ( Action . enter , "1" ) , /* client 2 enters */ new PresenceMessage ( Action . enter , "2" ) , /* client 3 enters and never leaves because of newness comparison for LEAVE fails */ new PresenceMessage ( Action . enter , "3" ) , /* client 4 enters and leaves */ new PresenceMessage ( Action . enter , "4" ) , new PresenceMessage ( Action . leave , "4" ) , /* client 1 is eliminated from the presence map because the first portion of SYNC is discarded */ new PresenceMessage ( Action . leave , "1" ) } ; assertEquals ( "Verify number of presence messages" , presenceHistory . size ( ) , correctPresenceHistory . length ) ; for ( int i = 0 ; i < correctPresenceHistory . length ; i ++ ) { PresenceMessage factualMsg = presenceHistory . get ( i ) ; PresenceMessage correctMsg = correctPresenceHistory [ i ] ; assertTrue ( "Verify presence message correctness" , factualMsg . clientId . equals ( correctMsg . clientId ) && factualMsg . action == correctMsg . action ) ; } } catch ( AblyException e ) { e . printStackTrace ( ) ; fail ( "Unexpected exception running test: " + e . getMessage ( ) ) ; } finally { if ( ably != null ) ably . close ( ) ; } }
Test if presence sync works as it should
 Tests RTP18a, RTP18b, RTP2f
Test if presence sync works as it should Tests RTP18a RTP18b RTP2f