/*
|
* CDDL HEADER START
|
*
|
* The contents of this file are subject to the terms of the
|
* Common Development and Distribution License, Version 1.0 only
|
* (the "License"). You may not use this file except in compliance
|
* with the License.
|
*
|
* You can obtain a copy of the license at
|
* trunk/opends/resource/legal-notices/OpenDS.LICENSE
|
* or https://OpenDS.dev.java.net/OpenDS.LICENSE.
|
* See the License for the specific language governing permissions
|
* and limitations under the License.
|
*
|
* When distributing Covered Code, include this CDDL HEADER in each
|
* file and include the License file at
|
* trunk/opends/resource/legal-notices/OpenDS.LICENSE. If applicable,
|
* add the following below this CDDL HEADER, with the fields enclosed
|
* by brackets "[]" replaced with your own identifying information:
|
* Portions Copyright [yyyy] [name of copyright owner]
|
*
|
* CDDL HEADER END
|
*
|
*
|
* Portions Copyright 2009 Sun Microsystems, Inc.
|
*/
|
package com.ibm.staf.service.opends;
|
|
import com.ibm.staf.*;
|
import com.ibm.staf.wrapper.*;
|
import com.ibm.staf.service.*;
|
import com.ibm.staf.service.opends.tester.*;
|
import java.util.StringTokenizer;
|
import java.io.*;
|
import java.util.ArrayList;
|
|
/**
|
* DSML Staf service
|
* it allows :
|
* - to test one or multiple DSEE DSML suite testcases (TODO)
|
* - compare testcase result against expected result
|
*/
|
public class DSMLService implements STAFServiceInterfaceLevel30 {
|
|
private static final String OP_COMPARE = "COMPARE";
|
private static final String OP_HELP = "HELP";
|
private static final String OP_FILE = "FILE";
|
private static final String OP_EXP_FILE = "EXP_FILE";
|
private static final String OP_ISSUE_FILE = "ISSUE_FILE";
|
private static final String OP_DIR = "DIR";
|
private static final String OP_EXP_DIR = "EXP_DIR";
|
private final String MATCH = " matches ";
|
private final String DIFFER = " differs from ";
|
private String fServiceName;
|
private STAFHandle fHandle;
|
private String fLocalMachineName = "";
|
private STAFLog logger = null;
|
|
// Define any error codes unique to this service
|
private static final int kDSMLInvalidSomething = 4001;
|
|
// STAFCommandParsers for each request
|
private STAFCommandParser fCompareParser;
|
private String fLineSep;
|
|
public STAFResult init(STAFServiceInterfaceLevel30.InitInfo info) {
|
try {
|
fServiceName = info.name;
|
fHandle = new STAFHandle("STAF/Service/" + info.name);
|
logger = new STAFLog(STAFLog.HANDLE, "dsmlLog", fHandle,
|
STAFLog.Fatal | STAFLog.Error | STAFLog.Warning);
|
} catch (STAFException e) {
|
return new STAFResult(STAFResult.STAFRegistrationError,
|
e.toString());
|
}
|
|
// COMPARE parser
|
fCompareParser = new STAFCommandParser(0, false);
|
fCompareParser.addOption(OP_COMPARE, 1, STAFCommandParser.VALUENOTALLOWED);
|
fCompareParser.addOption(OP_FILE, 1, STAFCommandParser.VALUEREQUIRED);
|
//fCompareParser.addOption(OP_F_SHORTCUT, 0, STAFCommandParser.VALUEREQUIRED);
|
fCompareParser.addOption(OP_DIR, 1, STAFCommandParser.VALUEREQUIRED);
|
fCompareParser.addOption(OP_EXP_FILE, 1, STAFCommandParser.VALUEREQUIRED);
|
fCompareParser.addOption(OP_EXP_DIR, 1, STAFCommandParser.VALUEREQUIRED);
|
//fCompareParser.addOption(OP_DIR_SHORT, 0, STAFCommandParser.VALUEREQUIRED);
|
//fCompareParser.addOption(OP_D_SHORTCUT, 0, STAFCommandParser.VALUEREQUIRED);
|
// either we compare directory or file
|
//fCompareParser.addOptionGroup(OP_FILE_GROUP, 1, 3);
|
//fCompareParser.addOptionGroup(OP_DIR_GROUP, 1, 3);
|
//TODO.1 not needed per dependency below
|
//TODO.1 fCompareParser.addOptionGroup(OP_EXPECTED_GROUP, 0, 1);
|
//TODO.1 fCompareParser.addOptionNeed(OP_EXPECTED_RESULT_FILE, OP_RESULT_FILE);
|
//TODO.1 fCompareParser.addOptionNeed(OP_EXPECTED_RESULT_DIR, OP_RESULT_DIR);
|
|
// if you specify COMPARE, RESULT_FILE is required
|
fCompareParser.addOptionNeed(OP_FILE, OP_EXP_FILE);
|
fCompareParser.addOptionNeed(OP_EXP_FILE, OP_FILE);
|
fCompareParser.addOptionNeed(OP_DIR, OP_EXP_DIR);
|
fCompareParser.addOptionNeed(OP_EXP_DIR, OP_DIR);
|
fCompareParser.addOptionNeed(OP_COMPARE, OP_FILE + " " + OP_DIR);
|
fCompareParser.addOptionNeed(OP_FILE + " " + OP_DIR, OP_COMPARE);
|
|
STAFResult res = new STAFResult();
|
|
// Resolve the line separator variable for the local machine
|
res = STAFUtil.resolveInitVar("{STAF/Config/Sep/Line}", fHandle);
|
|
if (res.rc != STAFResult.Ok) {
|
return res;
|
}
|
|
fLineSep = res.result;
|
|
// Resolve the machine name variable for the local machine
|
res = STAFUtil.resolveInitVar("{STAF/Config/Machine}", fHandle);
|
|
if (res.rc != STAFResult.Ok) {
|
return res;
|
}
|
|
fLocalMachineName = res.result;
|
|
// Register Help Data
|
registerHelpData(
|
kDSMLInvalidSomething+1,
|
"Invalid input",
|
"missing or wrong input files for results or expected results");
|
|
return new STAFResult(STAFResult.Ok);
|
}
|
|
public STAFResult acceptRequest(STAFServiceInterfaceLevel30.RequestInfo info) {
|
// dumping the RequestInfo
|
//TODO
|
|
//delegate the request handling
|
StringTokenizer requestTokenizer = new StringTokenizer(info.request);
|
String request = requestTokenizer.nextToken().toLowerCase();
|
|
// call the appropriate method to handle the command
|
if (request.equalsIgnoreCase(OP_COMPARE)) {
|
return handleCompare(info);
|
} else if (request.equalsIgnoreCase(OP_HELP)) {
|
return handleHelp(info);
|
} else {
|
return handleInvalidRequest(info);
|
}
|
}
|
|
public STAFResult term() {
|
logger.log(STAFLog.Warning, "termination initiated");
|
try {
|
// Un-register Help Data
|
|
unregisterHelpData(kDSMLInvalidSomething+2);
|
|
// Un-register the service handle
|
|
fHandle.unRegister();
|
} catch (STAFException ex) {
|
return new STAFResult(STAFResult.STAFRegistrationError,
|
ex.toString());
|
}
|
|
return new STAFResult(STAFResult.Ok);
|
}
|
|
private STAFResult handleCompare(STAFServiceInterfaceLevel30.RequestInfo info) {
|
STAFResult sr = new STAFResult(0);
|
|
//parse the input request
|
STAFCommandParseResult parsedRequest = fCompareParser.parse(info.request);
|
if (parsedRequest.rc != STAFResult.Ok) {
|
return new STAFResult(STAFResult.InvalidRequestString,
|
parsedRequest.errorBuffer);
|
}
|
|
// Resolve any STAF variables in the DIR option's value
|
STAFResult res = new STAFResult();
|
|
String file = parsedRequest.optionValue(OP_FILE);
|
String exp_file = parsedRequest.optionValue(OP_EXP_FILE);
|
String dir = parsedRequest.optionValue(OP_DIR);
|
String exp_dir = parsedRequest.optionValue(OP_EXP_DIR);
|
|
if (dir != null && dir.trim().length() > 0) {
|
sr = handleCompareDir(exp_dir, dir);
|
}
|
|
if (file != null && file.trim().length() > 0) {
|
sr = handleCompareFile(exp_file, file);
|
}
|
|
|
return sr;
|
}
|
|
/*
|
* It's expected that the result and expected result file have the same
|
* file path up to the file extension.
|
* expected result having extension ".res"
|
* result to be compared to expected result ".run"
|
* The filePath should exclude the file extension
|
* for ex a file like /tmp/add000.res the filePath expected is /tmp/add000
|
*/
|
private STAFResult handleCompareFile(String exp_file, String file) {
|
STAFResult sr = new STAFResult(STAFResult.Ok);
|
logger.log(STAFLog.Warning,
|
"handle File compare for exp_file=[" + exp_file + "], file=[" + file + "]");
|
if (!(exp_file.endsWith(DSMLFileFilter.EXPECTED_FILE_EXTENSION) || exp_file.endsWith(DSMLFileFilter.ISSUE_FILE_EXTENSION))){
|
sr.rc = STAFResult.FileReadError;
|
sr.result = "invalid input " + exp_file + " should end with " +
|
DSMLFileFilter.EXPECTED_FILE_EXTENSION + " or " +
|
DSMLFileFilter.ISSUE_FILE_EXTENSION;
|
} else if (!file.endsWith(DSMLFileFilter.RUN_FILE_EXTENSION)) {
|
sr.rc = STAFResult.FileReadError;
|
sr.result = "invalid input " + file + " should end with " + DSMLFileFilter.RUN_FILE_EXTENSION;
|
} else {
|
File expectedFile, resultFile;
|
// read the result and expected content files, and compare theme
|
try {
|
expectedFile = new File(exp_file);
|
resultFile = new File(file);
|
String line;
|
//reading result into ArrayList of POST results
|
BufferedReader resultBuffReader = new BufferedReader(new FileReader(resultFile));
|
ArrayList rl = new ArrayList();
|
StringBuffer resultContent = new StringBuffer();
|
int ln = 0;
|
while ((line = resultBuffReader.readLine()) != null) {
|
if (line.startsWith("HTTP") && ln > 0) {
|
rl.add(resultContent);
|
resultContent = new StringBuffer(line + "\n");
|
} else {
|
resultContent.append(line + "\n");
|
}
|
ln++;
|
}
|
rl.add(resultContent.toString());
|
resultBuffReader.close();
|
//reading expected result of POST results
|
BufferedReader expectedBufferReader = new BufferedReader(new FileReader(expectedFile));
|
ArrayList erl = new ArrayList();
|
StringBuffer expectedContent = new StringBuffer();
|
ln = 0;
|
while ((line = expectedBufferReader.readLine()) != null) {
|
if (line.startsWith("HTTP") && ln > 0) {
|
erl.add(expectedContent);
|
expectedContent = new StringBuffer(line + "\n");
|
} else {
|
expectedContent.append(line + "\n");
|
}
|
ln++;
|
}
|
erl.add(expectedContent.toString());
|
expectedBufferReader.close();
|
if (rl.size() != erl.size()) {
|
sr.rc = kDSMLInvalidSomething+3;//TODO
|
sr.result = "number of results " +
|
resultFile + "[" + rl.size() + "]" +
|
expectedFile + "[" + erl.size() + "]";
|
} else {
|
boolean identical = true;
|
for (int i = 0; i < rl.size(); i++) {
|
//starting from 1, because the first is always empty
|
/*PIERRE choose this one or below
|
identical &= compareResults("HTTP" + erl.get(i),
|
"HTTP" + rl.get(i));
|
* */
|
identical &= compareResults((String) erl.get(i), (String) rl.get(i));
|
logger.log(STAFLog.Warning, "comparing\n"+(String)erl.get(i)+"\nwith\n"+ (String)rl.get(i));
|
if (identical) {
|
// success
|
sr.rc = STAFResult.Ok;
|
sr.result = resultFile + MATCH + expectedFile;
|
} else {
|
logger.log(STAFLog.Error, "exp_file=[" + exp_file + "] "+
|
"differ from file=[" + file + "]");
|
|
sr.rc = kDSMLInvalidSomething+4;
|
sr.result = resultFile + DIFFER + expectedFile;
|
break;
|
}
|
}
|
}
|
} catch (FileNotFoundException fnfe) {
|
sr.rc = kDSMLInvalidSomething+5;//TODO
|
sr.result = fnfe.getMessage();
|
} catch (IOException ioe) {
|
sr.rc = kDSMLInvalidSomething+6;//TODO
|
sr.result = ioe.getMessage();
|
} catch (Exception e) {
|
sr.rc = kDSMLInvalidSomething+7;//TODO
|
sr.result = e.getMessage();
|
}
|
}
|
return sr;
|
}
|
|
private STAFResult handleCompareDir(String exp_dir, String run_dir) {
|
logger.log(STAFLog.Warning,
|
"handle Directory comparaison exp_dir[" + exp_dir + "],dir[" + run_dir + "]");
|
File expDirFile;
|
File runDirFile;
|
STAFResult sr = new STAFResult(STAFResult.Ok);
|
try {
|
expDirFile = new File(exp_dir);
|
runDirFile = new File(run_dir);
|
ArrayList test_a = new ArrayList();
|
ArrayList missing_e = new ArrayList();
|
ArrayList missing_r = new ArrayList();
|
if (expDirFile.isDirectory() && runDirFile.isDirectory()) {
|
// find all the files with extension ".res"
|
File[] eFiles = expDirFile.listFiles(new DSMLFileFilter(DSMLFileFilter.EXPECTED_FILE_EXTENSION));
|
ArrayList ea = new ArrayList(eFiles.length);
|
String eName;
|
for (int ei = 0; ei < eFiles.length; ei++) {
|
eName = eFiles[ei].getName();
|
eName = eName.substring(0,eName.lastIndexOf(DSMLFileFilter.EXPECTED_FILE_EXTENSION));
|
ea.add(eName);
|
}
|
// find all the files with extension ".run"
|
File[] rFiles = runDirFile.listFiles(new DSMLFileFilter(DSMLFileFilter.RUN_FILE_EXTENSION));
|
ArrayList ra = new ArrayList(rFiles.length);
|
String rName;
|
for (int ri = 0; ri < rFiles.length; ri++) {
|
rName = rFiles[ri].getName();
|
rName = rName.substring(0,rName.lastIndexOf(DSMLFileFilter.RUN_FILE_EXTENSION));
|
ra.add(rName);
|
if (!ea.contains(rName)) {
|
// get a run file not matching expected result
|
missing_e.add(rName);
|
} else {
|
// expected and run file are both present
|
test_a.add(rName);
|
}
|
}
|
// find the missing result file and remove from test_a
|
for (int i=0; i< ea.size(); i++) {
|
String e = (String) ea.get(i);
|
if (!ra.contains(e)) {
|
missing_r.add(e);
|
}
|
}
|
// loop through the test set test_a and compare the files
|
for (int i=0 ; i < test_a.size(); i++) {
|
String tf = (String) test_a.get(i);
|
sr = handleCompareFile(
|
exp_dir+File.separator+tf+DSMLFileFilter.EXPECTED_FILE_EXTENSION,
|
run_dir+File.separator+tf+DSMLFileFilter.RUN_FILE_EXTENSION);
|
}
|
} else {
|
logger.log(STAFLog.Warning, "Directory comparaison with invalid input dir : " + exp_dir);
|
sr.rc = kDSMLInvalidSomething+8;
|
sr.result = "Directory comparaison with invalid input dir : " + exp_dir;
|
}
|
} catch (Exception e) {
|
sr.rc = kDSMLInvalidSomething+9;
|
sr.result = e.getMessage();
|
}
|
return sr;
|
}
|
|
private boolean compareResults(String expectedResult, String result) throws Exception {
|
|
ResponseChecker dsmlReponse = null;
|
ResponseChecker expectedReponse = null;
|
|
//System.out.println("result\n" + result);
|
try {
|
dsmlReponse = new ResponseChecker(result);
|
} catch (Exception e) {
|
if (e.getCause() != null) {
|
e.printStackTrace();
|
throw (new Exception("Response parsing error: " + e.getCause().getMessage()));
|
} else {
|
e.printStackTrace();
|
throw (new Exception("Response parsing error: " + e.getMessage()));
|
}
|
}
|
|
|
try {
|
expectedReponse = new ResponseChecker(expectedResult);
|
} catch (Exception e) {
|
if (e.getCause() != null) {
|
throw (new Exception("Parsing error for expected result : " + e.getCause().getMessage()));
|
} else {
|
throw (new Exception("Parsing error for expected result : " + e.getMessage()));
|
}
|
}
|
|
try {
|
return (dsmlReponse.equals(expectedReponse));
|
} catch (Exception e) {
|
logger.log(STAFLog.Warning, "failed comparing DSML responses exception " + e.getMessage());
|
return false;
|
}
|
}
|
|
private STAFResult handleInvalidRequest(STAFServiceInterfaceLevel30.RequestInfo info) {
|
logger.log(STAFLog.Error, "invalid request : [" + info.request + "]");
|
STAFResult sr = new STAFResult(kDSMLInvalidSomething+10);
|
sr.result = info.request;
|
return sr;
|
}
|
|
private STAFResult handleHelp(STAFServiceInterfaceLevel30.RequestInfo info) {
|
// Verify the requester has at least trust level 1
|
|
STAFResult trustResult = STAFUtil.validateTrust(
|
1, fServiceName, "HELP", fLocalMachineName, info);
|
|
if (trustResult.rc != STAFResult.Ok) {
|
return trustResult;
|
}
|
|
// Return help text for the service
|
|
return new STAFResult(
|
STAFResult.Ok,
|
"DSML Service Help :" + fLineSep + fLineSep + OP_COMPARE + "(" +
|
OP_EXP_FILE + " filename " + OP_FILE + " filename " + " | " +
|
OP_EXP_DIR + " dirname " + OP_DIR + " dirname )" +
|
fLineSep + OP_HELP);
|
}
|
|
|
// Register error codes for the STAX Service with the HELP service
|
private void registerHelpData(int errorNumber, String info,
|
String description) {
|
//TODO
|
}
|
|
// Un-register error codes for the STAX Service with the HELP service
|
private void unregisterHelpData(int errorNumber) {
|
//TODO
|
}
|
|
private class DSMLFileFilter implements FilenameFilter {
|
|
public static final String EXPECTED_FILE_EXTENSION = ".res";
|
public static final String ISSUE_FILE_EXTENSION = ".issue";
|
public static final String RUN_FILE_EXTENSION = ".run";
|
public static final String INPUT_FILE_EXTENSION = ".dat";
|
private ArrayList extList;
|
private String exclusiveExtension;
|
|
DSMLFileFilter() {
|
extList = new ArrayList();
|
exclusiveExtension = null;
|
extList.add(EXPECTED_FILE_EXTENSION);
|
extList.add(ISSUE_FILE_EXTENSION);
|
extList.add(RUN_FILE_EXTENSION);
|
extList.add(INPUT_FILE_EXTENSION);
|
}
|
|
DSMLFileFilter(String ext) {
|
exclusiveExtension = ext;
|
}
|
|
public boolean accept(File dir, String name) {
|
int li = name.lastIndexOf(".");
|
if (li > 0) {
|
if (exclusiveExtension != null) {
|
//comparing file name extension with exclusively one extension
|
if (name.substring(li).equals(exclusiveExtension)) {
|
return ((new File(dir + File.separator + name)).isFile());
|
} else {
|
return false;
|
}
|
} else {
|
// compare file name extension
|
if (extList.contains(name.substring(li))) {
|
return ((new File(dir + File.separator + name)).isFile());
|
} else {
|
return false;
|
}
|
}
|
} else {
|
return false;
|
}
|
}
|
}
|
}
|