I'm getting the exception com.google.appengine.api.datastore.DatastoreFailureException: Unexpected failure
while trying to implement jBehave with Google App Engine. jBehave essentially runs on top of junit so I don't think jBehave itself is the problem.
This exception is thrown in about 1 out of every 3 runs of the test. I thought it might have been issues of consistency with the LocalServiceTestHelper so I tried configuring the LocalServiceTestHelper various ways which are supposed to ease testing by ensuring the data makes it to the database and can be read back for testing purposes.
Try #1:
private final LocalServiceTestHelper helper =
new LocalServiceTestHelper((new LocalDatastoreServiceTestConfig()));
Try #2:
private final LocalServiceTestHelper helper =
new LocalServiceTestHelper((new LocalDatastoreServiceTestConfig())
.setDefaultHighRepJobPolicyUnappliedJobPercentage(0));
Try #3:
private final LocalServiceTestHelper helper =
new LocalServiceTestHelper((new LocalDatastoreServiceTestConfig())
.setApplyAllHighRepJobPolicy());
However all of these attempts led to the same problem, namely the DatastoreFailureException in approximately 1 out of every 3 runs of the test.
Here's a full stack trace:
Processing system properties {}
Using controls EmbedderControls[batch=false,skip=false,generateViewAfterStories=true,ignoreFailureInStories=false,ignoreFailureInView=false,verboseFailures=false,verboseFiltering=false,storyTimeoutInSecs=300,failOnStoryTimeout=false,threads=1]
(BeforeStories)
Running story com/uluvit/backend/acceptance/user_can_log_in_using_email.story
User can send assumption what its partner think
(com/uluvit/backend/acceptance/user_can_log_in_using_email.story)
Narrative:
As a user
I want to log in using my email account which was registered before
So that I can start playing
Scenario:
(AfterStories)
Generating reports view to '/Users/mosofsky/Developer/UluvitServer/uluvit-backend-war/target/jbehave' using formats '[stats, console, txt]' and view properties '{navigator=ftl/jbehave-navigator.ftl, views=ftl/jbehave-views.ftl, reports=ftl/jbehave-reports-with-totals.ftl, nonDecorated=ftl/jbehave-report-non-decorated.ftl, decorated=ftl/jbehave-report-decorated.ftl, maps=ftl/jbehave-maps.ftl}'
Given A user John Test with email [email protected] and password test123 (FAILED)
(com.google.appengine.api.datastore.DatastoreFailureException: Unexpected failure)
Nov 11, 2014 3:38:08 AM com.google.appengine.api.datastore.dev.LocalDatastoreService init
INFO: Local Datastore initialized:
Type: Master/Slave
Storage: In-memory
When I log in using email [email protected] and password test123 (NOT PERFORMED)
Then I should see main screen (NOT PERFORMED)
org.jbehave.core.failures.UUIDExceptionWrapper: Given A user John Test with email [email protected] and password test123
at org.jbehave.core.steps.StepCreator$ParametrisedStep.perform(StepCreator.java:609)
at org.jbehave.core.embedder.StoryRunner$FineSoFar.run(StoryRunner.java:535)
at org.jbehave.core.embedder.StoryRunner.runStepsWhileKeepingState(StoryRunner.java:515)
at org.jbehave.core.embedder.StoryRunner.runScenarioSteps(StoryRunner.java:479)
at org.jbehave.core.embedder.StoryRunner.runStepsWithLifecycle(StoryRunner.java:445)
at org.jbehave.core.embedder.StoryRunner.runCancellable(StoryRunner.java:305)
at org.jbehave.core.embedder.StoryRunner.run(StoryRunner.java:220)
at org.jbehave.core.embedder.StoryRunner.run(StoryRunner.java:181)
at org.jbehave.core.embedder.StoryManager$EnqueuedStory.call(StoryManager.java:255)
at org.jbehave.core.embedder.StoryManager$EnqueuedStory.call(StoryManager.java:222)
at java.util.concurrent.FutureTask.run(FutureTask.java:262)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:745)
Caused by: com.google.appengine.api.datastore.DatastoreFailureException: Unexpected failure
at com.google.appengine.api.datastore.FutureHelper.getInternal(FutureHelper.java:74)
at com.google.appengine.api.datastore.FutureHelper.quietGet(FutureHelper.java:32)
at com.google.appengine.api.datastore.QueryResultsSourceImpl.peekQueryResultAndIfFirstRecordIndexList(QueryResultsSourceImpl.java:161)
at com.google.appengine.api.datastore.QueryResultsSourceImpl.loadMoreEntities(QueryResultsSourceImpl.java:104)
at com.google.appengine.api.datastore.QueryResultsSourceImpl.loadMoreEntities(QueryResultsSourceImpl.java:91)
at com.google.appengine.api.datastore.QueryResultIteratorImpl.ensureLoaded(QueryResultIteratorImpl.java:142)
at com.google.appengine.api.datastore.QueryResultIteratorImpl.hasNext(QueryResultIteratorImpl.java:62)
at com.googlecode.objectify.impl.KeysOnlyIterator.hasNext(KeysOnlyIterator.java:29)
at com.googlecode.objectify.impl.ChunkIterator.next(ChunkIterator.java:48)
at com.googlecode.objectify.impl.ChunkIterator.next(ChunkIterator.java:20)
at com.google.common.collect.Iterators$5.hasNext(Iterators.java:548)
at com.google.common.collect.Iterators$PeekingImpl.hasNext(Iterators.java:1149)
at com.googlecode.objectify.impl.ChunkingIterator.hasNext(ChunkingIterator.java:51)
at com.google.common.collect.Iterators.addAll(Iterators.java:361)
at com.google.common.collect.Lists.newArrayList(Lists.java:160)
at com.google.common.collect.Lists.newArrayList(Lists.java:144)
at com.googlecode.objectify.util.MakeListResult.translate(MakeListResult.java:21)
at com.googlecode.objectify.util.MakeListResult.translate(MakeListResult.java:11)
at com.googlecode.objectify.util.ResultTranslator.nowUncached(ResultTranslator.java:21)
at com.googlecode.objectify.util.ResultCache.now(ResultCache.java:30)
at com.googlecode.objectify.util.ResultProxy.invoke(ResultProxy.java:34)
at com.sun.proxy.$Proxy37.size(Unknown Source)
at com.uluvit.backend.domain.repository.GoogleStoreUserRepository.findByEmail(GoogleStoreUserRepository.java:59)
at com.uluvit.backend.domain.repository.GoogleStoreUserRepository.persist(GoogleStoreUserRepository.java:25)
at com.uluvit.backend.acceptance.UluvitSteps.givenAUserWithEmailAndPassword(UluvitSteps.java:97)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.jbehave.core.steps.StepCreator$ParametrisedStep.perform(StepCreator.java:595)
... 13 more
Caused by: java.lang.InterruptedException
at java.util.concurrent.FutureTask.awaitDone(FutureTask.java:400)
at java.util.concurrent.FutureTask.get(FutureTask.java:187)
at com.google.appengine.tools.development.ApiProxyLocalImpl$PrivilegedApiAction$1.get(ApiProxyLocalImpl.java:304)
at com.google.appengine.tools.development.ApiProxyLocalImpl$PrivilegedApiAction$1.get(ApiProxyLocalImpl.java:271)
at com.google.appengine.api.utils.FutureWrapper.get(FutureWrapper.java:86)
at com.google.appengine.api.utils.FutureWrapper.get(FutureWrapper.java:86)
at com.google.appengine.api.datastore.FutureHelper.getInternal(FutureHelper.java:71)
... 42 more
Reports view generated with 0 stories (of which 0 pending) containing 0 scenarios (of which 0 pending)
Upgrading from JBehave 3.9.4 to 3.9.5 fixed this problem. It also resolved this problem: Plugin execution not covered by lifecycle configuration (JBossas 7 EAR archetype)