diff options
Diffstat (limited to 'sparkybe-onap-service/src/test/java/org/onap/aai/sparky/sync/AbstractEntitySynchronizerTest.java')
-rw-r--r-- | sparkybe-onap-service/src/test/java/org/onap/aai/sparky/sync/AbstractEntitySynchronizerTest.java | 463 |
1 files changed, 463 insertions, 0 deletions
diff --git a/sparkybe-onap-service/src/test/java/org/onap/aai/sparky/sync/AbstractEntitySynchronizerTest.java b/sparkybe-onap-service/src/test/java/org/onap/aai/sparky/sync/AbstractEntitySynchronizerTest.java new file mode 100644 index 0000000..3bd4928 --- /dev/null +++ b/sparkybe-onap-service/src/test/java/org/onap/aai/sparky/sync/AbstractEntitySynchronizerTest.java @@ -0,0 +1,463 @@ +package org.onap.aai.sparky.sync; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + +import java.security.SecureRandom; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.regex.Pattern; + +import org.junit.Before; +import org.junit.Test; +import org.mockito.Mockito; +import org.onap.aai.cl.api.Logger; +import org.onap.aai.cl.eelf.LoggerFactory; +import org.onap.aai.restclient.client.OperationResult; +import org.onap.aai.sparky.config.oxm.SearchableEntityLookup; +import org.onap.aai.sparky.config.oxm.SearchableOxmEntityDescriptor; +import org.onap.aai.sparky.dal.ActiveInventoryAdapter; +import org.onap.aai.sparky.dal.ElasticSearchAdapter; +import org.onap.aai.sparky.dal.NetworkTransaction; +import org.onap.aai.sparky.dal.rest.HttpMethod; +import org.onap.aai.sparky.sync.config.NetworkStatisticsConfig; + + + +public class AbstractEntitySynchronizerTest { + + public class QuantumSynchronizer extends AbstractEntitySynchronizer { + + private boolean amIDone; + private SearchableEntityLookup searchableEntityLookup; + + protected QuantumSynchronizer(Logger logger, String syncName, int numSyncWorkers, int numActiveInventoryWorkers, + int numElasticsearchWorkers, String indexName, NetworkStatisticsConfig aaiStatConfig, + NetworkStatisticsConfig esStatConfig) throws Exception { + super(logger, syncName, numSyncWorkers, numActiveInventoryWorkers, numElasticsearchWorkers, indexName, + aaiStatConfig, esStatConfig); + + amIDone = false; + + } + + public void setSearchableEntityLookup(SearchableEntityLookup searchableEntityLookup) { + this.searchableEntityLookup = searchableEntityLookup; + } + + public void initCounters() { + if (this.searchableEntityLookup != null) { + this.aaiEntityStats + .intializeEntityCounters(searchableEntityLookup.getSearchableEntityDescriptors().keySet()); + this.esEntityStats + .intializeEntityCounters(searchableEntityLookup.getSearchableEntityDescriptors().keySet()); + + } + } + + public void setSyncDone(boolean done) { + this.amIDone = done; + } + + @Override + protected boolean isSyncDone() { + return amIDone; + } + + } + + private static Logger LOG = LoggerFactory.getInstance().getLogger(AbstractEntitySynchronizerTest.class); + private static SecureRandom secureRandom = new SecureRandom(); + + private QuantumSynchronizer quantumSync; + private NetworkStatisticsConfig aaiStatConfig; + private NetworkStatisticsConfig esStatConfig; + private ElasticSearchAdapter esAdapter; + private ActiveInventoryAdapter aaiAdapter; + private SearchableEntityLookup searchableEntityLookup; + + + @Before + public void init() throws Exception { + + aaiStatConfig = new NetworkStatisticsConfig(); + + aaiStatConfig.setNumSamplesPerThreadForRunningAverage(100); + + aaiStatConfig.setBytesHistogramLabel("[Response Size In Bytes]"); + aaiStatConfig.setBytesHistogramMaxYAxis(1000000L); + aaiStatConfig.setBytesHistogramNumBins(20); + aaiStatConfig.setBytesHistogramNumDecimalPoints(2); + + aaiStatConfig.setQueueLengthHistogramLabel("[Queue Item Length]"); + aaiStatConfig.setQueueLengthHistogramMaxYAxis(20000); + aaiStatConfig.setQueueLengthHistogramNumBins(20); + aaiStatConfig.setQueueLengthHistogramNumDecimalPoints(2); + + aaiStatConfig.setTaskAgeHistogramLabel("[Task Age In Ms]"); + aaiStatConfig.setTaskAgeHistogramMaxYAxis(600000L); + aaiStatConfig.setTaskAgeHistogramNumBins(20); + aaiStatConfig.setTaskAgeHistogramNumDecimalPoints(2); + + aaiStatConfig.setResponseTimeHistogramLabel("[Response Time In Ms]"); + aaiStatConfig.setResponseTimeHistogramMaxYAxis(1000L); + aaiStatConfig.setResponseTimeHistogramNumBins(20); + aaiStatConfig.setResponseTimeHistogramNumDecimalPoints(2); + + aaiStatConfig.setTpsHistogramLabel("[Transactions Per Second]"); + aaiStatConfig.setTpsHistogramMaxYAxis(100); + aaiStatConfig.setTpsHistogramNumBins(20); + aaiStatConfig.setTpsHistogramNumDecimalPoints(2); + + esStatConfig = new NetworkStatisticsConfig(); + + esStatConfig.setNumSamplesPerThreadForRunningAverage(100); + + esStatConfig.setBytesHistogramLabel("[Response Size In Bytes]"); + esStatConfig.setBytesHistogramMaxYAxis(1000000L); + esStatConfig.setBytesHistogramNumBins(20); + esStatConfig.setBytesHistogramNumDecimalPoints(2); + + esStatConfig.setQueueLengthHistogramLabel("[Queue Item Length]"); + esStatConfig.setQueueLengthHistogramMaxYAxis(20000); + esStatConfig.setQueueLengthHistogramNumBins(20); + esStatConfig.setQueueLengthHistogramNumDecimalPoints(2); + + esStatConfig.setTaskAgeHistogramLabel("[Task Age In Ms]"); + esStatConfig.setTaskAgeHistogramMaxYAxis(600000L); + esStatConfig.setTaskAgeHistogramNumBins(20); + esStatConfig.setTaskAgeHistogramNumDecimalPoints(2); + + esStatConfig.setResponseTimeHistogramLabel("[Response Time In Ms]"); + esStatConfig.setResponseTimeHistogramMaxYAxis(10000L); + esStatConfig.setResponseTimeHistogramNumBins(20); + esStatConfig.setResponseTimeHistogramNumDecimalPoints(2); + + esStatConfig.setTpsHistogramLabel("[Transactions Per Second]"); + esStatConfig.setTpsHistogramMaxYAxis(100); + esStatConfig.setTpsHistogramNumBins(20); + esStatConfig.setTpsHistogramNumDecimalPoints(2); + + esAdapter = Mockito.mock(ElasticSearchAdapter.class); + aaiAdapter = Mockito.mock(ActiveInventoryAdapter.class); + + } + + @Test + public void validateNetworkStatConfig() { + + // validate aaiStatConfig + + assertEquals(100, aaiStatConfig.getNumSamplesPerThreadForRunningAverage()); + + assertEquals("[Response Size In Bytes]",aaiStatConfig.getBytesHistogramLabel()); + assertEquals(1000000L,aaiStatConfig.getBytesHistogramMaxYAxis()); + assertEquals(20,aaiStatConfig.getBytesHistogramNumBins()); + assertEquals(2,aaiStatConfig.getBytesHistogramNumDecimalPoints()); + + assertEquals("[Queue Item Length]",aaiStatConfig.getQueueLengthHistogramLabel()); + assertEquals(20000,aaiStatConfig.getQueueLengthHistogramMaxYAxis()); + assertEquals(20,aaiStatConfig.getQueueLengthHistogramNumBins()); + assertEquals(2,aaiStatConfig.getQueueLengthHistogramNumDecimalPoints()); + + assertEquals("[Task Age In Ms]",aaiStatConfig.getTaskAgeHistogramLabel()); + assertEquals(600000L,aaiStatConfig.getTaskAgeHistogramMaxYAxis()); + assertEquals(20,aaiStatConfig.getTaskAgeHistogramNumBins()); + assertEquals(2,aaiStatConfig.getTaskAgeHistogramNumDecimalPoints()); + + assertEquals("[Response Time In Ms]",aaiStatConfig.getResponseTimeHistogramLabel()); + assertEquals(1000L,aaiStatConfig.getResponseTimeHistogramMaxYAxis()); + assertEquals(20,aaiStatConfig.getResponseTimeHistogramNumBins()); + assertEquals(2, aaiStatConfig.getResponseTimeHistogramNumDecimalPoints()); + + assertEquals("[Transactions Per Second]",aaiStatConfig.getTpsHistogramLabel()); + assertEquals(100,aaiStatConfig.getTpsHistogramMaxYAxis()); + assertEquals(20,aaiStatConfig.getTpsHistogramNumBins()); + assertEquals(2,aaiStatConfig.getTpsHistogramNumDecimalPoints()); + + // validate esStatConfig + + assertEquals(100, esStatConfig.getNumSamplesPerThreadForRunningAverage()); + + assertEquals("[Response Size In Bytes]",esStatConfig.getBytesHistogramLabel()); + assertEquals(1000000L,esStatConfig.getBytesHistogramMaxYAxis()); + assertEquals(20,esStatConfig.getBytesHistogramNumBins()); + assertEquals(2,esStatConfig.getBytesHistogramNumDecimalPoints()); + + assertEquals("[Queue Item Length]",esStatConfig.getQueueLengthHistogramLabel()); + assertEquals(20000,esStatConfig.getQueueLengthHistogramMaxYAxis()); + assertEquals(20,esStatConfig.getQueueLengthHistogramNumBins()); + assertEquals(2,esStatConfig.getQueueLengthHistogramNumDecimalPoints()); + + assertEquals("[Task Age In Ms]",esStatConfig.getTaskAgeHistogramLabel()); + assertEquals(600000L,esStatConfig.getTaskAgeHistogramMaxYAxis()); + assertEquals(20,esStatConfig.getTaskAgeHistogramNumBins()); + assertEquals(2,esStatConfig.getTaskAgeHistogramNumDecimalPoints()); + + assertEquals("[Response Time In Ms]",esStatConfig.getResponseTimeHistogramLabel()); + assertEquals(10000L,esStatConfig.getResponseTimeHistogramMaxYAxis()); + assertEquals(20,esStatConfig.getResponseTimeHistogramNumBins()); + assertEquals(2, esStatConfig.getResponseTimeHistogramNumDecimalPoints()); + + assertEquals("[Transactions Per Second]",esStatConfig.getTpsHistogramLabel()); + assertEquals(100,esStatConfig.getTpsHistogramMaxYAxis()); + assertEquals(20,esStatConfig.getTpsHistogramNumBins()); + assertEquals(2,esStatConfig.getTpsHistogramNumDecimalPoints()); + + } + + @Test + public void validateBasicConstruction() throws Exception { + + quantumSync = new QuantumSynchronizer(LOG, "quanumSynchronizer", 5, 5, 5, "quantum-search-index", aaiStatConfig, + esStatConfig); + + quantumSync.setAaiAdapter(aaiAdapter); + quantumSync.setElasticSearchAdapter(esAdapter); + + quantumSync.clearCache(); + + assertNotNull(quantumSync.getAaiAdapter()); + assertNotNull(quantumSync.getElasticSearchAdapter()); + assertEquals("quantum-search-index", quantumSync.getIndexName()); + + quantumSync.setIndexName("new-search-index-name"); + assertEquals("new-search-index-name", quantumSync.getIndexName()); + + quantumSync.shutdownExecutors(); + } + + private static String REST_STAT_LINE_FORMAT = ".*%s.*1XX:.*%d.*2XX:.*%d.*3XX:.*%d.*4XX:.*%d.*5XX:.*%d.*6XX:.*%d.*"; + private static String ENTITY_STATS_LINE_FORMAT = ".*%s.*TOTAL:.*%d.*FOUND:.*%d.*NO_PAYLOAD:.*%d.*NOT_FOUND:.*%d.*NUM_RETRIES:.*%d.*ERROR:.*%d.*"; + + private boolean reportContainsRestStatistics(String testString, HttpMethod httpMethod, long oneXX, long twoXX, + long threeXX, long fourXX, long fiveXX, long sixXX) { + + Pattern pattern = Pattern.compile(String.format(REST_STAT_LINE_FORMAT, httpMethod.toString(), oneXX, twoXX, + threeXX, fourXX, fiveXX, sixXX)); + + String lines[] = testString.split("\\r?\\n"); + + /* + * if we get a match on any of the lines in the report, then we + * succeeded + */ + + for (String line : lines) { + if (pattern.matcher(line).matches()) { + return true; + } + } + + return false; + } + + private boolean reportContainsEntityStatistics(String testString, String entityType, long total, long found, + long noPayload, long notFound, long numRetries, long numErrors) { + + Pattern pattern = Pattern.compile(String.format(ENTITY_STATS_LINE_FORMAT, entityType, total, found, + noPayload, notFound, numRetries, numErrors)); + + String lines[] = testString.split("\\r?\\n"); + + /* + * if we get a match on any of the lines in the report, then we + * succeeded + */ + + for (String line : lines) { + if (pattern.matcher(line).matches()) { + return true; + } + } + + return false; + } + + + @Test + public void validateStatisticTrackingAndReporting() throws Exception { + + quantumSync = new QuantumSynchronizer(LOG, "quanumSynchronizer", 5, 5, 5, "quantum-search-index", aaiStatConfig, + esStatConfig); + + quantumSync.setAaiAdapter(aaiAdapter); + quantumSync.setElasticSearchAdapter(esAdapter); + + searchableEntityLookup = new SearchableEntityLookup(); + + Map<String,SearchableOxmEntityDescriptor> searchableDescriptors = new HashMap<String,SearchableOxmEntityDescriptor>(); + + SearchableOxmEntityDescriptor complexDescriptor = new SearchableOxmEntityDescriptor(); + complexDescriptor.setEntityName("complex"); + List<String> pkeyNames = new ArrayList<String>(); + pkeyNames.add("physical-location-id"); + + complexDescriptor.setPrimaryKeyAttributeNames(pkeyNames); + complexDescriptor.setSearchableAttributes(pkeyNames); + + searchableDescriptors.put("complex", complexDescriptor); + + searchableEntityLookup.setSearchableEntityDescriptors(searchableDescriptors); + + quantumSync.setSearchableEntityLookup(searchableEntityLookup); + quantumSync.initCounters(); + + int randomMaxTimesToPegCounters = secureRandom.nextInt(1000); + + NetworkTransaction txn = null; + OperationResult opResult = null; + + + /* + * The result of this block is that for all HttpMethod types [ PUT, POST, GET, etc ] we'll peg a complex entity + * type counter a random number of times (set before the for loop, and for each status code category 1XX -> 6XX. + */ + + // GET, PUT, POST, DELETE, PATCH, HEAD + for (HttpMethod httpMethod : HttpMethod.values()) { + + // for randomMaxTimesToPegCounters + for (int numTimesToPegCounter = 0; numTimesToPegCounter < randomMaxTimesToPegCounters; numTimesToPegCounter++) { + txn = new NetworkTransaction(); + txn.setOperationType(httpMethod); + txn.setEntityType("complex"); + + /* + * set the txn optime to a random value between 0 and 10000 ms. + * Over thousands of counter statistics the random sample + * averages should be approximately uniform, but is highly + * dependent on the pseudo-RNG. + */ + txn.setOpTimeInMs(secureRandom.nextInt(10000)); + + // 1XX, 2XX, 3XX, 4XX, 5XX, 6XX + for ( int resultCode = 100; resultCode < 700; resultCode += 100) { + opResult = new OperationResult(); + opResult.setResultCode(resultCode); + + txn.setOperationResult(opResult); + + // peg both AAI and ES statistics + + quantumSync.updateActiveInventoryCounters(txn); + quantumSync.updateActiveInventoryCounters(httpMethod, "complex", opResult); + + quantumSync.updateElasticSearchCounters(txn); + quantumSync.updateElasticSearchCounters(httpMethod, "complex", opResult); + + } + } + } + + for (int numTimesToPegCounter = 0; numTimesToPegCounter < randomMaxTimesToPegCounters; numTimesToPegCounter++) { + quantumSync.incActiveInventoryWorkOnHandCounter(); + quantumSync.incElasticSearchWorkOnHandCounter(); + } + + assertEquals( randomMaxTimesToPegCounters, quantumSync.aaiWorkOnHand.get()); + assertEquals( randomMaxTimesToPegCounters, quantumSync.esWorkOnHand.get()); + + /* + * now we'll generate various reports and try to validate the output + */ + + String aaiStatsReport = quantumSync.getActiveInventoryStatisticsReport(); + + /* + * We double the expected validation check number because we peg each + * counter in each category twice (with different APIs for the same + * entity. + */ + + assertTrue(reportContainsRestStatistics(aaiStatsReport, HttpMethod.DELETE, randomMaxTimesToPegCounters * 2, + randomMaxTimesToPegCounters * 2, randomMaxTimesToPegCounters * 2, randomMaxTimesToPegCounters * 2, + randomMaxTimesToPegCounters * 2, randomMaxTimesToPegCounters * 2)); + + assertTrue(reportContainsRestStatistics(aaiStatsReport, HttpMethod.PUT, randomMaxTimesToPegCounters * 2, + randomMaxTimesToPegCounters * 2, randomMaxTimesToPegCounters * 2, randomMaxTimesToPegCounters * 2, + randomMaxTimesToPegCounters * 2, randomMaxTimesToPegCounters * 2)); + + assertTrue(reportContainsRestStatistics(aaiStatsReport, HttpMethod.POST, randomMaxTimesToPegCounters * 2, + randomMaxTimesToPegCounters * 2, randomMaxTimesToPegCounters * 2, randomMaxTimesToPegCounters * 2, + randomMaxTimesToPegCounters * 2, randomMaxTimesToPegCounters * 2)); + + assertTrue(reportContainsRestStatistics(aaiStatsReport, HttpMethod.GET, randomMaxTimesToPegCounters * 2, + randomMaxTimesToPegCounters * 2, randomMaxTimesToPegCounters * 2, randomMaxTimesToPegCounters * 2, + randomMaxTimesToPegCounters * 2, randomMaxTimesToPegCounters * 2)); + + long total = (randomMaxTimesToPegCounters*2)*6; + long found = randomMaxTimesToPegCounters*2; + long noPayload = (randomMaxTimesToPegCounters*2)*6; + long notFound = 0; + long numRetries = 0; + long numErrors = (randomMaxTimesToPegCounters*2)*5; + + assertTrue(reportContainsEntityStatistics(aaiStatsReport, "complex", total, found, + noPayload, notFound, numRetries, numErrors)); + + String esStatsReport = quantumSync.getElasticSearchStatisticsReport(); + + assertTrue(reportContainsRestStatistics(esStatsReport, HttpMethod.DELETE, randomMaxTimesToPegCounters * 2, + randomMaxTimesToPegCounters * 2, randomMaxTimesToPegCounters * 2, randomMaxTimesToPegCounters * 2, + randomMaxTimesToPegCounters * 2, randomMaxTimesToPegCounters * 2)); + + assertTrue(reportContainsRestStatistics(esStatsReport, HttpMethod.PUT, randomMaxTimesToPegCounters * 2, + randomMaxTimesToPegCounters * 2, randomMaxTimesToPegCounters * 2, randomMaxTimesToPegCounters * 2, + randomMaxTimesToPegCounters * 2, randomMaxTimesToPegCounters * 2)); + + assertTrue(reportContainsRestStatistics(esStatsReport, HttpMethod.POST, randomMaxTimesToPegCounters * 2, + randomMaxTimesToPegCounters * 2, randomMaxTimesToPegCounters * 2, randomMaxTimesToPegCounters * 2, + randomMaxTimesToPegCounters * 2, randomMaxTimesToPegCounters * 2)); + + assertTrue(reportContainsRestStatistics(esStatsReport, HttpMethod.GET, randomMaxTimesToPegCounters * 2, + randomMaxTimesToPegCounters * 2, randomMaxTimesToPegCounters * 2, randomMaxTimesToPegCounters * 2, + randomMaxTimesToPegCounters * 2, randomMaxTimesToPegCounters * 2)); + + + assertNotNull(quantumSync.getStatReport(10000L, false)); + assertNotNull(quantumSync.getStatReport(20000L, true)); + + for (int numTimesToPegCounter = 0; numTimesToPegCounter < randomMaxTimesToPegCounters; numTimesToPegCounter++) { + quantumSync.decActiveInventoryWorkOnHandCounter(); + quantumSync.decElasticSearchWorkOnHandCounter(); + } + + assertEquals( 0, quantumSync.aaiWorkOnHand.get()); + assertEquals( 0, quantumSync.esWorkOnHand.get()); + + /* + * Validate stat reports display zero stats for complex + */ + + quantumSync.resetCounters(); + + aaiStatsReport = quantumSync.getActiveInventoryStatisticsReport(); + + /* + * We double the expected validation check number because we peg each + * counter in each category twice (with different APIs for the same + * entity. + */ + + assertTrue(reportContainsRestStatistics(aaiStatsReport, HttpMethod.DELETE, 0, 0, 0, 0, 0, 0)); + assertTrue(reportContainsRestStatistics(aaiStatsReport, HttpMethod.PUT, 0, 0, 0, 0, 0, 0)); + assertTrue(reportContainsRestStatistics(aaiStatsReport, HttpMethod.POST, 0, 0, 0, 0, 0, 0)); + assertTrue(reportContainsRestStatistics(aaiStatsReport, HttpMethod.GET, 0, 0, 0, 0, 0, 0)); + + assertTrue(reportContainsEntityStatistics(aaiStatsReport, "complex", 0, 0, 0, 0, 0, 0)); + + esStatsReport = quantumSync.getElasticSearchStatisticsReport(); + + assertTrue(reportContainsRestStatistics(esStatsReport, HttpMethod.DELETE, 0, 0, 0, 0, 0, 0)); + assertTrue(reportContainsRestStatistics(esStatsReport, HttpMethod.PUT, 0, 0, 0, 0, 0, 0)); + assertTrue(reportContainsRestStatistics(esStatsReport, HttpMethod.POST, 0, 0, 0, 0, 0, 0)); + assertTrue(reportContainsRestStatistics(esStatsReport, HttpMethod.GET, 0, 0, 0, 0, 0, 0)); + + quantumSync.shutdownExecutors(); + } + +} |