// Copyright 2011 Google Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may not
// use this file except in compliance with the License. You may obtain a copy of
// the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
// License for the specific language governing permissions and limitations under
// the License.
package com.google.appengine.tools.pipeline;
import static com.google.appengine.tools.pipeline.impl.util.GUIDGenerator.USE_SIMPLE_GUIDS_FOR_DEBUGGING;
import com.google.appengine.api.taskqueue.dev.LocalTaskQueue;
import com.google.appengine.api.taskqueue.dev.QueueStateInfo;
import com.google.appengine.tools.development.testing.LocalDatastoreServiceTestConfig;
import com.google.appengine.tools.development.testing.LocalModulesServiceTestConfig;
import com.google.appengine.tools.development.testing.LocalServiceTestHelper;
import com.google.appengine.tools.development.testing.LocalTaskQueueTestConfig;
import com.google.apphosting.api.ApiProxy;
import junit.framework.TestCase;
import java.util.Map;
/**
* @author rudominer@google.com (Mitch Rudominer)
*
*/
public class PipelineTest extends TestCase {
protected LocalServiceTestHelper helper;
protected ApiProxy.Environment apiProxyEnvironment;
private static StringBuffer traceBuffer;
private LocalTaskQueue taskQueue;
public PipelineTest() {
LocalTaskQueueTestConfig taskQueueConfig = new LocalTaskQueueTestConfig();
taskQueueConfig.setCallbackClass(TestingTaskQueueCallback.class);
taskQueueConfig.setDisableAutoTaskExecution(false);
taskQueueConfig.setShouldCopyApiProxyEnvironment(true);
helper = new LocalServiceTestHelper(
new LocalDatastoreServiceTestConfig()
.setDefaultHighRepJobPolicyUnappliedJobPercentage(
isHrdSafe() ? 100 : 0),
taskQueueConfig, new LocalModulesServiceTestConfig());
}
/**
* Whether this test will succeed even if jobs remain unapplied indefinitely.
*
* NOTE: This may be called from the constructor, i.e., before the object is
* fully initialized.
*/
protected boolean isHrdSafe() {
return true;
}
protected static void trace(String what) {
if (traceBuffer.length() > 0) {
traceBuffer.append(' ');
}
traceBuffer.append(what);
}
protected static String trace() {
return traceBuffer.toString();
}
@Override
public void setUp() throws Exception {
super.setUp();
traceBuffer = new StringBuffer();
helper.setUp();
apiProxyEnvironment = ApiProxy.getCurrentEnvironment();
System.setProperty(USE_SIMPLE_GUIDS_FOR_DEBUGGING, "true");
taskQueue = LocalTaskQueueTestConfig.getLocalTaskQueue();
}
@Override
public void tearDown() throws Exception {
helper.tearDown();
super.tearDown();
}
protected void waitUntilTaskQueueIsEmpty() throws InterruptedException {
boolean hasMoreTasks = true;
while (hasMoreTasks) {
Map<String, QueueStateInfo> taskInfoMap = taskQueue.getQueueStateInfo();
hasMoreTasks = false;
for (QueueStateInfo taskQueueInfo : taskInfoMap.values()) {
if (taskQueueInfo.getCountTasks() > 0) {
hasMoreTasks = true;
break;
}
}
if (hasMoreTasks) {
Thread.sleep(100);
}
}
}
protected JobInfo waitUntilJobComplete(String pipelineId) throws Exception {
PipelineService service = PipelineServiceFactory.newPipelineService();
while (true) {
Thread.sleep(2000);
JobInfo jobInfo = service.getJobInfo(pipelineId);
switch (jobInfo.getJobState()) {
case RUNNING:
case WAITING_TO_RETRY:
break;
default:
return jobInfo;
}
}
}
@SuppressWarnings("unchecked")
protected <T> T waitForJobToComplete(String pipelineId) throws Exception {
JobInfo jobInfo = waitUntilJobComplete(pipelineId);
switch (jobInfo.getJobState()) {
case COMPLETED_SUCCESSFULLY:
return (T) jobInfo.getOutput();
case STOPPED_BY_ERROR:
throw new RuntimeException("Job stopped " + jobInfo.getError());
case STOPPED_BY_REQUEST:
throw new RuntimeException("Job stopped by request.");
case CANCELED_BY_REQUEST:
throw new RuntimeException("Job was canceled by request.");
default:
throw new RuntimeException("Unexpected job state: " + jobInfo.getJobState());
}
}
}