Package org.apache.hadoop.yarn.util

Source Code of org.apache.hadoop.yarn.util.TestCompositeService$ServiceManager

/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you 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.apache.hadoop.yarn.util;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.service.AbstractService;
import org.apache.hadoop.service.BreakableService;
import org.apache.hadoop.service.CompositeService;
import org.apache.hadoop.service.Service;
import org.apache.hadoop.service.ServiceStateException;
import org.apache.hadoop.service.Service.STATE;
import org.apache.hadoop.yarn.exceptions.YarnRuntimeException;
import org.junit.Before;
import org.junit.Test;

public class TestCompositeService {

  private static final int NUM_OF_SERVICES = 5;

  private static final int FAILED_SERVICE_SEQ_NUMBER = 2;

  private static final Log LOG  = LogFactory.getLog(TestCompositeService.class);

  /**
   * flag to state policy of CompositeService, and hence
   * what to look for after trying to stop a service from another state
   * (e.g inited)
   */
  private static final boolean STOP_ONLY_STARTED_SERVICES =
    CompositeServiceImpl.isPolicyToStopOnlyStartedServices();

  @Before
  public void setup() {
    CompositeServiceImpl.resetCounter();
  }

  @Test
  public void testCallSequence() {
    ServiceManager serviceManager = new ServiceManager("ServiceManager");

    // Add services
    for (int i = 0; i < NUM_OF_SERVICES; i++) {
      CompositeServiceImpl service = new CompositeServiceImpl(i);
      serviceManager.addTestService(service);
    }

    CompositeServiceImpl[] services = serviceManager.getServices().toArray(
        new CompositeServiceImpl[0]);

    assertEquals("Number of registered services ", NUM_OF_SERVICES,
        services.length);

    Configuration conf = new Configuration();
    // Initialise the composite service
    serviceManager.init(conf);

    //verify they were all inited
    assertInState(STATE.INITED, services);

    // Verify the init() call sequence numbers for every service
    for (int i = 0; i < NUM_OF_SERVICES; i++) {
      assertEquals("For " + services[i]
          + " service, init() call sequence number should have been ", i,
          services[i].getCallSequenceNumber());
    }

    // Reset the call sequence numbers
    resetServices(services);

    serviceManager.start();
    //verify they were all started
    assertInState(STATE.STARTED, services);

    // Verify the start() call sequence numbers for every service
    for (int i = 0; i < NUM_OF_SERVICES; i++) {
      assertEquals("For " + services[i]
          + " service, start() call sequence number should have been ", i,
          services[i].getCallSequenceNumber());
    }
    resetServices(services);


    serviceManager.stop();
    //verify they were all stopped
    assertInState(STATE.STOPPED, services);

    // Verify the stop() call sequence numbers for every service
    for (int i = 0; i < NUM_OF_SERVICES; i++) {
      assertEquals("For " + services[i]
          + " service, stop() call sequence number should have been ",
          ((NUM_OF_SERVICES - 1) - i), services[i].getCallSequenceNumber());
    }

    // Try to stop again. This should be a no-op.
    serviceManager.stop();
    // Verify that stop() call sequence numbers for every service don't change.
    for (int i = 0; i < NUM_OF_SERVICES; i++) {
      assertEquals("For " + services[i]
          + " service, stop() call sequence number should have been ",
          ((NUM_OF_SERVICES - 1) - i), services[i].getCallSequenceNumber());
    }
  }

  private void resetServices(CompositeServiceImpl[] services) {
    // Reset the call sequence numbers
    for (int i = 0; i < NUM_OF_SERVICES; i++) {
      services[i].reset();
    }
  }

