4141import org .junit .AfterClass ;
4242import org .junit .Before ;
4343import org .junit .BeforeClass ;
44+ import org .junit .Rule ;
4445import org .junit .Test ;
46+ import org .junit .rules .ExpectedException ;
4547import org .junit .runner .RunWith ;
4648import org .junit .runners .JUnit4 ;
4749
@@ -103,6 +105,9 @@ public class DatastoreTest {
103105 private static LocalGcdHelper gcdHelper ;
104106 private static final int PORT = LocalGcdHelper .findAvailablePort (LocalGcdHelper .DEFAULT_PORT );
105107
108+ @ Rule
109+ public ExpectedException thrown = ExpectedException .none ();
110+
106111 @ BeforeClass
107112 public static void beforeClass () throws IOException , InterruptedException {
108113 if (!LocalGcdHelper .isActive (PROJECT_ID , PORT )) {
@@ -636,7 +641,7 @@ public void testKeyFactory() {
636641 }
637642
638643 @ Test
639- public void testRetires () throws Exception {
644+ public void testRetryableException () throws Exception {
640645 DatastoreV1 .LookupRequest requestPb =
641646 DatastoreV1 .LookupRequest .newBuilder ().addKey (KEY1 .toPb ()).build ();
642647 DatastoreV1 .LookupResponse responsePb = DatastoreV1 .LookupResponse .newBuilder ()
@@ -658,4 +663,51 @@ public void testRetires() throws Exception {
658663 assertEquals (ENTITY1 , entity );
659664 EasyMock .verify (rpcFactoryMock , rpcMock );
660665 }
666+
667+ @ Test
668+ public void testNonRetryableException () throws Exception {
669+ DatastoreV1 .LookupRequest requestPb =
670+ DatastoreV1 .LookupRequest .newBuilder ().addKey (KEY1 .toPb ()).build ();
671+ DatastoreRpcFactory rpcFactoryMock = EasyMock .createStrictMock (DatastoreRpcFactory .class );
672+ DatastoreRpc rpcMock = EasyMock .createStrictMock (DatastoreRpc .class );
673+ EasyMock .expect (rpcFactoryMock .create (EasyMock .anyObject (DatastoreOptions .class )))
674+ .andReturn (rpcMock );
675+ EasyMock .expect (rpcMock .lookup (requestPb ))
676+ .andThrow (new DatastoreRpc .DatastoreRpcException (Reason .PERMISSION_DENIED ))
677+ .times (1 );
678+ EasyMock .replay (rpcFactoryMock , rpcMock );
679+ RetryParams retryParams = RetryParams .builder ().retryMinAttempts (2 ).build ();
680+ DatastoreOptions options = this .options .toBuilder ()
681+ .retryParams (retryParams )
682+ .serviceRpcFactory (rpcFactoryMock )
683+ .build ();
684+ Datastore datastore = DatastoreFactory .instance ().get (options );
685+ thrown .expect (DatastoreException .class );
686+ thrown .expectMessage (Reason .PERMISSION_DENIED .description ());
687+ datastore .get (KEY1 );
688+ EasyMock .verify (rpcFactoryMock , rpcMock );
689+ }
690+
691+ @ Test
692+ public void testRuntimeException () throws Exception {
693+ DatastoreV1 .LookupRequest requestPb =
694+ DatastoreV1 .LookupRequest .newBuilder ().addKey (KEY1 .toPb ()).build ();
695+ DatastoreRpcFactory rpcFactoryMock = EasyMock .createStrictMock (DatastoreRpcFactory .class );
696+ DatastoreRpc rpcMock = EasyMock .createStrictMock (DatastoreRpc .class );
697+ EasyMock .expect (rpcFactoryMock .create (EasyMock .anyObject (DatastoreOptions .class )))
698+ .andReturn (rpcMock );
699+ String exceptionMessage = "Artificial runtime exception" ;
700+ EasyMock .expect (rpcMock .lookup (requestPb ))
701+ .andThrow (new RuntimeException (exceptionMessage ));
702+ EasyMock .replay (rpcFactoryMock , rpcMock );
703+ DatastoreOptions options = this .options .toBuilder ()
704+ .retryParams (RetryParams .getDefaultInstance ())
705+ .serviceRpcFactory (rpcFactoryMock )
706+ .build ();
707+ Datastore datastore = DatastoreFactory .instance ().get (options );
708+ thrown .expect (DatastoreException .class );
709+ thrown .expectMessage (exceptionMessage );
710+ datastore .get (KEY1 );
711+ EasyMock .verify (rpcFactoryMock , rpcMock );
712+ }
661713}
0 commit comments