Skip to content
This repository was archived by the owner on Apr 22, 2025. It is now read-only.

Commit dc6c72c

Browse files
committed
FAB-4596 Improve code coverage
Improve code coverage for the fabric-sdk-java code base Change-Id: If9e62ee86315b70acfd0bbd8ab845b1775c71386 Signed-off-by: rickr <cr22rc@gmail.com>
1 parent 18b2e13 commit dc6c72c

File tree

3 files changed

+221
-44
lines changed

3 files changed

+221
-44
lines changed

src/main/java/org/hyperledger/fabric/sdk/Channel.java

Lines changed: 22 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1710,6 +1710,10 @@ Set<String> queryChannels(Peer peer) throws InvalidArgumentException, ProposalEx
17101710
}
17111711

17121712
ProposalResponse proposalResponse = proposalResponses.iterator().next();
1713+
if (proposalResponse.getStatus() != ChaincodeResponse.Status.SUCCESS) {
1714+
throw new ProposalException(format("Failed exception message is %s, status is %d", proposalResponse.getMessage(), proposalResponse.getStatus().getStatus()));
1715+
1716+
}
17131717

17141718
FabricProposalResponse.ProposalResponse fabricResponse = proposalResponse.getProposalResponse();
17151719
if (null == fabricResponse) {
@@ -1977,44 +1981,51 @@ private Pair(Peer peer, Future<FabricProposalResponse.ProposalResponse> future)
19771981
for (Peer peer : peers) {
19781982
logger.debug(format("Channel %s send proposal to peer %s at url %s",
19791983
name, peer.getName(), peer.getUrl()));
1980-
peerFuturePairs.add(new Pair(peer, peer.sendProposalAsync(signedProposal)));
1984+
Future<FabricProposalResponse.ProposalResponse> proposalResponseListenableFuture;
1985+
try {
1986+
proposalResponseListenableFuture = peer.sendProposalAsync(signedProposal);
1987+
} catch (Exception e) {
1988+
proposalResponseListenableFuture = new CompletableFuture<>();
1989+
((CompletableFuture) proposalResponseListenableFuture).completeExceptionally(e);
1990+
1991+
}
1992+
peerFuturePairs.add(new Pair(peer, proposalResponseListenableFuture));
1993+
19811994
}
19821995

19831996
Collection<ProposalResponse> proposalResponses = new ArrayList<>();
19841997
for (Pair peerFuturePair : peerFuturePairs) {
19851998

19861999
FabricProposalResponse.ProposalResponse fabricResponse = null;
19872000
String message;
1988-
int status;
2001+
int status = 500;
2002+
final String peerName = peerFuturePair.peer.getName();
19892003
try {
19902004
fabricResponse = peerFuturePair.future.get(transactionContext.getProposalWaitTime(), TimeUnit.MILLISECONDS);
19912005
message = fabricResponse.getResponse().getMessage();
19922006
status = fabricResponse.getResponse().getStatus();
19932007
logger.debug(format("Channel %s got back from peer %s status: %d, message: %s",
1994-
name, peerFuturePair.peer.getName(), status, message));
2008+
name, peerName, status, message));
19952009
} catch (InterruptedException e) {
1996-
message = "Sending proposal to " + peerFuturePair.peer.getName() + " failed because of interruption";
1997-
status = 500;
2010+
message = "Sending proposal to " + peerName + " failed because of interruption";
19982011
logger.error(message, e);
19992012
} catch (TimeoutException e) {
2000-
message = format("Sending proposal to " + peerFuturePair.peer.getName() + " failed because of timeout(%d milliseconds) expiration",
2013+
message = format("Sending proposal to " + peerName + " failed because of timeout(%d milliseconds) expiration",
20012014
transactionContext.getProposalWaitTime());
2002-
status = 500;
20032015
logger.error(message, e);
20042016
} catch (ExecutionException e) {
20052017
Throwable cause = e.getCause();
20062018
if (cause instanceof Error) {
2007-
String emsg = "Sending proposal to " + peerFuturePair.peer.getName() + " failed because of " + cause.getMessage();
2019+
String emsg = "Sending proposal to " + peerName + " failed because of " + cause.getMessage();
20082020
logger.error(emsg, new Exception(cause)); //wrapped in exception to get full stack trace.
20092021
throw (Error) cause;
20102022
} else {
20112023
if (cause instanceof StatusRuntimeException) {
2012-
message = format("Sending proposal to " + peerFuturePair.peer.getName() + " failed because of gRPC failure=%s",
2024+
message = format("Sending proposal to " + peerName + " failed because of: gRPC failure=%s",
20132025
((StatusRuntimeException) cause).getStatus());
20142026
} else {
2015-
message = format("Sending proposal to " + peerFuturePair.peer.getName() + " failed because of %s", cause.getMessage());
2027+
message = format("Sending proposal to " + peerName + " failed because of: %s", cause.getMessage());
20162028
}
2017-
status = 500;
20182029
logger.error(message, new Exception(cause)); //wrapped in exception to get full stack trace.
20192030
}
20202031
}

src/test/java/org/hyperledger/fabric/sdk/ChannelTest.java

Lines changed: 144 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,23 +14,40 @@
1414

1515
package org.hyperledger.fabric.sdk;
1616

17+
//Allow throwing undeclared checked execeptions in mock code.
18+
//CHECKSTYLE.OFF: IllegalImport
19+
20+
import java.lang.reflect.Field;
1721
import java.util.Arrays;
1822
import java.util.Collection;
1923
import java.util.concurrent.CompletableFuture;
2024

25+
import com.google.common.util.concurrent.ListenableFuture;
26+
import com.google.common.util.concurrent.SettableFuture;
27+
import io.grpc.Status;
28+
import io.grpc.StatusRuntimeException;
2129
import org.hyperledger.fabric.protos.common.Common;
2230
import org.hyperledger.fabric.protos.orderer.Ab;
31+
import org.hyperledger.fabric.protos.peer.FabricProposal;
32+
import org.hyperledger.fabric.protos.peer.FabricProposalResponse;
2333
import org.hyperledger.fabric.sdk.exception.InvalidArgumentException;
34+
import org.hyperledger.fabric.sdk.exception.PeerException;
2435
import org.hyperledger.fabric.sdk.exception.ProposalException;
2536
import org.hyperledger.fabric.sdk.exception.TransactionException;
2637
import org.junit.Assert;
2738
import org.junit.BeforeClass;
2839
import org.junit.Rule;
2940
import org.junit.Test;
3041
import org.junit.rules.ExpectedException;
42+
import sun.misc.Unsafe;
3143

3244
import static org.hyperledger.fabric.sdk.testutils.TestUtils.setField;
3345

46+
//CHECKSTYLE.ON: IllegalImport
47+
48+
49+
50+
3451
public class ChannelTest {
3552
private static HFClient hfclient = null;
3653
private static Channel shutdownChannel = null;
@@ -258,7 +275,6 @@ protected void parseConfigBlock() {
258275

259276
@Test
260277
public void testChannelShutdown() {
261-
Channel testChannel = null;
262278

263279
try {
264280

@@ -267,7 +283,7 @@ public void testChannelShutdown() {
267283
} catch (Exception e) {
268284

269285
Assert.assertTrue(e.getClass() == InvalidArgumentException.class);
270-
Assert.assertTrue(testChannel.isInitialized());
286+
Assert.assertTrue(shutdownChannel.isInitialized());
271287
}
272288

273289
}
@@ -605,4 +621,130 @@ public void testChannelQueryTransactionByIDNull() throws Exception {
605621

606622
}
607623

624+
@Test
625+
public void testQueryInstalledChaincodesThrowInterrupted() throws Exception {
626+
627+
thrown.expect(ProposalException.class);
628+
thrown.expectMessage("You interrupting me?");
629+
630+
final Channel channel = createRunningChannel(null);
631+
Peer peer = channel.getPeers().iterator().next();
632+
633+
setField(peer, "endorserClent", new MockEndorserClient(new InterruptedException("You interrupting me?")));
634+
635+
hfclient.queryChannels(peer);
636+
637+
}
638+
639+
@Test
640+
public void testQueryInstalledChaincodesThrowPeerException() throws Exception {
641+
642+
thrown.expect(ProposalException.class);
643+
thrown.expectMessage("rick did this:)");
644+
645+
final Channel channel = createRunningChannel(null);
646+
Peer peer = channel.getPeers().iterator().next();
647+
648+
setField(peer, "endorserClent", new MockEndorserClient(new PeerException("rick did this:)")));
649+
650+
hfclient.queryChannels(peer);
651+
652+
}
653+
654+
@Test
655+
public void testQueryInstalledChaincodesThrowTimeoutException() throws Exception {
656+
657+
thrown.expect(ProposalException.class);
658+
thrown.expectMessage("What time is it?");
659+
660+
final Channel channel = createRunningChannel(null);
661+
Peer peer = channel.getPeers().iterator().next();
662+
663+
setField(peer, "endorserClent", new MockEndorserClient(new PeerException("What time is it?")));
664+
665+
hfclient.queryChannels(peer);
666+
667+
}
668+
669+
@Test
670+
public void testQueryInstalledChaincodesERROR() throws Exception {
671+
672+
thrown.expect(Error.class);
673+
thrown.expectMessage("Error bad bad bad");
674+
675+
final Channel channel = createRunningChannel(null);
676+
Peer peer = channel.getPeers().iterator().next();
677+
678+
final SettableFuture<FabricProposalResponse.ProposalResponse> settableFuture = SettableFuture.create();
679+
settableFuture.setException(new Error("Error bad bad bad"));
680+
setField(peer, "endorserClent", new MockEndorserClient(settableFuture));
681+
682+
hfclient.queryChannels(peer);
683+
684+
}
685+
686+
@Test
687+
public void testQueryInstalledChaincodesStatusRuntimeException() throws Exception {
688+
689+
thrown.expect(ProposalException.class);
690+
thrown.expectMessage("ABORTED");
691+
692+
final Channel channel = createRunningChannel(null);
693+
Peer peer = channel.getPeers().iterator().next();
694+
695+
final SettableFuture<FabricProposalResponse.ProposalResponse> settableFuture = SettableFuture.create();
696+
settableFuture.setException(new StatusRuntimeException(Status.ABORTED));
697+
setField(peer, "endorserClent", new MockEndorserClient(settableFuture));
698+
699+
hfclient.queryChannels(peer);
700+
701+
}
702+
703+
class MockEndorserClient extends EndorserClient {
704+
final Throwable throwThis;
705+
private final ListenableFuture<FabricProposalResponse.ProposalResponse> returnedFuture;
706+
707+
MockEndorserClient(Throwable throwThis) {
708+
super(new Endpoint("grpc://loclhost:99", null).getChannelBuilder());
709+
if (throwThis == null) {
710+
throw new IllegalArgumentException("Can't throw a null!");
711+
}
712+
this.throwThis = throwThis;
713+
this.returnedFuture = null;
714+
}
715+
716+
MockEndorserClient(ListenableFuture<FabricProposalResponse.ProposalResponse> returnedFuture) {
717+
super(new Endpoint("grpc://loclhost:99", null).getChannelBuilder());
718+
this.throwThis = null;
719+
this.returnedFuture = returnedFuture;
720+
}
721+
722+
@Override
723+
public ListenableFuture<FabricProposalResponse.ProposalResponse> sendProposalAsync(FabricProposal.SignedProposal proposal) throws PeerException {
724+
if (throwThis != null) {
725+
getUnsafe().throwException(throwThis);
726+
}
727+
return returnedFuture;
728+
729+
}
730+
731+
@Override
732+
public boolean isChannelActive() {
733+
734+
return true;
735+
736+
}
737+
738+
private Unsafe getUnsafe() { //lets us throw undeclared exceptions.
739+
try {
740+
Field field = Unsafe.class.getDeclaredField("theUnsafe");
741+
field.setAccessible(true);
742+
return (Unsafe) field.get(null);
743+
} catch (Exception e) {
744+
throw new RuntimeException(e);
745+
}
746+
}
747+
}
748+
749+
608750
}

src/test/java/org/hyperledger/fabric/sdk/TestHFClient.java

Lines changed: 55 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,13 @@
1515
package org.hyperledger.fabric.sdk;
1616

1717
import java.io.File;
18-
import java.security.PrivateKey;
1918

2019
import org.hyperledger.fabric.sdk.security.CryptoSuite;
2120
import org.hyperledger.fabric.sdkintegration.SampleStore;
2221
import org.hyperledger.fabric.sdkintegration.SampleUser;
2322

23+
import static java.lang.String.format;
24+
2425
public class TestHFClient {
2526

2627
final File tempFile;
@@ -43,41 +44,46 @@ public static HFClient newInstance() throws Exception {
4344
}
4445
final SampleStore sampleStore = new SampleStore(sampleStoreFile);
4546

46-
SampleUser someTestUSER = sampleStore.getMember("someTestUSER", "someTestORG");
47+
//src/test/fixture/sdkintegration/e2e-2Orgs/channel/crypto-config/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp/keystore/
48+
49+
//SampleUser someTestUSER = sampleStore.getMember("someTestUSER", "someTestORG");
50+
SampleUser someTestUSER = sampleStore.getMember("someTestUSER", "someTestORG", "mspid",
51+
findFileSk("src/test/fixture/sdkintegration/e2e-2Orgs/channel/crypto-config/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp/keystore"),
52+
new File("src/test/fixture/sdkintegration/e2e-2Orgs/channel/crypto-config/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp/signcerts/Admin@org1.example.com-cert.pem"));
4753
someTestUSER.setMspId("testMSPID?");
4854

4955
HFClient hfclient = HFClient.createNewInstance();
5056
hfclient.setCryptoSuite(CryptoSuite.Factory.getCryptoSuite());
5157

52-
someTestUSER.setEnrollment(new Enrollment() {
53-
@Override
54-
public PrivateKey getKey() {
55-
return new PrivateKey() {
56-
private static final long serialVersionUID = -7506317638561401152L;
57-
58-
@Override
59-
public String getAlgorithm() {
60-
return "algorithm?";
61-
}
62-
63-
@Override
64-
public String getFormat() {
65-
return "format?";
66-
}
67-
68-
@Override
69-
public byte[] getEncoded() {
70-
return new byte[0];
71-
}
72-
};
73-
}
74-
75-
@Override
76-
public String getCert() {
77-
return "fakecert?";
78-
}
79-
80-
});
58+
// someTestUSER.setEnrollment(new Enrollment() {
59+
// @Override
60+
// public PrivateKey getKey() {
61+
// return new PrivateKey() {
62+
// private static final long serialVersionUID = -7506317638561401152L;
63+
//
64+
// @Override
65+
// public String getAlgorithm() {
66+
// return "algorithm?";
67+
// }
68+
//
69+
// @Override
70+
// public String getFormat() {
71+
// return "format?";
72+
// }
73+
//
74+
// @Override
75+
// public byte[] getEncoded() {
76+
// return new byte[0];
77+
// }
78+
// };
79+
// }
80+
//
81+
// @Override
82+
// public String getCert() {
83+
// return "fakecert?";
84+
// }
85+
//
86+
// });
8187
hfclient.setUserContext(someTestUSER);
8288

8389

@@ -87,6 +93,24 @@ public String getCert() {
8793

8894
}
8995

96+
static File findFileSk(String directorys) {
97+
98+
File directory = new File(directorys);
99+
100+
File[] matches = directory.listFiles((dir, name) -> name.endsWith("_sk"));
101+
102+
if (null == matches) {
103+
throw new RuntimeException(format("Matches returned null does %s directory exist?", directory.getAbsoluteFile().getName()));
104+
}
105+
106+
if (matches.length != 1) {
107+
throw new RuntimeException(format("Expected in %s only 1 sk file but found %d", directory.getAbsoluteFile().getName(), matches.length));
108+
}
109+
110+
return matches[0];
111+
112+
}
113+
90114
@Override
91115
protected void finalize() throws Throwable {
92116
super.finalize();

0 commit comments

Comments
 (0)