You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
accounting-lib/src/test/java/org/gcube/accounting/datamodel/validations/validators/TestRules.java

253 lines
9.3 KiB
Java

package org.gcube.accounting.datamodel.validations.validators;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.FilenameFilter;
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.gcube.accounting.aggregator.RegexRulesAggregator;
import org.gcube.accounting.datamodel.aggregation.AggregatedServiceUsageRecord;
import org.gcube.accounting.datamodel.usagerecords.ServiceUsageRecord;
import org.gcube.documentstore.exception.NotAggregatableRecordsExceptions;
import org.gcube.documentstore.records.DSMapper;
import org.gcube.testutility.ContextTest;
import org.gcube.testutility.TestUsageRecord;
import org.junit.Assert;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.fasterxml.jackson.databind.ObjectMapper;
public class TestRules extends ContextTest {
private static final Logger logger = LoggerFactory.getLogger(TestRules.class);
public File getRulesDirectory() throws Exception {
URL logbackFileURL = TestRules.class.getClassLoader().getResource("logback-test.xml");
File logbackFile = new File(logbackFileURL.toURI());
File resourcesDirectory = logbackFile.getParentFile();
return new File(resourcesDirectory, "rules");
}
protected long durationWeightedAverage(int numberA, long durationA, int numberB, long durationB) {
return ((numberA * durationA) + (numberB * durationB)) / (numberA + numberB);
}
public List<File> allRules() throws Exception {
File rulesDirectory = getRulesDirectory();
FilenameFilter filenameFilter = new FilenameFilter() {
@Override
public boolean accept(File dir, String name) {
return name.endsWith(".json");
}
};
List<File> rulesFiles = new ArrayList<>();
for(File dir : rulesDirectory.listFiles()) {
if(!dir.isDirectory()) {
continue;
}
rulesFiles.addAll(Arrays.asList(dir.listFiles(filenameFilter)));
RegexRulesAggregator regexRulesAggregator = RegexRulesAggregator.getInstance();
regexRulesAggregator.vacumRules();
for(File rulesFile : rulesFiles) {
ObjectMapper mapper = DSMapper.getObjectMapper();
MatcherReplace matcherReplace = mapper.readValue(rulesFile, MatcherReplace.class);
regexRulesAggregator.addMatcherReplace(matcherReplace);
}
}
return rulesFiles;
}
public void testRule(File rulesFile) throws Exception {
logger.info(
"-----------------------------------------------------------------------------------------------------");
logger.info("Analisyng rule from file {}\n", rulesFile.getAbsolutePath());
File rulesDirectory = rulesFile.getParentFile();
ObjectMapper mapper = DSMapper.getObjectMapper();
MatcherReplace matcherReplace = mapper.readValue(rulesFile, MatcherReplace.class);
Replace replacementRegex = matcherReplace.getReplacementRegex();
Map<String,AggregatedServiceUsageRecord> aggregatedMap = new HashMap<>();
AggregatedServiceUsageRecord aggregated;
// it indicates that the rules can create multiple calledMethod because the replacement is based on
// Named Capture Group
final String requiredMatchesFileName = rulesFile.getName().replaceAll(".json", ".csv");
File elaborationFile = new File(rulesDirectory, requiredMatchesFileName);
try(BufferedReader br = new BufferedReader(new FileReader(elaborationFile))) {
for(String line; (line = br.readLine()) != null;) {
String[] splittedLine = line.split(",");
String serviceClass = splittedLine[0];
String serviceName = splittedLine[1];
String calledMethod = splittedLine[2];
Replace replace = matcherReplace.check(serviceClass, serviceName, calledMethod);
if(replace != null) {
logger.info("{} --> {},{},{}", line, replace.getServiceClass(), replace.getServiceName(),
replace.getCalledMethod());
} else {
logger.error("{} does not match {}. This MUST not occur.", line,
matcherReplace.getMultiMatcher().toString());
throw new Exception();
}
String obtainedTriple = replace.getServiceClass() + "+++" + replace.getServiceName() + "+++"
+ replace.getCalledMethod();
if(aggregatedMap.containsKey(obtainedTriple)) {
aggregated = aggregatedMap.get(obtainedTriple);
} else {
ServiceUsageRecord serviceUsageRecord = TestUsageRecord.createTestServiceUsageRecord();
serviceUsageRecord.setServiceClass(replace.getServiceClass());
serviceUsageRecord.setServiceName(replace.getServiceName());
serviceUsageRecord.setCalledMethod(replace.getCalledMethod());
serviceUsageRecord.validate();
aggregated = new AggregatedServiceUsageRecord(serviceUsageRecord);
aggregatedMap.put(obtainedTriple, aggregated);
}
ServiceUsageRecord sur = TestUsageRecord.createTestServiceUsageRecord();
sur.setServiceClass(serviceClass);
sur.setServiceName(serviceName);
sur.setCalledMethod(calledMethod);
sur.validate();
sur.validate();
// logger.trace("To Be aggregated ServiceUsageRecord {}", sur);
long oldMinInvocationTime = aggregated.getMinInvocationTime();
long oldMaxInvocationTime = aggregated.getMaxInvocationTime();
int oldOperationCount = aggregated.getOperationCount();
long oldDuration = aggregated.getDuration();
long surDuration = sur.getDuration();
try {
aggregated.aggregate(sur);
//logger.debug("Resulting Aggregated ServiceUsageRecord: {}", aggregated);
}catch(NotAggregatableRecordsExceptions e) {
logger.error("The Record is not aggregatable : {}", sur);
throw e;
}
long avgDuration = durationWeightedAverage(oldOperationCount, oldDuration, 1, surDuration);
Assert.assertTrue(aggregated.getDuration() == (avgDuration));
Assert.assertTrue(aggregated.getOperationCount() == ++oldOperationCount);
if(oldMinInvocationTime >= surDuration) {
Assert.assertTrue(aggregated.getMinInvocationTime() == surDuration);
} else {
Assert.assertTrue(aggregated.getMinInvocationTime() == oldMinInvocationTime);
}
if(oldMaxInvocationTime >= surDuration) {
Assert.assertTrue(aggregated.getMaxInvocationTime() == oldMaxInvocationTime);
} else {
Assert.assertTrue(aggregated.getMaxInvocationTime() == surDuration);
}
}
} catch(Exception e) {
throw e;
}
FilenameFilter filenameFilter = new FilenameFilter() {
@Override
public boolean accept(File dir, String name) {
boolean accept = name.endsWith(".csv");
return name.compareTo(requiredMatchesFileName) != 0 && accept;
}
};
for(File elaborationFileNoMatch : rulesDirectory.listFiles(filenameFilter)) {
logger.info("Comparing examples which must not match from file {}", elaborationFileNoMatch.getName());
try(BufferedReader br = new BufferedReader(new FileReader(elaborationFileNoMatch))) {
for(String line; (line = br.readLine()) != null;) {
String[] splittedLine = line.split(",");
String serviceClass = splittedLine[0];
String serviceName = splittedLine[1];
String calledMethod = splittedLine[2];
Replace replace = matcherReplace.check(serviceClass, serviceName, calledMethod);
if(replace != null) {
logger.error("{} match {} but it should NOT. This MUST not occur.", line,
matcherReplace.getMultiMatcher().toString());
throw new Exception();
} else {
logger.trace("{} does NOT match as requested", line, replacementRegex.getServiceClass(),
replacementRegex.getServiceName(), replacementRegex.getCalledMethod());
}
ServiceUsageRecord sur = TestUsageRecord.createTestServiceUsageRecord();
sur.setServiceClass(serviceClass);
sur.setServiceName(serviceName);
sur.setCalledMethod(calledMethod);
sur.validate();
//logger.trace("Should not be aggregated ServiceUsageRecord {}", sur);
for(AggregatedServiceUsageRecord asur : aggregatedMap.values()) {
try {
asur.aggregate(sur);
logger.error("The record {} has been aggregated and it should NOT", sur);
throw new Exception("The record has been aggregated and it should NOT");
} catch(NotAggregatableRecordsExceptions e) {
//logger.trace("{} is not aggragable as expected", sur);
}
}
}
} catch(Exception e) {
throw e;
}
}
logger.info(
"-----------------------------------------------------------------------------------------------------\n\n\n");
}
@Test
public void testSingleRule() throws Exception {
allRules();
File rulesDirectory = getRulesDirectory();
File rulesDirFile = new File(rulesDirectory, "DataMiner");
File rulesFile = new File(rulesDirFile, "DataMiner-all.json");
testRule(rulesFile);
}
@Test
public void testAllRules() throws Exception {
List<File> rulesFiles = allRules();
for(File rulesFile : rulesFiles) {
testRule(rulesFile);
}
}
@Test
public void testMatcherReplace() throws Exception {
File rulesDirectory = getRulesDirectory();
File rulesDirFile = new File(rulesDirectory, "geoanalytics-gos");
File rulesFile = new File(rulesDirFile, "geoanalytics-gos-OTHER.json");
ObjectMapper mapper = DSMapper.getObjectMapper();
MatcherReplace matcherReplace = mapper.readValue(rulesFile, MatcherReplace.class);
Replace replace = matcherReplace.check("geoanalytics","geoanalytics-gos-gos","/ShapeManagement/applyOnView");
logger.info("{}", replace);
}
}