/*!
* 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-2017 Pentaho Corporation.. All rights reserved.
*/
package org.pentaho.reporting.platform.plugin.output;
import org.apache.commons.io.output.ByteArrayOutputStream;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Ignore;
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.ReportProcessingException;
import org.pentaho.reporting.engine.classic.core.event.ReportProgressEvent;
import org.pentaho.reporting.engine.classic.core.modules.output.pageable.base.PageableReportProcessor;
import org.pentaho.reporting.engine.classic.core.modules.output.table.html.AllItemsHtmlPrinter;
import org.pentaho.reporting.libraries.repository.ContentIOException;
import org.pentaho.reporting.libraries.resourceloader.ResourceException;
import org.pentaho.reporting.libraries.resourceloader.ResourceManager;
import org.pentaho.reporting.platform.plugin.MicroPlatformFactory;
import org.pentaho.reporting.platform.plugin.async.AsyncExecutionStatus;
import org.pentaho.reporting.platform.plugin.async.IAsyncReportListener;
import org.pentaho.reporting.platform.plugin.async.ReportListenerThreadHolder;
import org.pentaho.reporting.platform.plugin.async.TestListener;
import org.pentaho.reporting.platform.plugin.cache.IPluginCacheManager;
import org.pentaho.reporting.platform.plugin.cache.IReportContent;
import org.pentaho.reporting.platform.plugin.cache.IReportContentCache;
import org.pentaho.reporting.platform.plugin.cache.PluginCacheManagerImpl;
import org.pentaho.test.platform.engine.core.MicroPlatform;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.core.classloader.annotations.PowerMockIgnore;
import org.powermock.modules.junit4.PowerMockRunner;
import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Random;
import java.util.UUID;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.mockito.Matchers.anyInt;
import static org.mockito.Matchers.anyObject;
import static org.mockito.Matchers.anyString;
import static org.mockito.Mockito.CALLS_REAL_METHODS;
import static org.mockito.Mockito.any;
import static org.mockito.Mockito.atLeastOnce;
import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@RunWith( PowerMockRunner.class )
@PrepareForTest( CachingPageableHTMLOutput.class )
@PowerMockIgnore( "javax.swing.*" )
public class PageableHTMLOutputTest {
PageableHTMLOutput pageableHTMLOutput;
private IAsyncReportListener listener;
@Before public void setUp() {
pageableHTMLOutput = new PageableHTMLOutput();
listener = mock( IAsyncReportListener.class );
ReportListenerThreadHolder.setListener( listener );
}
@After public void tearDown() {
ReportListenerThreadHolder.clear();
listener = null;
}
@Test public void testGetReportLock() throws Exception {
Assert.assertEquals( pageableHTMLOutput, pageableHTMLOutput.getReportLock() );
}
@Test public void testSetContentHandlerPattern() throws Exception {
Assert.assertNull( pageableHTMLOutput.getContentHandlerPattern() );
pageableHTMLOutput.setContentHandlerPattern( "pattern" ); //$NON-NLS-1$
Assert.assertEquals( "pattern", pageableHTMLOutput.getContentHandlerPattern() ); //$NON-NLS-1$
}
@Test public void testSetProxyOutputStream() throws Exception {
Assert.assertNull( pageableHTMLOutput.getProxyOutputStream() );
ProxyOutputStream mockStream = mock( ProxyOutputStream.class );
pageableHTMLOutput.setProxyOutputStream( mockStream );
Assert.assertEquals( mockStream, pageableHTMLOutput.getProxyOutputStream() );
}
@Test public void testSetPrinter() throws Exception {
Assert.assertNull( pageableHTMLOutput.getPrinter() );
AllItemsHtmlPrinter mockPrinter = mock( AllItemsHtmlPrinter.class );
pageableHTMLOutput.setPrinter( mockPrinter );
Assert.assertEquals( mockPrinter, pageableHTMLOutput.getPrinter() );
}
@Test public void testSetReportProcessor() throws Exception {
Assert.assertNull( pageableHTMLOutput.getReportProcessor() );
PageableReportProcessor mockProcessor = mock( PageableReportProcessor.class );
pageableHTMLOutput.setReportProcessor( mockProcessor );
Assert.assertEquals( mockProcessor, pageableHTMLOutput.getReportProcessor() );
}
@Test public void testSupportsPagination() throws Exception {
Assert.assertEquals( true, pageableHTMLOutput.supportsPagination() );
}
@Test public void testPaginate() throws Exception {
PageableHTMLOutput output = mock( PageableHTMLOutput.class, CALLS_REAL_METHODS );
PageableReportProcessor processor = mock( PageableReportProcessor.class );
doNothing().when( output ).reinitOutputTarget();
doReturn( true ).when( processor ).isPaginated();
MasterReport report = mock( MasterReport.class );
AllItemsHtmlPrinter printer = mock( AllItemsHtmlPrinter.class );
doNothing().when( printer ).setContentWriter( null, null );
doNothing().when( printer ).setDataWriter( null, null );
output.setReportProcessor( processor );
output.setPrinter( printer );
Assert.assertEquals( 0, output.paginate( report, 0 ) );
doReturn( false ).when( processor ).isPaginated();
output.setReportProcessor( processor );
Assert.assertEquals( 0, output.paginate( report, 0 ) );
}
@Test
public void testGenerateListener() throws Exception {
ClassicEngineBoot.getInstance().start();
pageableHTMLOutput.generate( new MasterReport(), 1, new ByteArrayOutputStream(), 1 );
verify( listener, times( 1 ) ).reportProcessingStarted( any( ReportProgressEvent.class ) );
verify( listener, times( 1 ) ).reportProcessingFinished( any( ReportProgressEvent.class ) );
verify( listener, atLeastOnce() ).reportProcessingUpdate( any( ReportProgressEvent.class ) );
}
@Test
public void testGenerate() throws Exception {
ClassicEngineBoot.getInstance().start();
ReportListenerThreadHolder.clear();
pageableHTMLOutput.generate( new MasterReport(), 1, new ByteArrayOutputStream(), 1 );
verify( listener, times( 0 ) ).reportProcessingStarted( any( ReportProgressEvent.class ) );
verify( listener, times( 0 ) ).reportProcessingFinished( any( ReportProgressEvent.class ) );
verify( listener, times( 0 ) ).reportProcessingUpdate( any( ReportProgressEvent.class ) );
}
@Test
public void testGenerateListenerFlow() throws Exception {
ClassicEngineBoot.getInstance().start();
pageableHTMLOutput.generate( new MasterReport(), -1, new ByteArrayOutputStream(), 1 );
verify( listener, times( 1 ) ).reportProcessingStarted( any( ReportProgressEvent.class ) );
verify( listener, times( 1 ) ).reportProcessingFinished( any( ReportProgressEvent.class ) );
verify( listener, atLeastOnce() ).reportProcessingUpdate( any( ReportProgressEvent.class ) );
}
@Test
public void testGenerateFlow() throws Exception {
ClassicEngineBoot.getInstance().start();
ReportListenerThreadHolder.clear();
pageableHTMLOutput.generate( new MasterReport(), -1, new ByteArrayOutputStream(), 1 );
verify( listener, times( 0 ) ).reportProcessingStarted( any( ReportProgressEvent.class ) );
verify( listener, times( 0 ) ).reportProcessingFinished( any( ReportProgressEvent.class ) );
verify( listener, times( 0 ) ).reportProcessingUpdate( any( ReportProgressEvent.class ) );
}
@Ignore
@Test
public void testPageNotInCacheSchedule() throws PlatformInitializationException, ContentIOException,
ReportProcessingException, IOException,
ResourceException {
ClassicEngineBoot.getInstance().start();
MicroPlatform microPlatform = MicroPlatformFactory.create();
try {
microPlatform.define( ReportOutputHandlerFactory.class, FastExportReportOutputHandlerFactory.class );
final IReportContentCache mockCache = mock( IReportContentCache.class );
final IReportContent iReportContent = mock( IReportContent.class );
when( iReportContent.getPageData( 3 ) ).thenReturn( null );
final String key = "test";
when( mockCache.get( key ) ).thenReturn( iReportContent );
final IPluginCacheManager iPluginCacheManager =
new PluginCacheManagerImpl( mockCache );
microPlatform.define( "IPluginCacheManager", iPluginCacheManager );
microPlatform.start();
final IPentahoSession session = new StandaloneSession();
PentahoSessionHolder.setSession( session );
final CachingPageableHTMLOutput cachingPageableHTMLOutput = spy( new CachingPageableHTMLOutput() );
final ResourceManager mgr = new ResourceManager();
final File src = new File( "target/test/resource/solution/test/reporting/report1.prpt" );
final MasterReport r = (MasterReport) mgr.createDirectly( src, MasterReport.class ).getResource();
r.setContentCacheKey( key );
final TestListener listener = new TestListener( "1", UUID.randomUUID(), "" );
listener.setStatus( AsyncExecutionStatus.SCHEDULED );
ReportListenerThreadHolder.setListener( listener );
try ( final java.io.ByteArrayOutputStream outputStream =
new java.io.ByteArrayOutputStream() ) { //$NON-NLS-1$ //$NON-NLS-2$
cachingPageableHTMLOutput.generate( r, 3, outputStream, 1 );
final String content = new String( outputStream.toByteArray(), "UTF-8" );
assertTrue( content.contains( "Scheduled paginated HTML report" ) );
}
verify( cachingPageableHTMLOutput, times( 1 ) ).regenerateCache( r, 1, key, 3 );
} finally {
ReportListenerThreadHolder.clear();
microPlatform.stop();
microPlatform = null;
}
}
@Ignore
@Test
public void testPageNotInCache() throws PlatformInitializationException, ContentIOException,
ReportProcessingException, IOException,
ResourceException {
ClassicEngineBoot.getInstance().start();
MicroPlatform microPlatform = MicroPlatformFactory.create();
try {
microPlatform.define( ReportOutputHandlerFactory.class, FastExportReportOutputHandlerFactory.class );
final IReportContentCache mockCache = mock( IReportContentCache.class );
final IReportContent iReportContent = mock( IReportContent.class );
when( iReportContent.getPageData( 3 ) ).thenReturn( null );
final String key = "test";
when( mockCache.get( key ) ).thenReturn( iReportContent );
final IPluginCacheManager iPluginCacheManager =
new PluginCacheManagerImpl( mockCache );
microPlatform.define( "IPluginCacheManager", iPluginCacheManager );
microPlatform.start();
final IPentahoSession session = new StandaloneSession();
PentahoSessionHolder.setSession( session );
final CachingPageableHTMLOutput cachingPageableHTMLOutput = spy( new CachingPageableHTMLOutput() );
final ResourceManager mgr = new ResourceManager();
final File src = new File( "target/test/resource/solution/test/reporting/report1.prpt" );
final MasterReport r = (MasterReport) mgr.createDirectly( src, MasterReport.class ).getResource();
r.setContentCacheKey( key );
cachingPageableHTMLOutput.generate( r, 3, mock( OutputStream.class ), 1 );
verify( cachingPageableHTMLOutput, times( 1 ) ).regenerateCache( r, 1, key, 3 );
} finally {
microPlatform.stop();
microPlatform = null;
}
}
@Test
public void testPaginateInCache() throws PlatformInitializationException, ContentIOException,
ReportProcessingException, IOException,
ResourceException {
ClassicEngineBoot.getInstance().start();
MicroPlatform microPlatform = MicroPlatformFactory.create();
try {
microPlatform.define( ReportOutputHandlerFactory.class, FastExportReportOutputHandlerFactory.class );
final IReportContentCache mockCache = mock( IReportContentCache.class );
final IReportContent iReportContent = mock( IReportContent.class );
final int value = new Random().nextInt();
when( iReportContent.getPageCount() ).thenReturn( value );
final String key = "test";
when( mockCache.get( key ) ).thenReturn( iReportContent );
final IPluginCacheManager iPluginCacheManager =
new PluginCacheManagerImpl( mockCache );
microPlatform.define( "IPluginCacheManager", iPluginCacheManager );
microPlatform.start();
final IPentahoSession session = new StandaloneSession();
PentahoSessionHolder.setSession( session );
final CachingPageableHTMLOutput cachingPageableHTMLOutput = spy( new CachingPageableHTMLOutput() );
final ResourceManager mgr = new ResourceManager();
final File src = new File( "target/test/resource/solution/test/reporting/report.prpt" );
final MasterReport r = (MasterReport) mgr.createDirectly( src, MasterReport.class ).getResource();
r.setContentCacheKey( key );
assertEquals( value, cachingPageableHTMLOutput.paginate( r, 1 ) );
} finally {
microPlatform.stop();
microPlatform = null;
}
}
@Test
public void testNotCaching() throws ContentIOException, ReportProcessingException, IOException {
final CachingPageableHTMLOutput mock = mock( CachingPageableHTMLOutput.class );
when( mock.generate( null, -1, null, 1 ) ).thenCallRealMethod();
mock.generate( null, -1, null, 1 );
verify( mock, times( 1 ) ).generateNonCaching( null, -1, null, 1 );
}
@Ignore
@Test
public void testIsQueryLimitReached() throws Exception {
ClassicEngineBoot.getInstance().start();
MicroPlatform microPlatform = MicroPlatformFactory.create();
try {
microPlatform.define( ReportOutputHandlerFactory.class, FastExportReportOutputHandlerFactory.class );
final IReportContentCache mockCache = mock( IReportContentCache.class );
final IReportContent iReportContent = mock( IReportContent.class );
final int value = new Random().nextInt();
when( iReportContent.getPageCount() ).thenReturn( value );
final String key = "test";
when( mockCache.get( key ) ).thenReturn( iReportContent );
final IPluginCacheManager iPluginCacheManager =
new PluginCacheManagerImpl( mockCache );
microPlatform.define( "IPluginCacheManager", iPluginCacheManager );
microPlatform.start();
final IPentahoSession session = new StandaloneSession();
PentahoSessionHolder.setSession( session );
final TestListener listener = new TestListener( "1", UUID.randomUUID(), "" );
ReportListenerThreadHolder.setListener( listener );
final ResourceManager mgr = new ResourceManager();
final File src = new File( "target/test/resource/solution/test/reporting/report.prpt" );
final MasterReport masterReport = (MasterReport) mgr.createDirectly( src, MasterReport.class ).getResource();
masterReport.setQueryLimit( 50 );
pageableHTMLOutput.generate( masterReport, 1, new ByteArrayOutputStream(), 1 );
assertEquals( listener.isQueryLimitReached(), true );
} finally {
microPlatform.stop();
microPlatform = null;
}
}
@Test
public void testRegenerateCacheThrowExceptionForNullMasterReport() throws Exception {
// BACKLOG-11306
boolean thrown = false;
final CachingPageableHTMLOutput cachingPageableHTMLOutput = PowerMockito.mock( CachingPageableHTMLOutput.class );
final IReportContent iReportContent = PowerMockito.mock( IReportContent.class );
final MasterReport masterReport = PowerMockito.mock( MasterReport.class );
final ReportListenerThreadHolder reportListenerThreadHolder = PowerMockito.mock( ReportListenerThreadHolder.class );
reportListenerThreadHolder.setListener( null );
PowerMockito.when( cachingPageableHTMLOutput, "produceCacheablePages", null, 1, "key", 0 ).thenReturn( iReportContent );
PowerMockito.when( cachingPageableHTMLOutput.regenerateCache( anyObject(), anyInt(), anyString(), anyInt() ) ).thenCallRealMethod();
try {
cachingPageableHTMLOutput.regenerateCache( null, 1, "key", 0 );
} catch ( NullPointerException e ) {
thrown = true;
}
assertTrue( thrown );
thrown = false;
try {
cachingPageableHTMLOutput.regenerateCache( masterReport, 1, "key", 0 );
} catch ( NullPointerException e ) {
thrown = true;
}
assertFalse( thrown );
}
@Test
public void testGenerateWErrorCache() throws Exception {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
final String key = "test";
MasterReport mockMasterReport = mock( MasterReport.class );
CachingPageableHTMLOutput mockCachingPageableHTMLOutput = mock( CachingPageableHTMLOutput.class );
ReportListenerThreadHolder.clear();
doReturn( key ).when( mockMasterReport ).getContentCacheKey();
doReturn( null ).when( mockCachingPageableHTMLOutput ).getCachedContent( key );
doReturn( null ).when( mockCachingPageableHTMLOutput ).regenerateCache( mockMasterReport, 1, key, 1 );
when( mockCachingPageableHTMLOutput.generate( mockMasterReport, 1, baos, 1 ) ).thenCallRealMethod();
int returnedValue = mockCachingPageableHTMLOutput.generate( mockMasterReport, 1, baos, 1 );
verify( mockCachingPageableHTMLOutput ).regenerateCache( mockMasterReport, 1, key, 1 );
assertTrue( returnedValue == -1 );
}
}