org.mitre.mpf.mst.TestStreamingJobStartStop.java Source code

Java tutorial

Introduction

Here is the source code for org.mitre.mpf.mst.TestStreamingJobStartStop.java

Source

/******************************************************************************
 * NOTICE                                                                     *
 *                                                                            *
 * This software (or technical data) was produced for the U.S. Government     *
 * under contract, and is subject to the Rights in Data-General Clause        *
 * 52.227-14, Alt. IV (DEC 2007).                                             *
 *                                                                            *
 * Copyright 2018 The MITRE Corporation. All Rights Reserved.                 *
 ******************************************************************************/

/******************************************************************************
 * Copyright 2018 The MITRE Corporation                                       *
 *                                                                            *
 * 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 org.mitre.mpf.mst;

import org.apache.commons.lang3.tuple.Pair;
import org.jgroups.Address;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mitre.mpf.interop.JsonSegmentSummaryReport;
import org.mitre.mpf.nms.AddressParser;
import org.mitre.mpf.nms.MasterNode;
import org.mitre.mpf.nms.NodeTypes;
import org.mitre.mpf.wfm.businessrules.StreamingJobRequestBo;
import org.mitre.mpf.wfm.data.entities.persistent.StreamingJobStatus;
import org.mitre.mpf.wfm.data.entities.transients.*;
import org.mitre.mpf.wfm.enums.ActionType;
import org.mitre.mpf.wfm.enums.StreamingJobStatusType;
import org.mitre.mpf.wfm.service.StreamingJobMessageSender;
import org.mockito.ArgumentCaptor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import java.net.URL;
import java.util.Collection;
import java.util.List;
import java.util.Map;

import static java.util.stream.Collectors.*;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.mockito.AdditionalMatchers.*;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.*;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(initializers = TestSystemWithDefaultConfig.AppCtxInit.class)
@ActiveProfiles("jenkins")
@DirtiesContext // Make sure TestStreamingJobStartStop does not use same application context as other tests.
public class TestStreamingJobStartStop {

    private static final Logger LOG = LoggerFactory.getLogger(TestStreamingJobStartStop.class);

    private static final StreamingJobRequestBo _mockStreamingJobRequestBo = mock(StreamingJobRequestBo.class);

    @Configuration
    public static class TestConfig {

        @Bean
        @Primary
        public StreamingJobRequestBo streamingJobRequestBo() {
            return _mockStreamingJobRequestBo;
        }
    }

    @Autowired
    private StreamingJobMessageSender _jobSender;

    @Autowired
    private MasterNode _masterNode;

    @Test(timeout = 5 * 60_000)
    public void testJobStartStop() throws InterruptedException {
        long jobId = 43231;
        long test_start_time = System.currentTimeMillis();

        waitForCorrectNodes();

        TransientStage stage1 = new TransientStage("stage1", "description", ActionType.DETECTION);
        stage1.getActions().add(new TransientAction("Action1", "description", "SUBSENSE"));

        TransientPipeline pipeline = new TransientPipeline("SUBSENSE MOTION DETECTION (WITH TRACKING) PIPELINE",
                "desc");
        pipeline.getStages().add(stage1);

        URL videoUrl = getClass().getResource("/samples/face/new_face_video.avi");
        TransientStream stream = new TransientStream(124, videoUrl.toString());
        stream.setSegmentSize(10);
        TransientStreamingJob streamingJob = new TransientStreamingJob(jobId, "ext id", pipeline, 1, 1, false,
                "mydir", false);
        streamingJob.setStream(stream);

        _jobSender.launchJob(streamingJob);

        verify(_mockStreamingJobRequestBo, timeout(30_000).atLeastOnce()).handleNewActivityAlert(eq(jobId), geq(0L),
                gt(test_start_time));

        _jobSender.stopJob(jobId);

        verify(_mockStreamingJobRequestBo, timeout(30_000)).handleJobStatusChange(eq(jobId),
                or(eq(new StreamingJobStatus(StreamingJobStatusType.TERMINATED)),
                        eq(new StreamingJobStatus(StreamingJobStatusType.CANCELLED))),
                gt(test_start_time));

        ArgumentCaptor<JsonSegmentSummaryReport> reportCaptor = ArgumentCaptor
                .forClass(JsonSegmentSummaryReport.class);

        verify(_mockStreamingJobRequestBo, timeout(30_000).atLeastOnce())
                .handleNewSummaryReport(reportCaptor.capture());

        JsonSegmentSummaryReport summaryReport = reportCaptor.getValue();
        assertEquals(jobId, summaryReport.getJobId());

        boolean hasNonEmptyDetection = summaryReport.getTypes().values().stream().flatMap(Collection::stream)
                .flatMap(t -> t.getDetections().stream()).anyMatch(d -> d.getHeight() > 0 && d.getWidth() > 0);
        assertTrue(hasNonEmptyDetection);
    }

    private void waitForCorrectNodes() throws InterruptedException {
        while (!hasCorrectNodes()) {
            Thread.sleep(1000);
        }
    }

    // Sometimes when the test starts there are 2 master nodes.
    // This makes sure there is only one master node and only one child node.
    private boolean hasCorrectNodes() {
        List<Address> currentNodes = _masterNode.getCurrentNodeManagerHosts();
        Map<NodeTypes, Long> nodeTypeCounts = currentNodes.stream().map(AddressParser::parse)
                .collect(groupingBy(Pair::getRight, counting()));

        long masterNodeCount = nodeTypeCounts.getOrDefault(NodeTypes.MasterNode, 0L);
        long childNodeCount = nodeTypeCounts.getOrDefault(NodeTypes.NodeManager, 0L);
        if (masterNodeCount == 1 && childNodeCount == 1) {
            return true;
        }

        String currentNodeList = currentNodes.stream().map(Object::toString).collect(joining("\n"));

        LOG.warn("Current Nodes:\n{}", currentNodeList);

        if (masterNodeCount != 1) {
            LOG.warn("Incorrect number of master nodes. Expected 1 but there were {}.", masterNodeCount);
        }
        if (childNodeCount != 1) {
            LOG.warn("Incorrect number of child nodes. Expected 1 but there were {}.", childNodeCount);
        }
        return false;
    }
}