/*!
* This program is free software; you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License, version 2.1 as published by the Free Software
* Foundation.
*
* You should have received a copy of the GNU Lesser General Public License along with this
* program; if not, you can obtain a copy at http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html
* or from the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU Lesser General Public License for more details.
*
* Copyright (c) 2002-2013 Pentaho Corporation.. All rights reserved.
*/
package org.pentaho.reporting.engine.classic.core.bugs;
import java.io.OutputStream;
import junit.framework.Assert;
import junit.framework.TestCase;
import org.pentaho.reporting.engine.classic.core.ClassicEngineBoot;
import org.pentaho.reporting.engine.classic.core.MasterReport;
import org.pentaho.reporting.engine.classic.core.ReportProcessingException;
import org.pentaho.reporting.engine.classic.core.SimplePageDefinition;
import org.pentaho.reporting.engine.classic.core.designtime.DesignTimeDataSchemaModel;
import org.pentaho.reporting.engine.classic.core.layout.model.LogicalPageBox;
import org.pentaho.reporting.engine.classic.core.layout.output.ContentProcessingException;
import org.pentaho.reporting.engine.classic.core.layout.output.LogicalPageKey;
import org.pentaho.reporting.engine.classic.core.layout.output.OutputProcessorMetaData;
import org.pentaho.reporting.engine.classic.core.layout.process.CountBoxesStep;
import org.pentaho.reporting.engine.classic.core.modules.misc.datafactory.sequence.PerformanceTestSequence;
import org.pentaho.reporting.engine.classic.core.modules.misc.datafactory.sequence.SequenceDataFactory;
import org.pentaho.reporting.engine.classic.core.modules.output.table.base.FlowReportProcessor;
import org.pentaho.reporting.engine.classic.core.modules.output.table.base.StreamReportProcessor;
import org.pentaho.reporting.engine.classic.core.modules.output.table.base.TableContentProducer;
import org.pentaho.reporting.engine.classic.core.modules.output.table.html.AllItemsHtmlPrinter;
import org.pentaho.reporting.engine.classic.core.modules.output.table.html.FileSystemURLRewriter;
import org.pentaho.reporting.engine.classic.core.modules.output.table.html.HtmlOutputProcessor;
import org.pentaho.reporting.engine.classic.core.modules.output.table.html.HtmlPrinter;
import org.pentaho.reporting.engine.classic.core.modules.output.table.html.StreamHtmlOutputProcessor;
import org.pentaho.reporting.engine.classic.core.modules.output.table.xls.FlowExcelOutputProcessor;
import org.pentaho.reporting.engine.classic.core.testsupport.DebugReportRunner;
import org.pentaho.reporting.engine.classic.core.testsupport.RelationalReportBuilder;
import org.pentaho.reporting.engine.classic.core.util.PageSize;
import org.pentaho.reporting.libraries.base.config.Configuration;
import org.pentaho.reporting.libraries.base.util.NullOutputStream;
import org.pentaho.reporting.libraries.repository.ContentLocation;
import org.pentaho.reporting.libraries.repository.DefaultNameGenerator;
import org.pentaho.reporting.libraries.repository.stream.StreamRepository;
import org.pentaho.reporting.libraries.resourceloader.ResourceManager;
public class Prd4069Test extends TestCase
{
public Prd4069Test()
{
}
protected void setUp() throws Exception
{
ClassicEngineBoot.getInstance().start();
}
public void testFlowTableExport () throws ReportProcessingException
{
if (DebugReportRunner.isSkipLongRunTest())
{
return;
}
final MasterReport report = createTestReport();
final FlowExcelOutputProcessor target = new ValidatingFlowExcelOutputProcessor
(report.getConfiguration(), new NullOutputStream(), report.getResourceManager());
target.setUseXlsxFormat(true);
final FlowReportProcessor reportProcessor = new FlowReportProcessor(report, target);
reportProcessor.processReport();
reportProcessor.close();
}
private static class ValidatingFlowExcelOutputProcessor extends FlowExcelOutputProcessor
{
private CountBoxesStep countBoxesStep;
private ValidatingFlowExcelOutputProcessor(final Configuration config,
final OutputStream outputStream,
final ResourceManager resourceManager)
{
super(config, outputStream, resourceManager);
countBoxesStep = new CountBoxesStep();
}
protected void processTableContent(final LogicalPageKey logicalPageKey,
final LogicalPageBox logicalPage,
final TableContentProducer contentProducer) throws ContentProcessingException
{
final int count = countBoxesStep.countChildren(logicalPage);
// Count the maximum number of boxes that are active at any given point in time in the model.
// The model should work on a revolving basis, removing boxes that have been processed, so that
// we should see a relatively stable, low number of boxes, even though we process 20K of rows.
if (count > 10000)
{
Assert.fail();
}
super.processTableContent(logicalPageKey, logicalPage, contentProducer);
}
protected void updateTableContent(final LogicalPageKey logicalPageKey,
final LogicalPageBox logicalPageBox,
final TableContentProducer tableContentProducer,
final boolean performOutput) throws ContentProcessingException
{
final int count = countBoxesStep.countChildren(logicalPageBox);
// Count the maximum number of boxes that are active at any given point in time in the model.
// The model should work on a revolving basis, removing boxes that have been processed, so that
// we should see a relatively stable, low number of boxes, even though we process 20K of rows.
if (count > 10000)
{
Assert.fail();
}
super.updateTableContent(logicalPageKey, logicalPageBox, tableContentProducer, performOutput);
}
}
public void testStreamTableExport() throws ReportProcessingException
{
if (DebugReportRunner.isSkipLongRunTest())
{
return;
}
final MasterReport report = createTestReport();
final StreamRepository targetRepository = new StreamRepository(new NullOutputStream());
final ContentLocation targetRoot = targetRepository.getRoot();
final HtmlOutputProcessor outputProcessor = new StreamHtmlOutputProcessor(report.getConfiguration());
final HtmlPrinter printer = new ValidatingHtmlPrinter(report.getResourceManager());
printer.setContentWriter(targetRoot, new DefaultNameGenerator(targetRoot, "index", "html"));
printer.setDataWriter(null, null);
printer.setUrlRewriter(new FileSystemURLRewriter());
outputProcessor.setPrinter(printer);
final StreamReportProcessor sp = new StreamReportProcessor(report, outputProcessor);
sp.processReport();
sp.close();
}
private static class ValidatingHtmlPrinter extends AllItemsHtmlPrinter
{
private CountBoxesStep countBoxesStep;
private ValidatingHtmlPrinter(final ResourceManager resourceManager)
{
super(resourceManager);
countBoxesStep = new CountBoxesStep();
}
public void print(final LogicalPageKey logicalPageKey,
final LogicalPageBox logicalPage,
final TableContentProducer contentProducer,
final OutputProcessorMetaData metaData,
final boolean incremental) throws ContentProcessingException
{
final int count = countBoxesStep.countChildren(logicalPage);
// Count the maximum number of boxes that are active at any given point in time in the model.
// The model should work on a revolving basis, removing boxes that have been processed, so that
// we should see a relatively stable, low number of boxes, even though we process 20K of rows.
if (count > 2500)
{
Assert.fail();
}
super.print(logicalPageKey, logicalPage, contentProducer, metaData, incremental);
}
}
private MasterReport createTestReport()
{
final PerformanceTestSequence sequence = new PerformanceTestSequence();
sequence.setParameter("seed", 999L);
sequence.setParameter("limit", 20000);
final SequenceDataFactory sdf = new SequenceDataFactory();
sdf.addSequence("query", sequence);
// use HTML export for test
final MasterReport report = new MasterReport();
report.setPageDefinition(new SimplePageDefinition(new PageSize(800, 300)));
report.setDataFactory(sdf);
report.setQuery("query");
final DesignTimeDataSchemaModel dataSchemaModel = new DesignTimeDataSchemaModel(report);
final RelationalReportBuilder builder = new RelationalReportBuilder(dataSchemaModel);
builder.addDetails("text", null, null);
report.setRootGroup(builder.create());
return report;
}
}