  @Test
  public void testServiceStartup() {
    ServiceManager serviceManager = new ServiceManager("ServiceManager");

    // Add services
    for (int i = 0; i < NUM_OF_SERVICES; i++) {
      CompositeServiceImpl service = new CompositeServiceImpl(i);
      if (i == FAILED_SERVICE_SEQ_NUMBER) {
        service.setThrowExceptionOnStart(true);
      }
      serviceManager.addTestService(service);
    }

    CompositeServiceImpl[] services = serviceManager.getServices().toArray(
        new CompositeServiceImpl[0]);

    Configuration conf = new Configuration();

    // Initialise the composite service
    serviceManager.init(conf);

    // Start the composite service
    try {
      serviceManager.start();
      fail("Exception should have been thrown due to startup failure of last service");
    } catch (YarnRuntimeException e) {
      for (int i = 0; i < NUM_OF_SERVICES - 1; i++) {
        if (i >= FAILED_SERVICE_SEQ_NUMBER && STOP_ONLY_STARTED_SERVICES) {
          // Failed service state should be INITED
          assertEquals("Service state should have been ", STATE.INITED,
              services[NUM_OF_SERVICES - 1].getServiceState());
        } else {
          assertEquals("Service state should have been ", STATE.STOPPED,
              services[i].getServiceState());
        }
      }

    }
  }

  @Test
  public void testServiceStop() {
    ServiceManager serviceManager = new ServiceManager("ServiceManager");

    // Add services
    for (int i = 0; i < NUM_OF_SERVICES; i++) {
      CompositeServiceImpl service = new CompositeServiceImpl(i);
      if (i == FAILED_SERVICE_SEQ_NUMBER) {
        service.setThrowExceptionOnStop(true);
      }
      serviceManager.addTestService(service);
    }

    CompositeServiceImpl[] services = serviceManager.getServices().toArray(
        new CompositeServiceImpl[0]);

    Configuration conf = new Configuration();

    // Initialise the composite service
    serviceManager.init(conf);

    serviceManager.start();

    // Stop the composite service
    try {
      serviceManager.stop();
    } catch (YarnRuntimeException e) {
    }
    assertInState(STATE.STOPPED, services);
  }

  /**
   * Assert that all services are in the same expected state
   * @param expected expected state value
   * @param services services to examine
   */
  private void assertInState(STATE expected, CompositeServiceImpl[] services) {
    assertInState(expected, services,0, services.length);
  }

  /**
   * Assert that all services are in the same expected state
   * @param expected expected state value
   * @param services services to examine
   * @param start start offset
   * @param finish finish offset: the count stops before this number
   */
  private void assertInState(STATE expected,
                             CompositeServiceImpl[] services,
                             int start, int finish) {
    for (int i = start; i < finish; i++) {
      Service service = services[i];
      assertInState(expected, service);
    }
  }

  private void assertInState(STATE expected, Service service) {
    assertEquals("Service state should have been " + expected + " in "
                 + service,
                 expected,
                 service.getServiceState());
  }

  /**
   * Shut down from not-inited: expect nothing to have happened
   */
  @Test
  public void testServiceStopFromNotInited() {
    ServiceManager serviceManager = new ServiceManager("ServiceManager");

    // Add services
    for (int i = 0; i < NUM_OF_SERVICES; i++) {
      CompositeServiceImpl service = new CompositeServiceImpl(i);
      serviceManager.addTestService(service);
    }

    CompositeServiceImpl[] services = serviceManager.getServices().toArray(
      new CompositeServiceImpl[0]);
    serviceManager.stop();
    assertInState(STATE.NOTINITED, services);
  }

  /**
   * Shut down from inited
   */
  @Test
  public void testServiceStopFromInited() {
    ServiceManager serviceManager = new ServiceManager("ServiceManager");

    // Add services
    for (int i = 0; i < NUM_OF_SERVICES; i++) {
      CompositeServiceImpl service = new CompositeServiceImpl(i);
      serviceManager.addTestService(service);
    }

    CompositeServiceImpl[] services = serviceManager.getServices().toArray(
      new CompositeServiceImpl[0]);
    serviceManager.init(new Configuration());
    serviceManager.stop();
    if (STOP_ONLY_STARTED_SERVICES) {
      //this policy => no services were stopped
      assertInState(STATE.INITED, services);
    } else {
      assertInState(STATE.STOPPED, services);
    }
  }

  /**
   * Use a null configuration & expect a failure
   * @throws Throwable
   */
  @Test
  public void testInitNullConf() throws Throwable {
    ServiceManager serviceManager = new ServiceManager("testInitNullConf");

    CompositeServiceImpl service = new CompositeServiceImpl(0);
    serviceManager.addTestService(service);
    try {
      serviceManager.init(null);
      LOG.warn("Null Configurations are permitted " + serviceManager);
    } catch (ServiceStateException e) {
      //expected
    }
  }

