266 lines
9.3 KiB
Java
266 lines
9.3 KiB
Java
|
/*-
|
|||
|
* Copyright (C) 2002, 2017, Oracle and/or its affiliates. All rights reserved.
|
|||
|
*
|
|||
|
* This file was distributed by Oracle as part of a version of Oracle Berkeley
|
|||
|
* DB Java Edition made available at:
|
|||
|
*
|
|||
|
* http://www.oracle.com/technetwork/database/database-technologies/berkeleydb/downloads/index.html
|
|||
|
*
|
|||
|
* Please see the LICENSE file included in the top-level directory of the
|
|||
|
* appropriate version of Oracle Berkeley DB Java Edition for a copy of the
|
|||
|
* license and additional information.
|
|||
|
*/
|
|||
|
|
|||
|
package com.sleepycat.je.jmx;
|
|||
|
|
|||
|
import java.io.ByteArrayOutputStream;
|
|||
|
import java.io.File;
|
|||
|
import java.io.ObjectOutputStream;
|
|||
|
import java.io.Serializable;
|
|||
|
import java.util.Arrays;
|
|||
|
import java.util.List;
|
|||
|
import javax.management.DynamicMBean;
|
|||
|
import javax.management.MBeanAttributeInfo;
|
|||
|
import javax.management.MBeanConstructorInfo;
|
|||
|
import javax.management.MBeanInfo;
|
|||
|
import javax.management.MBeanNotificationInfo;
|
|||
|
import javax.management.MBeanOperationInfo;
|
|||
|
import javax.management.MBeanParameterInfo;
|
|||
|
|
|||
|
import com.sleepycat.je.Environment;
|
|||
|
import com.sleepycat.je.EnvironmentConfig;
|
|||
|
import com.sleepycat.je.dbi.DbEnvPool;
|
|||
|
import com.sleepycat.je.util.TestUtils;
|
|||
|
import junit.framework.TestCase;
|
|||
|
|
|||
|
/**
|
|||
|
* A utility class for testing JE MBeans.
|
|||
|
*/
|
|||
|
public class MBeanTestUtils extends TestCase {
|
|||
|
public static void validateGetters(DynamicMBean mbean,
|
|||
|
int numExpectedAttributes,
|
|||
|
boolean DEBUG)
|
|||
|
throws Throwable {
|
|||
|
|
|||
|
MBeanInfo info = mbean.getMBeanInfo();
|
|||
|
|
|||
|
MBeanAttributeInfo[] attrs = info.getAttributes();
|
|||
|
|
|||
|
/* test getters. */
|
|||
|
int attributesWithValues = 0;
|
|||
|
for (int i = 0; i < attrs.length; i++) {
|
|||
|
String name = attrs[i].getName();
|
|||
|
Object result = mbean.getAttribute(name);
|
|||
|
if (DEBUG) {
|
|||
|
System.out.println("Attribute " + i +
|
|||
|
" name=" + name +
|
|||
|
" result=" + result);
|
|||
|
}
|
|||
|
if (result != null) {
|
|||
|
attributesWithValues++;
|
|||
|
checkObjectType
|
|||
|
("Attribute", name, attrs[i].getType(), result);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
assertEquals(numExpectedAttributes, attributesWithValues);
|
|||
|
}
|
|||
|
|
|||
|
/*
|
|||
|
* Check that there are the expected number of operations.
|
|||
|
*/
|
|||
|
public static void checkOpNum(DynamicMBean mbean,
|
|||
|
int numExpectedOperations,
|
|||
|
boolean DEBUG)
|
|||
|
throws Throwable {
|
|||
|
|
|||
|
MBeanInfo info = mbean.getMBeanInfo();
|
|||
|
|
|||
|
MBeanOperationInfo[] ops = info.getOperations();
|
|||
|
if (DEBUG) {
|
|||
|
for (int i = 0; i < ops.length; i++) {
|
|||
|
System.out.println("op: " + ops[i].getName());
|
|||
|
}
|
|||
|
}
|
|||
|
assertEquals(numExpectedOperations, ops.length);
|
|||
|
}
|
|||
|
|
|||
|
/**
|
|||
|
* Checks that all types for the given mbean are serializable.
|
|||
|
*/
|
|||
|
public static void doTestSerializable(DynamicMBean mbean) {
|
|||
|
|
|||
|
MBeanInfo info = mbean.getMBeanInfo();
|
|||
|
|
|||
|
MBeanAttributeInfo[] attrs = info.getAttributes();
|
|||
|
for (int i = 0; i < attrs.length; i++) {
|
|||
|
checkSerializable
|
|||
|
("Attribute", attrs[i].getName(), attrs[i].getType());
|
|||
|
}
|
|||
|
|
|||
|
MBeanOperationInfo[] ops = info.getOperations();
|
|||
|
for (int i = 0; i < ops.length; i += 1) {
|
|||
|
checkSerializable
|
|||
|
("Operation",
|
|||
|
ops[i].getName() + " return type",
|
|||
|
ops[i].getReturnType());
|
|||
|
MBeanParameterInfo[] params = ops[i].getSignature();
|
|||
|
for (int j = 0; j < params.length; j += 1) {
|
|||
|
checkSerializable
|
|||
|
("Operation",
|
|||
|
ops[i].getName() + " parameter " + j,
|
|||
|
params[j].getType());
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
MBeanConstructorInfo[] ctors = info.getConstructors();
|
|||
|
for (int i = 0; i < ctors.length; i++) {
|
|||
|
MBeanParameterInfo[] params = ctors[i].getSignature();
|
|||
|
for (int j = 0; j < params.length; j += 1) {
|
|||
|
checkSerializable
|
|||
|
("Constructor",
|
|||
|
ctors[i].getName() + " parameter " + j,
|
|||
|
params[j].getType());
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
MBeanNotificationInfo[] notifs = info.getNotifications();
|
|||
|
for (int i = 0; i < notifs.length; i++) {
|
|||
|
String[] types = notifs[i].getNotifTypes();
|
|||
|
for (int j = 0; j < types.length; j += 1) {
|
|||
|
checkSerializable
|
|||
|
("Notification", notifs[i].getName(), types[j]);
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/**
|
|||
|
* Checks that a given type is serializable.
|
|||
|
*/
|
|||
|
private static void checkSerializable(String identifier,
|
|||
|
String name,
|
|||
|
String type) {
|
|||
|
|
|||
|
if ("void".equals(type)) {
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
String msg = identifier + ' ' + name + " is type " + type;
|
|||
|
try {
|
|||
|
Class cls = Class.forName(type);
|
|||
|
if (!Serializable.class.isAssignableFrom(cls)) {
|
|||
|
fail(msg + " -- not Serializable");
|
|||
|
}
|
|||
|
} catch (Exception e) {
|
|||
|
fail(msg + " -- " + e);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/**
|
|||
|
* Checks that an object (parameter or return value) is of the type
|
|||
|
* specified in the BeanInfo.
|
|||
|
*/
|
|||
|
public static void checkObjectType(String identifier,
|
|||
|
String name,
|
|||
|
String type,
|
|||
|
Object object) {
|
|||
|
String msg = identifier + ' ' + name + " is type " + type;
|
|||
|
if ("void".equals(type)) {
|
|||
|
assertNull(msg + "-- should be null", object);
|
|||
|
return;
|
|||
|
}
|
|||
|
try {
|
|||
|
Class cls = Class.forName(type);
|
|||
|
assertTrue
|
|||
|
(msg + " -- object class is " + object.getClass().getName(),
|
|||
|
cls.isAssignableFrom(object.getClass()));
|
|||
|
} catch (Exception e) {
|
|||
|
fail(msg + " -- " + e);
|
|||
|
}
|
|||
|
|
|||
|
/*
|
|||
|
* The true test of serializable is to serialize. This checks the a
|
|||
|
* elements of a list, for example.
|
|||
|
*/
|
|||
|
try {
|
|||
|
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
|||
|
ObjectOutputStream oos = new ObjectOutputStream(baos);
|
|||
|
oos.writeObject(object);
|
|||
|
} catch (Exception e) {
|
|||
|
fail(msg + " -- " + e);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
public static void checkForNoOpenHandles(String environmentDir) {
|
|||
|
assertFalse(DbEnvPool.getInstance().isOpen(new File(environmentDir)));
|
|||
|
}
|
|||
|
|
|||
|
public static Environment openTxnalEnv(boolean isTransactional,
|
|||
|
File envHome)
|
|||
|
throws Exception {
|
|||
|
|
|||
|
EnvironmentConfig envConfig = TestUtils.initEnvConfig();
|
|||
|
envConfig.setAllowCreate(true);
|
|||
|
envConfig.setTransactional(isTransactional);
|
|||
|
|
|||
|
return new Environment(envHome, envConfig);
|
|||
|
}
|
|||
|
|
|||
|
/*
|
|||
|
* Check that there are the expected number of operations. If specified,
|
|||
|
* invoke and check the operations of JEMonitor and JEApplicationMBean.
|
|||
|
*/
|
|||
|
public static void validateMBeanOperations(DynamicMBean mbean,
|
|||
|
int numExpectedOperations,
|
|||
|
boolean tryInvoke,
|
|||
|
String databaseName,
|
|||
|
String[] expectedDatabases,
|
|||
|
boolean DEBUG)
|
|||
|
throws Throwable {
|
|||
|
|
|||
|
checkOpNum(mbean, numExpectedOperations, DEBUG);
|
|||
|
|
|||
|
MBeanInfo info = mbean.getMBeanInfo();
|
|||
|
MBeanOperationInfo[] ops = info.getOperations();
|
|||
|
|
|||
|
if (tryInvoke) {
|
|||
|
for (int i = 0; i < ops.length; i++) {
|
|||
|
String opName = ops[i].getName();
|
|||
|
|
|||
|
/* Try the per-database operations if specified. */
|
|||
|
if ((databaseName != null) &&
|
|||
|
opName.equals(JEMBeanHelper.OP_DB_STAT)) {
|
|||
|
/* Invoke with the name of the database. */
|
|||
|
Object result = mbean.invoke
|
|||
|
(opName,
|
|||
|
new Object[] {null, null, databaseName},
|
|||
|
null);
|
|||
|
assertTrue(result instanceof String);
|
|||
|
checkObjectType
|
|||
|
("Operation", opName, ops[i].getReturnType(), result);
|
|||
|
}
|
|||
|
|
|||
|
if ((expectedDatabases != null) &&
|
|||
|
opName.equals(JEMBeanHelper.OP_DB_NAMES)) {
|
|||
|
Object result = mbean.invoke(opName, null, null);
|
|||
|
List names = (List) result;
|
|||
|
assertTrue(Arrays.equals(expectedDatabases,
|
|||
|
names.toArray()));
|
|||
|
checkObjectType
|
|||
|
("Operation", opName, ops[i].getReturnType(), result);
|
|||
|
}
|
|||
|
|
|||
|
/*
|
|||
|
* Also invoke all operations with null params, to sanity
|
|||
|
* check.
|
|||
|
*/
|
|||
|
Object result = mbean.invoke(opName, null, null);
|
|||
|
if (result != null) {
|
|||
|
checkObjectType
|
|||
|
("Operation", opName, ops[i].getReturnType(), result);
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|