/*
* Copyright 2013-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.glowroot.agent.embedded.repo;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import com.google.common.base.Ticker;
import com.google.common.collect.ImmutableList;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.glowroot.agent.collector.Collector.AggregateReader;
import org.glowroot.agent.collector.Collector.AggregateVisitor;
import org.glowroot.agent.embedded.util.CappedDatabase;
import org.glowroot.agent.embedded.util.DataSource;
import org.glowroot.common.live.ImmutableOverallQuery;
import org.glowroot.common.live.ImmutableTransactionQuery;
import org.glowroot.common.live.LiveAggregateRepository.OverallQuery;
import org.glowroot.common.live.LiveAggregateRepository.OverviewAggregate;
import org.glowroot.common.live.LiveAggregateRepository.TransactionQuery;
import org.glowroot.common.model.Result;
import org.glowroot.common.model.TransactionSummaryCollector;
import org.glowroot.common.model.TransactionSummaryCollector.SummarySortOrder;
import org.glowroot.common.model.TransactionSummaryCollector.TransactionSummary;
import org.glowroot.common.repo.AggregateRepository;
import org.glowroot.common.repo.ConfigRepository;
import org.glowroot.common.repo.ConfigRepository.RollupConfig;
import org.glowroot.common.repo.ImmutableRollupConfig;
import org.glowroot.common.util.Styles;
import org.glowroot.wire.api.model.AgentConfigOuterClass.AgentConfig.AdvancedConfig;
import org.glowroot.wire.api.model.AggregateOuterClass.Aggregate;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
// this is not an integration test (*IT.java) since then it would run against shaded agent and fail
// due to shading issues
@Styles.Private
public class AggregateDaoTest {
private static final String AGENT_ID = "";
private DataSource dataSource;
private File cappedFile;
private CappedDatabase cappedDatabase;
private AggregateDao aggregateDao;
@Before
public void beforeEachTest() throws Exception {
dataSource = new DataSource();
if (dataSource.tableExists("overall_point")) {
dataSource.execute("drop table overall_point");
}
if (dataSource.tableExists("transaction_point")) {
dataSource.execute("drop table transaction_point");
}
cappedFile = File.createTempFile("glowroot-test-", ".capped.db");
cappedDatabase = new CappedDatabase(cappedFile, 1000000, Ticker.systemTicker());
ConfigRepository configRepository = mock(ConfigRepository.class);
when(configRepository.getAdvancedConfig(AGENT_ID))
.thenReturn(AdvancedConfig.getDefaultInstance());
ImmutableList<RollupConfig> rollupConfigs = ImmutableList.<RollupConfig>of(
ImmutableRollupConfig.of(1000, 0), ImmutableRollupConfig.of(15000, 3600000),
ImmutableRollupConfig.of(900000000, 8 * 3600000));
when(configRepository.getRollupConfigs()).thenReturn(rollupConfigs);
aggregateDao = new AggregateDao(
dataSource, ImmutableList.<CappedDatabase>of(cappedDatabase, cappedDatabase,
cappedDatabase, cappedDatabase),
configRepository, mock(TransactionTypeDao.class), mock(FullQueryTextDao.class));
}
@After
public void afterEachTest() throws Exception {
dataSource.close();
cappedDatabase.close();
cappedFile.delete();
}
@Test
public void shouldReadTransactions() throws Exception {
// given
populateAggregates();
// when
TransactionQuery query = ImmutableTransactionQuery.builder()
.transactionType("a type")
.from(0)
.to(100000)
.rollupLevel(0)
.build();
OverallQuery query2 = ImmutableOverallQuery.builder()
.transactionType("a type")
.from(0)
.to(100000)
.rollupLevel(0)
.build();
TransactionSummaryCollector collector = new TransactionSummaryCollector();
List<OverviewAggregate> overallAggregates =
aggregateDao.readOverviewAggregates(AGENT_ID, query);
aggregateDao.mergeTransactionSummariesInto(AGENT_ID, query2, SummarySortOrder.TOTAL_TIME,
10, collector);
Result<TransactionSummary> queryResult =
collector.getResult(SummarySortOrder.TOTAL_TIME, 10);
// then
assertThat(overallAggregates).hasSize(2);
assertThat(queryResult.records()).hasSize(3);
assertThat(queryResult.records().get(0).transactionName()).isEqualTo("seven");
assertThat(queryResult.records().get(0).totalDurationNanos()).isEqualTo(2800000);
assertThat(queryResult.records().get(0).transactionCount()).isEqualTo(14);
assertThat(queryResult.records().get(1).transactionName()).isEqualTo("two");
assertThat(queryResult.records().get(1).totalDurationNanos()).isEqualTo(600000);
assertThat(queryResult.records().get(1).transactionCount()).isEqualTo(4);
assertThat(queryResult.records().get(2).transactionName()).isEqualTo("one");
assertThat(queryResult.records().get(2).totalDurationNanos()).isEqualTo(200000);
assertThat(queryResult.records().get(2).transactionCount()).isEqualTo(2);
}
// also used by TransactionCommonServiceTest
public void populateAggregates() throws Exception {
aggregateDao.store(new AggregateReader() {
@Override
public long captureTime() {
return 10000;
}
@Override
public void accept(AggregateVisitor aggregateVisitor) throws Exception {
aggregateVisitor.visitOverallAggregate("a type", new ArrayList<String>(),
Aggregate.newBuilder()
.setTotalDurationNanos(1000000)
.setErrorCount(0)
.setTransactionCount(10)
.setDurationNanosHistogram(getFakeHistogram())
.build());
aggregateVisitor.visitTransactionAggregate("a type", "one", new ArrayList<String>(),
Aggregate.newBuilder()
.setTotalDurationNanos(100000)
.setErrorCount(0)
.setTransactionCount(1)
.setDurationNanosHistogram(getFakeHistogram())
.build());
aggregateVisitor.visitTransactionAggregate("a type", "two", new ArrayList<String>(),
Aggregate.newBuilder()
.setTotalDurationNanos(300000)
.setErrorCount(0)
.setTransactionCount(2)
.setDurationNanosHistogram(getFakeHistogram())
.build());
aggregateVisitor.visitTransactionAggregate("a type", "seven",
new ArrayList<String>(), Aggregate.newBuilder()
.setTotalDurationNanos(1400000)
.setErrorCount(0)
.setTransactionCount(7)
.setDurationNanosHistogram(getFakeHistogram())
.build());
}
});
aggregateDao.store(new AggregateReader() {
@Override
public long captureTime() {
return 20000;
}
@Override
public void accept(AggregateVisitor aggregateVisitor) throws Exception {
aggregateVisitor.visitOverallAggregate("a type", new ArrayList<String>(),
Aggregate.newBuilder()
.setTotalDurationNanos(1000000)
.setErrorCount(0)
.setTransactionCount(10)
.setDurationNanosHistogram(getFakeHistogram())
.build());
aggregateVisitor.visitTransactionAggregate("a type", "one", new ArrayList<String>(),
Aggregate.newBuilder()
.setTotalDurationNanos(100000)
.setErrorCount(0)
.setTransactionCount(1)
.setDurationNanosHistogram(getFakeHistogram())
.build());
aggregateVisitor.visitTransactionAggregate("a type", "two", new ArrayList<String>(),
Aggregate.newBuilder()
.setTotalDurationNanos(300000)
.setErrorCount(0)
.setTransactionCount(2)
.setDurationNanosHistogram(getFakeHistogram())
.build());
aggregateVisitor.visitTransactionAggregate("a type", "seven",
new ArrayList<String>(), Aggregate.newBuilder()
.setTotalDurationNanos(1400000)
.setErrorCount(0)
.setTransactionCount(7)
.setDurationNanosHistogram(getFakeHistogram())
.build());
}
});
}
// used by TransactionCommonServiceTest
public AggregateRepository getAggregateRepository() {
return aggregateDao;
}
private static Aggregate.Histogram getFakeHistogram() {
return Aggregate.Histogram.newBuilder()
.addOrderedRawValue(123)
.addOrderedRawValue(456)
.build();
}
}