  /**
   * Walk the service through their lifecycle without any children;
   * verify that it all works.
   */
  @Test
  public void testServiceLifecycleNoChildren() {
    ServiceManager serviceManager = new ServiceManager("ServiceManager");
    serviceManager.init(new Configuration());
    serviceManager.start();
    serviceManager.stop();
  }

  @Test
  public void testAddServiceInInit() throws Throwable {
    BreakableService child = new BreakableService();
    assertInState(STATE.NOTINITED, child);
    CompositeServiceAddingAChild composite =
      new CompositeServiceAddingAChild(child);
    composite.init(new Configuration());
    assertInState(STATE.INITED, child);
  }

  @Test (timeout = 1000)
  public void testAddIfService() {
    CompositeService testService = new CompositeService("TestService") {
      Service service;
      @Override
      public void serviceInit(Configuration conf) {
        Integer notAService = new Integer(0);
        assertFalse("Added an integer as a service",
            addIfService(notAService));

        service = new AbstractService("Service") {};
        assertTrue("Unable to add a service", addIfService(service));
      }
    };

    testService.init(new Configuration());
    assertEquals("Incorrect number of services",
        1, testService.getServices().size());
  }

  @Test
  public void testRemoveService() {
    CompositeService testService = new CompositeService("TestService") {
      @Override
      public void serviceInit(Configuration conf) {
        Integer notAService = new Integer(0);
        assertFalse("Added an integer as a service",
            addIfService(notAService));

        Service service1 = new AbstractService("Service1") {};
        addIfService(service1);

        Service service2 = new AbstractService("Service2") {};
        addIfService(service2);

        Service service3 = new AbstractService("Service3") {};
        addIfService(service3);

        removeService(service1);
      }
    };

    testService.init(new Configuration());
    assertEquals("Incorrect number of services",
        2, testService.getServices().size());
  }

  public static class CompositeServiceAddingAChild extends CompositeService{
    Service child;

    public CompositeServiceAddingAChild(Service child) {
      super("CompositeServiceAddingAChild");
      this.child = child;
    }

    @Override
    protected void serviceInit(Configuration conf) throws Exception {
      addService(child);
      super.serviceInit(conf);
    }
  }
 
  public static class CompositeServiceImpl extends CompositeService {

    public static boolean isPolicyToStopOnlyStartedServices() {
      return STOP_ONLY_STARTED_SERVICES;
    }

    private static int counter = -1;

    private int callSequenceNumber = -1;

    private boolean throwExceptionOnStart;

    private boolean throwExceptionOnStop;

    public CompositeServiceImpl(int sequenceNumber) {
      super(Integer.toString(sequenceNumber));
    }

    @Override
    protected void serviceInit(Configuration conf) throws Exception {
      counter++;
      callSequenceNumber = counter;
      super.serviceInit(conf);
    }

    @Override
    protected void serviceStart() throws Exception {
      if (throwExceptionOnStart) {
        throw new YarnRuntimeException("Fake service start exception");
      }
      counter++;
      callSequenceNumber = counter;
      super.serviceStart();
    }

    @Override
    protected void serviceStop() throws Exception {
      counter++;
      callSequenceNumber = counter;
      if (throwExceptionOnStop) {
        throw new YarnRuntimeException("Fake service stop exception");
      }
      super.serviceStop();
    }

    public static int getCounter() {
      return counter;
    }

    public int getCallSequenceNumber() {
      return callSequenceNumber;
    }

    public void reset() {
      callSequenceNumber = -1;
      counter = -1;
    }

    public static void resetCounter() {
      counter = -1;
    }

    public void setThrowExceptionOnStart(boolean throwExceptionOnStart) {
      this.throwExceptionOnStart = throwExceptionOnStart;
    }

    public void setThrowExceptionOnStop(boolean throwExceptionOnStop) {
      this.throwExceptionOnStop = throwExceptionOnStop;
    }

    @Override
    public String toString() {
      return "Service " + getName();
    }

  }

  public static class ServiceManager extends CompositeService {

    public void addTestService(CompositeService service) {
      addService(service);
    }

    public ServiceManager(String name) {
      super(name);
    }
  }

}
TOP

Related Classes of org.apache.hadoop.yarn.util.TestCompositeService$ServiceManager

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.