co.cask.cdap.internal.app.services.ProgramLifecycleServiceTest.java Source code

Java tutorial

Introduction

Here is the source code for co.cask.cdap.internal.app.services.ProgramLifecycleServiceTest.java

Source

/*
 * Copyright  2015 Cask Data, 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 co.cask.cdap.internal.app.services;

import co.cask.cdap.WordCountApp;
import co.cask.cdap.app.runtime.ProgramController;
import co.cask.cdap.app.runtime.ProgramRuntimeService;
import co.cask.cdap.app.runtime.ProgramRuntimeService.RuntimeInfo;
import co.cask.cdap.app.store.Store;
import co.cask.cdap.common.app.RunIds;
import co.cask.cdap.common.conf.Constants;
import co.cask.cdap.common.utils.Tasks;
import co.cask.cdap.internal.app.services.http.AppFabricTestBase;
import co.cask.cdap.internal.app.store.DefaultStore;
import co.cask.cdap.internal.app.store.RunRecordMeta;
import co.cask.cdap.proto.Id;
import co.cask.cdap.proto.ProgramRunStatus;
import co.cask.cdap.proto.ProgramType;
import co.cask.cdap.proto.RunRecord;
import com.google.common.collect.Sets;
import org.apache.http.HttpResponse;
import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.Test;

import java.util.List;
import java.util.Set;
import java.util.concurrent.Callable;
import java.util.concurrent.TimeUnit;

/**
 * Unit test for {@link ProgramLifecycleService}
 */
public class ProgramLifecycleServiceTest extends AppFabricTestBase {

    private static ProgramLifecycleService programLifecycleService;
    private static Store store;
    private static ProgramRuntimeService runtimeService;

    @BeforeClass
    public static void setup() throws Exception {
        programLifecycleService = getInjector().getInstance(ProgramLifecycleService.class);
        store = getInjector().getInstance(DefaultStore.class);
        runtimeService = getInjector().getInstance(ProgramRuntimeService.class);
    }

    @Test
    public void testInvalidFlowRunRecord() throws Exception {
        // Create App with Flow and the deploy
        HttpResponse response = deploy(WordCountApp.class, Constants.Gateway.API_VERSION_3_TOKEN, TEST_NAMESPACE1);
        Assert.assertEquals(200, response.getStatusLine().getStatusCode());

        final Id.Program wordcountFlow1 = Id.Program.from(TEST_NAMESPACE1, "WordCountApp", ProgramType.FLOW,
                "WordCountFlow");

        // flow is stopped initially
        Assert.assertEquals("STOPPED", getProgramStatus(wordcountFlow1));

        // start a flow and check the status
        startProgram(wordcountFlow1);
        waitState(wordcountFlow1, ProgramRunStatus.RUNNING.toString());

        // Wait until we have a run record
        Tasks.waitFor(1, new Callable<Integer>() {
            @Override
            public Integer call() throws Exception {
                return getProgramRuns(wordcountFlow1, ProgramRunStatus.RUNNING.toString()).size();
            }
        }, 5, TimeUnit.SECONDS);

        // Get the RunRecord
        List<RunRecord> runRecords = getProgramRuns(wordcountFlow1, ProgramRunStatus.RUNNING.toString());
        Assert.assertEquals(1, runRecords.size());
        RunRecord rr = runRecords.get(0);

        // Check the RunRecords status
        Assert.assertEquals(ProgramRunStatus.RUNNING, rr.getStatus());

        // Lets set the runtime info to off
        RuntimeInfo runtimeInfo = runtimeService.lookup(wordcountFlow1, RunIds.fromString(rr.getPid()));
        ProgramController programController = runtimeInfo.getController();
        programController.stop();

        Thread.sleep(2000);

        // Verify that the status of that run is KILLED
        RunRecordMeta runRecordMeta = store.getRun(wordcountFlow1, rr.getPid());
        Assert.assertEquals(ProgramRunStatus.KILLED, runRecordMeta.getStatus());

        // Use the store manipulate state to be RUNNING
        long now = System.currentTimeMillis();
        long nowSecs = TimeUnit.MILLISECONDS.toSeconds(now);
        store.setStart(wordcountFlow1, rr.getPid(), nowSecs);

        // Now check again via Store to assume data store is wrong.
        runRecordMeta = store.getRun(wordcountFlow1, rr.getPid());
        Assert.assertEquals(ProgramRunStatus.RUNNING, runRecordMeta.getStatus());

        // Verify there is NO FAILED run record for the application
        runRecords = getProgramRuns(wordcountFlow1, ProgramRunStatus.FAILED.toString());
        Assert.assertEquals(0, runRecords.size());

        // Lets fix it
        Set<String> processedInvalidRunRecordIds = Sets.newHashSet();
        programLifecycleService.validateAndCorrectRunningRunRecords(ProgramType.FLOW, processedInvalidRunRecordIds);

        // Verify there is one FAILED run record for the application
        runRecords = getProgramRuns(wordcountFlow1, ProgramRunStatus.FAILED.toString());
        Assert.assertEquals(1, runRecords.size());
        rr = runRecords.get(0);
        Assert.assertEquals(ProgramRunStatus.FAILED, rr.getStatus());
    }
}