### Question:
InstalledProtocolsProcedure extends CallableProcedure.BasicProcedure { @Override public RawIterator<Object[],ProcedureException> apply( Context ctx, Object[] input, ResourceTracker resourceTracker ) { Stream<Object[]> outbound = toOutputRows( clientInstalledProtocols, ProtocolInstaller.Orientation.Client.OUTBOUND ); Stream<Object[]> inbound = toOutputRows( serverInstalledProtocols, ProtocolInstaller.Orientation.Server.INBOUND ); return Iterators.asRawIterator( Stream.concat( outbound, inbound ) ); } InstalledProtocolsProcedure( Supplier<Stream<Pair<AdvertisedSocketAddress,ProtocolStack>>> clientInstalledProtocols,
            Supplier<Stream<Pair<SocketAddress,ProtocolStack>>> serverInstalledProtocols ); @Override RawIterator<Object[],ProcedureException> apply(
            Context ctx, Object[] input, ResourceTracker resourceTracker ); static final String PROCEDURE_NAME; }### Answer:
@Test public void shouldHaveEmptyOutputIfNoInstalledProtocols() throws Throwable { InstalledProtocolsProcedure installedProtocolsProcedure = new InstalledProtocolsProcedure( Stream::empty, Stream::empty ); RawIterator<Object[],ProcedureException> result = installedProtocolsProcedure.apply( null, null, null ); assertFalse( result.hasNext() ); }
@Test public void shouldListOutboundProtocols() throws Throwable { InstalledProtocolsProcedure installedProtocolsProcedure = new InstalledProtocolsProcedure( () -> Stream.of( outbound1, outbound2 ), Stream::empty ); RawIterator<Object[],ProcedureException> result = installedProtocolsProcedure.apply( null, null, null ); assertThat( result.next(), arrayContaining( "outbound", "host1:1", "raft", 1L, "[TestSnappy]" ) ); assertThat( result.next(), arrayContaining( "outbound", "host2:2", "raft", 2L, "[TestSnappy,ROT13]" ) ); assertFalse( result.hasNext() ); }
@Test public void shouldListInboundProtocols() throws Throwable { InstalledProtocolsProcedure installedProtocolsProcedure = new InstalledProtocolsProcedure( Stream::empty, () -> Stream.of( inbound1, inbound2 ) ); RawIterator<Object[],ProcedureException> result = installedProtocolsProcedure.apply( null, null, null ); assertThat( result.next(), arrayContaining( "inbound", "host3:3", "raft", 3L, "[TestSnappy]" ) ); assertThat( result.next(), arrayContaining( "inbound", "host4:4", "raft", 4L, "[]" ) ); assertFalse( result.hasNext() ); }
@Test public void shouldListInboundAndOutboundProtocols() throws Throwable { InstalledProtocolsProcedure installedProtocolsProcedure = new InstalledProtocolsProcedure( () -> Stream.of( outbound1, outbound2 ), () -> Stream.of( inbound1, inbound2 ) ); RawIterator<Object[],ProcedureException> result = installedProtocolsProcedure.apply( null, null, null ); assertThat( result.next(), arrayContaining( "outbound", "host1:1", "raft", 1L, "[TestSnappy]" ) ); assertThat( result.next(), arrayContaining( "outbound", "host2:2", "raft", 2L, "[TestSnappy,ROT13]" ) ); assertThat( result.next(), arrayContaining( "inbound", "host3:3", "raft", 3L, "[TestSnappy]" ) ); assertThat( result.next(), arrayContaining( "inbound", "host4:4", "raft", 4L, "[]" ) ); assertFalse( result.hasNext() ); }