You are viewing a plain text version of this content. The canonical link for it is here.
Posted to common-commits@hadoop.apache.org by st...@apache.org on 2009/05/27 13:02:13 UTC

svn commit: r779107 - in /hadoop/core/branches/HADOOP-3628-2/src/test: core/org/apache/hadoop/io/TestThrowableWritable.java core/org/apache/hadoop/util/TestServiceLifecycle.java mapred/org/apache/hadoop/mapred/TestTaskTrackerLifecycle.java

Author: stevel
Date: Wed May 27 11:02:13 2009
New Revision: 779107

URL: http://svn.apache.org/viewvc?rev=779107&view=rev
Log:
HADOOP-3628 reinsert moved tests

Added:
    hadoop/core/branches/HADOOP-3628-2/src/test/core/org/apache/hadoop/io/TestThrowableWritable.java
    hadoop/core/branches/HADOOP-3628-2/src/test/core/org/apache/hadoop/util/TestServiceLifecycle.java
    hadoop/core/branches/HADOOP-3628-2/src/test/mapred/org/apache/hadoop/mapred/TestTaskTrackerLifecycle.java

Added: hadoop/core/branches/HADOOP-3628-2/src/test/core/org/apache/hadoop/io/TestThrowableWritable.java
URL: http://svn.apache.org/viewvc/hadoop/core/branches/HADOOP-3628-2/src/test/core/org/apache/hadoop/io/TestThrowableWritable.java?rev=779107&view=auto
==============================================================================
--- hadoop/core/branches/HADOOP-3628-2/src/test/core/org/apache/hadoop/io/TestThrowableWritable.java (added)
+++ hadoop/core/branches/HADOOP-3628-2/src/test/core/org/apache/hadoop/io/TestThrowableWritable.java Wed May 27 11:02:13 2009
@@ -0,0 +1,154 @@
+/**
+ * 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.io;
+
+import junit.framework.TestCase;
+
+import java.io.IOException;
+
+public class TestThrowableWritable extends TestCase {
+
+  private ThrowableWritable simple, messageOnly, chained, empty;
+  private static final String SIMPLE = "simple";
+  private static final String MESSAGE_ONLY = "messageOnly";
+  private static final String OUTER = "outer";
+  private static final String INNER = "inner";
+
+  public TestThrowableWritable() {
+  }
+
+  public TestThrowableWritable(String s) {
+    super(s);
+  }
+
+  /** {@inheritDoc} */
+  @Override
+  protected void setUp() throws Exception {
+    super.setUp();
+
+    simple = new ThrowableWritable(new Throwable(SIMPLE));
+    messageOnly = new ThrowableWritable(MESSAGE_ONLY);
+    empty = new ThrowableWritable();
+    chained = new ThrowableWritable(new Throwable(OUTER,
+        new IOException(INNER)));
+  }
+
+  private void assertEmptyStack(ThrowableWritable throwableWritable) {
+    assertEquals(0, throwableWritable.getStack().length);
+  }
+
+  private void assertCopyWorks(ThrowableWritable instance) throws CloneNotSupportedException {
+    Object cloned = instance.clone();
+    ThrowableWritable copy = new ThrowableWritable(instance);
+    assertEquals(cloned, copy);
+    assertEquals(instance, copy);
+    assertEquals(instance.hashCode(), copy.hashCode());
+    assertEquals(instance.getDepth(), copy.getDepth());
+  }
+
+  private void assertStackSetUp(ThrowableWritable instance) {
+    assertTrue(instance.getStack().length > 0);
+    String topEntry = instance.getStack()[0];
+    assertTrue("No stack in "+topEntry,
+        topEntry.contains("TestThrowableWritable"));
+  }
+
+  private void assertMessageEquals(String message, ThrowableWritable instance) {
+    assertEquals(message,instance.getMessage());
+  }
+
+  private void assertDepth(int depth, ThrowableWritable instance) {
+    assertEquals(depth, instance.getDepth());
+  }
+
+  private void assertClassnameContains(String classname, ThrowableWritable instance) {
+    assertNotNull(instance.getClassname());
+    assertContains(classname, instance.getClassname());
+  }
+
+  private void assertContains(String expected, String source) {
+    assertNotNull(source);
+    assertTrue("Did not find "+expected+ " in "+source,source.contains(expected));
+  }
+
+  private void close(java.io.Closeable c) throws IOException {
+    if(c!=null) {
+      c.close();
+    }
+  }
+
+  private void assertRoundTrips(ThrowableWritable source) throws IOException {
+    DataOutputBuffer out = null;
+    DataInputBuffer in = null;
+    ThrowableWritable dest;
+    try {
+      out = new DataOutputBuffer();
+      in = new DataInputBuffer();
+      out.reset();
+      source.write(out);
+      in.reset(out.getData(), out.getLength());
+      dest = new ThrowableWritable();
+      dest.readFields(in);
+    } finally {
+      close(in);
+      close(out);
+    }
+    assertEquals(source, dest);
+  }
+
+  public void testEmptyInstance() throws Throwable {
+    assertNotNull(empty.toString());
+    assertNull(empty.getClassname());
+    assertEquals(empty, empty);
+    assertNull(empty.getMessage());
+    assertCopyWorks(empty);
+    assertDepth(1, empty);
+  }
+
+  public void testSimple() throws Throwable {
+    assertMessageEquals(SIMPLE, simple);
+    assertClassnameContains("Throwable", simple);
+    assertStackSetUp(simple);
+    assertDepth(1, simple);
+    assertCopyWorks(simple);
+    assertRoundTrips(simple);
+  }
+
+  public void testMessageOnly() throws Throwable {
+    assertMessageEquals(MESSAGE_ONLY, messageOnly);
+    assertEmptyStack(messageOnly);
+    assertDepth(1, messageOnly);
+    assertCopyWorks(messageOnly);
+    assertRoundTrips(messageOnly);
+  }
+
+  public void testChained() throws Throwable {
+    assertContains(OUTER, chained.toString());
+    assertClassnameContains("Throwable", chained);
+    assertStackSetUp(chained);
+    assertDepth(2, chained);
+    assertCopyWorks(chained);
+    ThrowableWritable cause = chained.getCause();
+    assertContains(INNER, cause.toString());
+    assertClassnameContains("IOException", cause);
+    assertRoundTrips(chained);
+  }
+
+
+}

