/*!
* 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-2016 Pentaho Corporation.. All rights reserved.
*/
package org.pentaho.reporting.platform.plugin;
import junit.framework.Assert;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.pentaho.platform.api.engine.IApplicationContext;
import org.pentaho.platform.api.engine.IPentahoSession;
import org.pentaho.platform.engine.core.system.PentahoSessionHolder;
import org.pentaho.platform.engine.core.system.PentahoSystem;
import org.pentaho.platform.engine.core.system.StandaloneSession;
import org.pentaho.platform.engine.core.system.boot.PlatformInitializationException;
import org.pentaho.reporting.engine.classic.core.ClassicEngineBoot;
import org.pentaho.reporting.engine.classic.core.MasterReport;
import org.pentaho.reporting.engine.classic.core.event.ReportProgressEvent;
import org.pentaho.reporting.engine.classic.core.layout.output.ReportProcessorThreadHolder;
import org.pentaho.reporting.libraries.base.config.ModifiableConfiguration;
import org.pentaho.reporting.libraries.resourceloader.ResourceManager;
import org.pentaho.reporting.platform.plugin.async.AsyncExecutionStatus;
import org.pentaho.reporting.platform.plugin.async.AsyncReportStatusListener;
import org.pentaho.reporting.platform.plugin.async.ReportListenerThreadHolder;
import org.pentaho.reporting.platform.plugin.async.TestListener;
import org.pentaho.reporting.platform.plugin.cache.FileSystemCacheBackend;
import org.pentaho.reporting.platform.plugin.cache.IPluginCacheManager;
import org.pentaho.reporting.platform.plugin.cache.IReportContent;
import org.pentaho.reporting.platform.plugin.cache.PluginCacheManagerImpl;
import org.pentaho.reporting.platform.plugin.cache.PluginSessionCache;
import org.pentaho.test.platform.engine.core.MicroPlatform;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.util.Collections;
import java.util.HashMap;
import java.util.UUID;
import static org.junit.Assert.*;
import static org.mockito.Mockito.*;
public class PageableHTMLIT {
private static MicroPlatform microPlatform;
private static File tmp;
private static FileSystemCacheBackend fileSystemCacheBackend;
@BeforeClass
public static void setUpClass() throws PlatformInitializationException {
fileSystemCacheBackend = new FileSystemCacheBackend();
fileSystemCacheBackend.setCachePath( "/test-cache/" );
tmp = new File( "target/test/resource/solution/system/tmp" );
tmp.mkdirs();
microPlatform = MicroPlatformFactory.create();
final PluginSessionCache pluginSessionCache = spy( new PluginSessionCache( fileSystemCacheBackend ) );
final IReportContent content = mock( IReportContent.class );
when( content.getPageData( 3 ) ).thenReturn( null );
IPluginCacheManager iPluginCacheManager =
new PluginCacheManagerImpl( pluginSessionCache );
microPlatform.define( "IPluginCacheManager", iPluginCacheManager );
microPlatform.start();
IPentahoSession session = new StandaloneSession();
PentahoSessionHolder.setSession( session );
when( pluginSessionCache.get( "test" ) ).thenReturn( content );
final IApplicationContext applicationContext = PentahoSystem.getApplicationContext();
applicationContext.setSolutionRootPath( "target/test/resource/solution" );
}
@AfterClass
public static void tearDownClass() {
Assert.assertTrue( fileSystemCacheBackend.purge( Collections.singletonList( "" ) ) );
microPlatform.stop();
microPlatform = null;
}
@Test
public void testPageCount() throws Exception {
// create an instance of the component
SimpleReportingComponent rc = new SimpleReportingComponent();
// create/set the InputStream
FileInputStream reportDefinition =
new FileInputStream( "target/test/resource/solution/test/reporting/report.prpt" ); //$NON-NLS-1$
rc.setReportDefinitionInputStream( reportDefinition );
rc.setOutputType( "text/html" ); //$NON-NLS-1$
// turn on pagination, by way of input (typical mode for xaction)
HashMap<String, Object> inputs = new HashMap<String, Object>();
inputs.put( "paginate", "true" ); //$NON-NLS-1$ //$NON-NLS-2$
inputs.put( "accepted-page", "0" ); //$NON-NLS-1$ //$NON-NLS-2$
rc.setInputs( inputs );
FileOutputStream outputStream =
new FileOutputStream( new File( tmp, System.currentTimeMillis() + ".html" ) ); //$NON-NLS-1$ //$NON-NLS-2$
rc.setOutputStream( outputStream );
// execute the component
assertTrue( rc.execute() );
// make sure this report has 8 pages (we know this report will produce 8 pages with sample data)
assertEquals( 8, rc.getPageCount() );
}
@Test
public void testPaginatedHTML() throws Exception {
doTestPaginatedHTML( true, false );
Assert.assertTrue( fileSystemCacheBackend.purge( Collections.singletonList( "" ) ) );
doTestPaginatedHTML( true, true );
Assert.assertTrue( fileSystemCacheBackend.purge( Collections.singletonList( "" ) ) );
doTestPaginatedHTML( false, true );
Assert.assertTrue( fileSystemCacheBackend.purge( Collections.singletonList( "" ) ) );
doTestPaginatedHTML( false, false );
}
public void doTestPaginatedHTML( final boolean cache, final boolean listener ) throws Exception {
final ModifiableConfiguration edConf = ClassicEngineBoot.getInstance().getEditableConfig();
edConf.setConfigProperty( "org.pentaho.reporting.platform.plugin.output.CachePageableHtmlContent",
String.valueOf( cache ) );
edConf.setConfigProperty( "org.pentaho.reporting.platform.plugin.output.FirstPageMode", "true" );
edConf.setConfigProperty( "org.pentaho.reporting.engine.classic.core.states.PerformanceMonitorContext",
"org.pentaho.reporting.platform.plugin.PluginPerfomanceMonitorContext" );
try {
if ( listener ) {
ReportListenerThreadHolder.setListener( new TestListener( "test", UUID.randomUUID(), "text/html" ) );
}
// create an instance of the component
SimpleReportingComponent rc = new SimpleReportingComponent();
// create/set the InputStream
FileInputStream reportDefinition =
new FileInputStream( "target/test/resource/solution/test/reporting/report.prpt" ); //$NON-NLS-1$
rc.setReportDefinitionInputStream( reportDefinition );
rc.setOutputType( "text/html" ); //$NON-NLS-1$
// turn on pagination
rc.setPaginateOutput( true );
assertTrue( rc.isPaginateOutput() );
// turn it back off
rc.setPaginateOutput( false );
assertFalse( rc.isPaginateOutput() );
// turn on pagination, by way of input (typical mode for xaction)
HashMap<String, Object> inputs = new HashMap<String, Object>();
inputs.put( "paginate", "true" ); //$NON-NLS-1$ //$NON-NLS-2$
inputs.put( "accepted-page", "0" ); //$NON-NLS-1$ //$NON-NLS-2$
rc.setInputs( inputs );
FileOutputStream outputStream =
new FileOutputStream( new File( tmp, System.currentTimeMillis() + ".html" ) ); //$NON-NLS-1$ //$NON-NLS-2$
rc.setOutputStream( outputStream );
// check the accepted page
assertEquals( 0, rc.getAcceptedPage() );
// make sure pagination is really on
assertTrue( rc.isPaginateOutput() );
// validate the component
assertTrue( rc.validate() );
// execute the component
assertTrue( rc.execute() );
// make sure this report has 8 pages (we know this report will produce 8 pages with sample data)
assertEquals( 8, rc.getPageCount() );
} finally {
edConf.setConfigProperty( "org.pentaho.reporting.platform.plugin.output.CachePageableHtmlContent", null );
edConf.setConfigProperty( "org.pentaho.reporting.platform.plugin.output.FirstPageMode", null );
if ( listener ) {
ReportListenerThreadHolder.clear();
}
}
}
@Test
public void testPaginate() throws Exception {
final ModifiableConfiguration edConf = ClassicEngineBoot.getInstance().getEditableConfig();
edConf.setConfigProperty( "org.pentaho.reporting.platform.plugin.output.CachePageableHtmlContent", "true" );
edConf.setConfigProperty( "org.pentaho.reporting.platform.plugin.output.FirstPageMode", "true" );
try {
// create an instance of the component
SimpleReportingComponent rc = new SimpleReportingComponent();
// create/set the InputStream
FileInputStream reportDefinition =
new FileInputStream( "target/test/resource/solution/test/reporting/report.prpt" ); //$NON-NLS-1$
rc.setReportDefinitionInputStream( reportDefinition );
rc.setOutputType( "text/html" ); //$NON-NLS-1$
// turn on pagination
rc.setPaginateOutput( true );
assertTrue( rc.isPaginateOutput() );
// turn it back off
rc.setPaginateOutput( false );
assertFalse( rc.isPaginateOutput() );
// turn on pagination, by way of input (typical mode for xaction)
HashMap<String, Object> inputs = new HashMap<String, Object>();
inputs.put( "paginate", "true" ); //$NON-NLS-1$ //$NON-NLS-2$
inputs.put( "accepted-page", "0" ); //$NON-NLS-1$ //$NON-NLS-2$
rc.setInputs( inputs );
assertEquals( 8, rc.paginate() );
} finally {
edConf.setConfigProperty( "org.pentaho.reporting.platform.plugin.output.CachePageableHtmlContent", null );
edConf.setConfigProperty( "org.pentaho.reporting.platform.plugin.output.FirstPageMode", null );
}
}
@Test
public void testSchedulePartialCache() throws Exception {
ClassicEngineBoot.getInstance().start();
final ModifiableConfiguration edConf = ClassicEngineBoot.getInstance().getEditableConfig();
edConf.setConfigProperty( "org.pentaho.reporting.platform.plugin.output.CachePageableHtmlContent", "true" );
edConf.setConfigProperty( "org.pentaho.reporting.platform.plugin.output.FirstPageMode", "true" );
try {
final TestListener listener = new TestListener( "1", UUID.randomUUID(), "" );
listener.setStatus( AsyncExecutionStatus.SCHEDULED );
ReportListenerThreadHolder.setListener( listener );
// create an instance of the component
final SimpleReportingComponent rc = new SimpleReportingComponent();
final File src = new File( "target/test/resource/solution/test/reporting/report.prpt" );
final ResourceManager mgr = new ResourceManager();
final MasterReport r = (MasterReport) mgr.createDirectly( src, MasterReport.class ).getResource();
r.setContentCacheKey( "test" );
rc.setReport( r );
rc.setOutputType( "text/html" ); //$NON-NLS-1$
// turn on pagination, by way of input (typical mode for xaction)
final HashMap<String, Object> inputs = new HashMap<String, Object>();
inputs.put( "paginate", "true" ); //$NON-NLS-1$ //$NON-NLS-2$
inputs.put( "accepted-page", "3" ); //$NON-NLS-1$ //$NON-NLS-2$
rc.setInputs( inputs );
try ( final ByteArrayOutputStream outputStream =
new ByteArrayOutputStream() ) { //$NON-NLS-1$ //$NON-NLS-2$
rc.setOutputStream( outputStream );
assertTrue( rc.execute() );
final byte[] bytes = outputStream.toByteArray();
assertNotNull( bytes );
final String content = new String( bytes, "UTF-8" );
assertTrue( content.contains( "Scheduled paginated HTML report" ) );
}
// execute the component
assertTrue( listener.isOnStart() );
assertTrue( listener.isOnUpdate() );
assertTrue( listener.isOnFinish() );
assertFalse( -1 == listener.getState().getRow() );
assertFalse( -1 == listener.getState().getTotalRows() );
} finally {
ReportListenerThreadHolder.clear();
edConf.setConfigProperty( "org.pentaho.reporting.platform.plugin.output.CachePageableHtmlContent", null );
edConf.setConfigProperty( "org.pentaho.reporting.platform.plugin.output.FirstPageMode", null );
}
}
@Test
public void testCancel() throws Exception {
ClassicEngineBoot.getInstance().start();
final ModifiableConfiguration edConf = ClassicEngineBoot.getInstance().getEditableConfig();
edConf.setConfigProperty( "org.pentaho.reporting.platform.plugin.output.CachePageableHtmlContent", "true" );
edConf.setConfigProperty( "org.pentaho.reporting.platform.plugin.output.FirstPageMode", "true" );
try {
final AsyncReportStatusListener listener =
spy( new AsyncReportStatusListener( "report.prpt", UUID.randomUUID(), "text/html", Collections.emptyList() ) );
listener.setStatus( AsyncExecutionStatus.SCHEDULED );
ReportListenerThreadHolder.setListener( listener );
// create an instance of the component
SimpleReportingComponent rc = new SimpleReportingComponent();
// create/set the InputStream
FileInputStream reportDefinition =
new FileInputStream( "target/test/resource/solution/test/reporting/BigReport.prpt" ); //$NON-NLS-1$
rc.setReportDefinitionInputStream( reportDefinition );
rc.setOutputType( "text/html" ); //$NON-NLS-1$
// turn on pagination, by way of input (typical mode for xaction)
HashMap<String, Object> inputs = new HashMap<String, Object>();
inputs.put( "paginate", "true" ); //$NON-NLS-1$ //$NON-NLS-2$
inputs.put( "accepted-page", "0" ); //$NON-NLS-1$ //$NON-NLS-2$
rc.setInputs( inputs );
FileOutputStream outputStream =
new FileOutputStream( new File( tmp, System.currentTimeMillis() + ".html" ) ); //$NON-NLS-1$ //$NON-NLS-2$
rc.setOutputStream( outputStream );
listener.cancel();
// execute the component
assertFalse( rc.execute() );
} finally {
ReportListenerThreadHolder.clear();
edConf.setConfigProperty( "org.pentaho.reporting.platform.plugin.output.CachePageableHtmlContent", null );
edConf.setConfigProperty( "org.pentaho.reporting.platform.plugin.output.FirstPageMode", null );
}
}
/**
* What if somebody cleaned up ThreadLocal?
*/
@Test
public void testCancelBroken() throws Exception {
ClassicEngineBoot.getInstance().start();
final ModifiableConfiguration edConf = ClassicEngineBoot.getInstance().getEditableConfig();
edConf.setConfigProperty( "org.pentaho.reporting.platform.plugin.output.CachePageableHtmlContent", "true" );
edConf.setConfigProperty( "org.pentaho.reporting.platform.plugin.output.FirstPageMode", "true" );
try {
final AsyncReportStatusListener listener =
spy( new AsyncReportStatusListener( "report.prpt", UUID.randomUUID(), "text/html", Collections.emptyList() ) {
@Override public synchronized void reportProcessingUpdate( final ReportProgressEvent event ) {
ReportProcessorThreadHolder.clear();
super.reportProcessingUpdate( event );
}
} );
listener.setStatus( AsyncExecutionStatus.SCHEDULED );
ReportListenerThreadHolder.setListener( listener );
// create an instance of the component
SimpleReportingComponent rc = new SimpleReportingComponent();
// create/set the InputStream
FileInputStream reportDefinition =
new FileInputStream( "target/test/resource/solution/test/reporting/report.prpt" ); //$NON-NLS-1$
rc.setReportDefinitionInputStream( reportDefinition );
rc.setOutputType( "text/html" ); //$NON-NLS-1$
// turn on pagination, by way of input (typical mode for xaction)
HashMap<String, Object> inputs = new HashMap<String, Object>();
inputs.put( "paginate", "true" ); //$NON-NLS-1$ //$NON-NLS-2$
inputs.put( "accepted-page", "0" ); //$NON-NLS-1$ //$NON-NLS-2$
rc.setInputs( inputs );
FileOutputStream outputStream =
new FileOutputStream( new File( tmp, System.currentTimeMillis() + ".html" ) ); //$NON-NLS-1$ //$NON-NLS-2$
rc.setOutputStream( outputStream );
listener.cancel();
// execute the component
assertTrue( rc.execute() );
} finally {
ReportListenerThreadHolder.clear();
edConf.setConfigProperty( "org.pentaho.reporting.platform.plugin.output.CachePageableHtmlContent", null );
edConf.setConfigProperty( "org.pentaho.reporting.platform.plugin.output.FirstPageMode", null );
}
}
}