001/*
002 * Licensed to the Apache Software Foundation (ASF) under one
003 * or more contributor license agreements.  See the NOTICE file
004 * distributed with this work for additional information
005 * regarding copyright ownership.  The ASF licenses this file
006 * to you under the Apache License, Version 2.0 (the
007 * "License"); you may not use this file except in compliance
008 * with the License.  You may obtain a copy of the License at
009 *
010 *     http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing, software
013 * distributed under the License is distributed on an "AS IS" BASIS,
014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015 * See the License for the specific language governing permissions and
016 * limitations under the License.
017 */
018package org.apache.hadoop.hbase;
019
020import java.util.ArrayList;
021import java.util.HashSet;
022import java.util.List;
023import java.util.Map;
024import java.util.Set;
025import org.apache.hadoop.hbase.ResourceChecker.Phase;
026import org.apache.hadoop.hbase.util.JVM;
027
028/**
029 * ResourceCheckers when running JUnit tests.
030 */
031public final class JUnitResourceCheckers {
032
033  private JUnitResourceCheckers() {
034  }
035
036  private static class ThreadResourceAnalyzer extends ResourceChecker.ResourceAnalyzer {
037    private Set<String> initialThreadNames = new HashSet<>();
038    private List<String> stringsToLog = null;
039
040    @Override
041    public int getVal(Phase phase) {
042      Map<Thread, StackTraceElement[]> stackTraces = Thread.getAllStackTraces();
043      if (phase == Phase.INITIAL) {
044        stringsToLog = null;
045        for (Thread t : stackTraces.keySet()) {
046          initialThreadNames.add(t.getName());
047        }
048      } else if (phase == Phase.END) {
049        if (stackTraces.size() > initialThreadNames.size()) {
050          stringsToLog = new ArrayList<>();
051          for (Thread t : stackTraces.keySet()) {
052            if (!initialThreadNames.contains(t.getName())) {
053              stringsToLog.add("\nPotentially hanging thread: " + t.getName() + "\n");
054              StackTraceElement[] stackElements = stackTraces.get(t);
055              for (StackTraceElement ele : stackElements) {
056                stringsToLog.add("\t" + ele + "\n");
057              }
058            }
059          }
060        }
061      }
062      return stackTraces.size();
063    }
064
065    @Override
066    public int getMax() {
067      return 500;
068    }
069
070    @Override
071    public List<String> getStringsToLog() {
072      return stringsToLog;
073    }
074  }
075
076  private static class OpenFileDescriptorResourceAnalyzer extends ResourceChecker.ResourceAnalyzer {
077    @Override
078    public int getVal(Phase phase) {
079      if (!JVM.isUnix()) {
080        return 0;
081      }
082      JVM jvm = new JVM();
083      return (int) jvm.getOpenFileDescriptorCount();
084    }
085
086    @Override
087    public int getMax() {
088      return 1024;
089    }
090  }
091
092  private static class MaxFileDescriptorResourceAnalyzer extends ResourceChecker.ResourceAnalyzer {
093    @Override
094    public int getVal(Phase phase) {
095      if (!JVM.isUnix()) {
096        return 0;
097      }
098      JVM jvm = new JVM();
099      return (int) jvm.getMaxFileDescriptorCount();
100    }
101  }
102
103  private static class SystemLoadAverageResourceAnalyzer extends ResourceChecker.ResourceAnalyzer {
104    @Override
105    public int getVal(Phase phase) {
106      if (!JVM.isUnix()) {
107        return 0;
108      }
109      return (int) (new JVM().getSystemLoadAverage() * 100);
110    }
111  }
112
113  private static class ProcessCountResourceAnalyzer extends ResourceChecker.ResourceAnalyzer {
114    @Override
115    public int getVal(Phase phase) {
116      if (!JVM.isUnix()) {
117        return 0;
118      }
119      return new JVM().getNumberOfRunningProcess();
120    }
121  }
122
123  private static class AvailableMemoryMBResourceAnalyzer extends ResourceChecker.ResourceAnalyzer {
124    @Override
125    public int getVal(Phase phase) {
126      if (!JVM.isUnix()) {
127        return 0;
128      }
129      return (int) (new JVM().getFreeMemory() / (1024L * 1024L));
130    }
131  }
132
133  public static void addResourceAnalyzer(ResourceChecker rc) {
134    rc.addResourceAnalyzer(new ThreadResourceAnalyzer());
135    rc.addResourceAnalyzer(new OpenFileDescriptorResourceAnalyzer());
136    rc.addResourceAnalyzer(new MaxFileDescriptorResourceAnalyzer());
137    rc.addResourceAnalyzer(new SystemLoadAverageResourceAnalyzer());
138    rc.addResourceAnalyzer(new ProcessCountResourceAnalyzer());
139    rc.addResourceAnalyzer(new AvailableMemoryMBResourceAnalyzer());
140  }
141}