Added: hadoop/core/branches/HADOOP-3628-2/src/test/core/org/apache/hadoop/util/TestServiceLifecycle.java
URL: http://svn.apache.org/viewvc/hadoop/core/branches/HADOOP-3628-2/src/test/core/org/apache/hadoop/util/TestServiceLifecycle.java?rev=779107&view=auto
==============================================================================
--- hadoop/core/branches/HADOOP-3628-2/src/test/core/org/apache/hadoop/util/TestServiceLifecycle.java (added)
+++ hadoop/core/branches/HADOOP-3628-2/src/test/core/org/apache/hadoop/util/TestServiceLifecycle.java Wed May 27 11:02:13 2009
@@ -0,0 +1,350 @@
+/**
+ * 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.util;
+
+import junit.framework.TestCase;
+
+import java.io.IOException;
+import java.util.List;
+
+
+/**vc
+ * Test service transitions in a mock service
+ */
+
+public class TestServiceLifecycle extends TestCase {
+  private MockService service;
+
+  public TestServiceLifecycle(String name) {
+    super(name);
+  }
+
+  @Override
+  protected void setUp() throws Exception {
+    super.setUp();
+    service = new MockService();
+  }
+
+  @Override
+  protected void tearDown() throws Exception {
+    Service.close(service);
+    super.tearDown();
+  }
+
+  private void ping() throws IOException {
+    service.ping();
+  }
+
+  private void start() throws IOException {
+    service.start();
+  }
+
+  private void close() throws IOException {
+    service.close();
+    assertInTerminatedState();
+  }
+
+  protected void assertInState(Service.ServiceState state)
+          throws Service.ServiceStateException {
+    service.verifyServiceState(state);
+  }
+
+  private void assertInLiveState() throws Service.ServiceStateException {
+    assertInState(Service.ServiceState.LIVE);
+  }
+
+  private void assertInCreatedState() throws Service.ServiceStateException {
+    assertInState(Service.ServiceState.CREATED);
+  }
+
+  private void assertInFailedState() throws Service.ServiceStateException {
+    assertInState(Service.ServiceState.FAILED);
+  }
+
+  private void assertInTerminatedState() throws Service.ServiceStateException {
+    assertInState(Service.ServiceState.CLOSED);
+  }
+
+  private void assertRunning() {
+    assertTrue("Service is not running: " + service, service.isRunning());
+  }
+
+  private void assertNotRunning() {
+    assertFalse("Service is running: " + service, service.isRunning());
+  }
+
+  private void enterState(Service.ServiceState state)
+          throws Service.ServiceStateException {
+    service.changeState(state);
+    assertInState(state);
+  }
+
+
+  private void enterFailedState() throws Service.ServiceStateException {
+    enterState(Service.ServiceState.FAILED);
+  }
+
+  private void enterTerminatedState() throws Service.ServiceStateException {
+    enterState(Service.ServiceState.CLOSED);
+  }
+
+  private void assertStateChangeCount(int expected) {
+    assertEquals("Wrong state change count for " + service,
+            expected,
+            service.getStateChangeCount());
+  }
+
+  private void assertPingCount(int expected) {
+    assertEquals("Wrong pingchange count for " + service,
+            expected,
+            service.getPingCount());
+  }
+
+  private void assertNoStartFromState(Service.ServiceState serviceState)
+          throws IOException {
+    enterState(serviceState);
+    try {
+      service.start();
+      failShouldNotGetHere();
+    } catch (Service.ServiceStateException expected) {
+      //expected
+    }
+  }
+
+  private void failShouldNotGetHere() {
+    fail("expected failure, but service is in " + service.getServiceState());
+  }
+
+  /**
+   * Test that the ping operation returns a mock exception
+   * @return the service status
+   * @throws IOException IO problems
+   */
+  private Service.ServiceStatus assertPingContainsMockException()
+          throws IOException {
+    Service.ServiceStatus serviceStatus = service.ping();
+    List<Throwable> thrown = serviceStatus.getThrowables();
+    assertFalse("No nested exceptions in service status", thrown.isEmpty());
+    Throwable throwable = thrown.get(0);
+    assertTrue(
+            "Nested exception is not a MockServiceException : "+throwable,
+            throwable instanceof MockService.MockServiceException);
+    return serviceStatus;
+  }
+
+  /**
+   * Walk through the lifecycle and check it changes visible state
+   */
+  public void testBasicLifecycle() throws Throwable {
+    assertInCreatedState();
+    assertNotRunning();
+    assertNotRunning();
+    start();
+    assertInLiveState();
+    assertRunning();
+    ping();
+    ping();
+    assertPingCount(2);
+    close();
+    assertStateChangeCount(3);
+    assertNotRunning();
+  }
+
+  /**
+   * Assert that a state changing operation is idempotent
+   * @throws Throwable if something went wrong
+   */
+  public void testStartIdempotent() throws Throwable {
+    start();
+    int count = service.getStateChangeCount();
+    //declare that we want to fail in our start operation
+    service.setFailOnStart(true);
+    //then start. If the innerStart() method is called: failure
+    start();
+    //check that the state count has not changed either.
+    assertStateChangeCount(count);
+    assertInLiveState();
+  }
+
+  public void testTerminateIdempotent() throws Throwable {
+    close();
+    int count = service.getStateChangeCount();
+    close();
+    assertStateChangeCount(count);
+  }
+
+  public void testCloseFromCreated() throws Throwable {
+    close();
+  }
+
+  public void testStaticCloseHandlesNull() throws Throwable {
+    Service.close(null);
+  }
+
+
+  public void testStaticCloseOperation() throws Throwable {
+    Service.close(service);
+    assertInTerminatedState();
+    Service.close(service);
+  }
+
+  public void testFailInStart() throws Throwable {
+    service.setFailOnStart(true);
+    try {
+      start();
+      failShouldNotGetHere();
+    } catch (MockService.MockServiceException e) {
+      assertInFailedState();
+    }
+  }
+
+  public void testPingInFailedReturnsException() throws Throwable {
+    service.setFailOnStart(true);
+    try {
+      start();
+      failShouldNotGetHere();
+    } catch (MockService.MockServiceException e) {
+      assertInFailedState();
+      //and test that the ping works out
+      Service.ServiceStatus serviceStatus = assertPingContainsMockException();
+      assertEquals(Service.ServiceState.FAILED, serviceStatus.getState());
+    }
+  }
+
+  public void testTerminateFromFailure() throws Throwable {
+    enterFailedState();
+    //test that we can get from failed to terminated
+    close();
+  }
+
+  public void testFailInPing() throws Throwable {
+    service.setFailOnPing(true);
+    start();
+    Service.ServiceStatus serviceStatus = service.ping();
+    assertEquals(Service.ServiceState.FAILED, serviceStatus.getState());
+    assertPingCount(1);
+    List<Throwable> thrown = serviceStatus.getThrowables();
+    assertEquals(1, thrown.size());
+    Throwable throwable = thrown.get(0);
+    assertTrue(throwable instanceof MockService.MockServiceException);
+  }
+
+  public void testPingInCreated() throws Throwable {
+    service.setFailOnPing(true);
+    ping();
+    assertPingCount(0);
+  }
+
+
+  /**
+   * Test that when in a failed state, you can't ping the service
+   *
+   * @throws Throwable if needed
+   */
+  public void testPingInFailedStateIsNoop() throws Throwable {
+    enterFailedState();
+    assertInFailedState();
+    Service.ServiceStatus serviceStatus = service.ping();
+    assertEquals(Service.ServiceState.FAILED, serviceStatus.getState());
+    assertPingCount(0);
+  }
+
+  /**
+   * Test that when in a terminated state, you can't ping the service
+   *
+   * @throws Throwable if needed
+   */
+  public void testPingInTerminatedStateIsNoop() throws Throwable {
+    enterTerminatedState();
+    assertInTerminatedState();
+    Service.ServiceStatus serviceStatus = service.ping();
+    assertEquals(Service.ServiceState.CLOSED, serviceStatus.getState());
+    assertPingCount(0);
+  }
+
+  public void testDeploy() throws Throwable {
+    Service.startService(service);
+    assertInLiveState();
+  }
+
+  public void testDeployFailingStart() throws Throwable {
+    service.setFailOnStart(true);
+    try {
+      Service.startService(service);
+    } catch (MockService.MockServiceException e) {
+      assertInTerminatedState();
+    }
+  }
+
+  public void testNoStartFromTerminated() throws Throwable {
+    assertNoStartFromState(Service.ServiceState.CLOSED);
+  }
+
+  public void testNoStartFromFailed() throws Throwable {
+    assertNoStartFromState(Service.ServiceState.CLOSED);
+  }
+
+  public void testStartFromLiveIdempotent() throws Throwable {
+    enterState(Service.ServiceState.LIVE);
+    int count = service.getStateChangeCount();
+    start();
+    assertStateChangeCount(count);
+  }
+
+  public void testFailOnClose() throws Throwable {
+    service.setFailOnClose(true);
+    try {
+      service.close();
+      fail("Should have thrown an exception");
+    } catch (IOException e) {
+      assertInTerminatedState();
+      assertTrue(service.isClosed());
+    }
+    //the second call should be a no-op; no exceptions get thrown
+    service.close();
+  }
+
+  public void testFailIdempotent() throws Throwable {
+    Exception cause = new Exception("test");
+    service.enterFailedState(null);
+    int count = service.getStateChangeCount();
+    service.enterFailedState(cause);
+    assertStateChangeCount(count);
+    assertEquals(cause, service.getFailureCause());
+  }
+
+  public void testFailFromTerminatedDoesNotChangeState() throws Throwable {
+    Service.startService(service);
+    service.close();
+    assertInTerminatedState();
+    Exception cause = new Exception("test");
+    service.enterFailedState(cause);
+    assertInTerminatedState();
+    assertEquals(cause,service.getFailureCause());
+  }
+
+  public void testFailFromFailedDoesNotChangeCause() throws Throwable {
+    Exception cause = new Exception("test");
+    service.enterFailedState(cause);
+    assertInFailedState();
+    service.enterFailedState(new Exception("test2"));
+    assertInFailedState();
+    assertEquals(cause, service.getFailureCause());
+  }
+
+}

Added: hadoop/core/branches/HADOOP-3628-2/src/test/mapred/org/apache/hadoop/mapred/TestTaskTrackerLifecycle.java
URL: http://svn.apache.org/viewvc/hadoop/core/branches/HADOOP-3628-2/src/test/mapred/org/apache/hadoop/mapred/TestTaskTrackerLifecycle.java?rev=779107&view=auto
==============================================================================
--- hadoop/core/branches/HADOOP-3628-2/src/test/mapred/org/apache/hadoop/mapred/TestTaskTrackerLifecycle.java (added)
+++ hadoop/core/branches/HADOOP-3628-2/src/test/mapred/org/apache/hadoop/mapred/TestTaskTrackerLifecycle.java Wed May 27 11:02:13 2009
@@ -0,0 +1,114 @@
+/**
+ * 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.mapred;
+
+import junit.framework.TestCase;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.hadoop.fs.FileSystem;
+import org.apache.hadoop.util.Service;
+
+import java.io.File;
+import java.io.IOException;
+
+/**
+ * Test that the task tracker follows the service lifecycle
+ */
+
+public class TestTaskTrackerLifecycle extends TestCase {
+  private TaskTracker tracker;
+  private static final Log LOG = LogFactory.getLog(TestTaskTrackerLifecycle.class);
+
+  /**
+   * Tears down the fixture, for example, close a network connection. This method
+   * is called after a test is executed.
+   */
+  protected void tearDown() throws Exception {
+    super.tearDown();
+    Service.close(tracker);
+  }
+
+  /**
+   * Create a job conf suitable for testing
+   * @return a new job conf instance
+   */
+  private JobConf createJobConf() {
+    JobConf config = new JobConf();
+    String dataDir = System.getProperty("test.build.data");
+    File hdfsDir = new File(dataDir, "dfs");
+    config.set("dfs.name.dir", new File(hdfsDir, "name1").getPath());
+    FileSystem.setDefaultUri(config, "hdfs://localhost:0");
+    config.set("dfs.http.address", "hdfs://localhost:0");
+    config.set("mapred.job.tracker", "localhost:8012");
+    config.set("ipc.client.connect.max.retries", "1");
+    return config;
+  }
+
+  private void assertConnectionRefused(IOException e) throws Throwable {
+    if(!e.getMessage().contains("Connection refused")) {
+      LOG.error("Wrong exception",e);
+      throw e;
+    }
+  }
+
+  /**
+   * Test that if a tracker isn't started, we can still terminate it cleanly
+   * @throws Throwable on a failure
+   */
+  public void testTerminateUnstartedTracker() throws Throwable {
+    tracker = new TaskTracker(createJobConf(), false);
+    tracker.ping();
+    tracker.close();
+  }
+
+  public void testOrphanTrackerFailure() throws Throwable {
+    try {
+      tracker = new TaskTracker(createJobConf());
+      fail("Expected a failure");
+    } catch (IOException e) {
+      assertConnectionRefused(e);
+    }
+  }
+
+  public void testFailingTracker() throws Throwable {
+    tracker = new TaskTracker(createJobConf(), false);
+    try {
+      tracker.start();
+      fail("Expected a failure");
+    } catch (IOException e) {
+      assertConnectionRefused(e);
+      assertEquals(Service.ServiceState.FAILED, tracker.getServiceState());
+    }
+  }
+
+  public void testStartedTracker() throws Throwable {
+    tracker = new TaskTracker(createJobConf(), false);
+    try {
+      Service.startService(tracker);
+      fail("Expected a failure");
+    } catch (IOException e) {
+      assertConnectionRefused(e);
+      assertEquals(Service.ServiceState.CLOSED, tracker.getServiceState());
+    }
+    tracker.ping();
+    tracker.close();
+    tracker.ping();
+  }
+
+}