/* * This program is free software; you can redistribute it and/or modify it under the * terms of the GNU General Public License, version 2 as published by the Free Software * Foundation. * * You should have received a copy of the GNU General Public License along with this * program; if not, you can obtain a copy at http://www.gnu.org/licenses/gpl-2.0.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 General Public License for more details. * * * Copyright 2017 Pentaho Corporation. All rights reserved. */ package org.pentaho.platform.engine.services.runtime; import mockit.Mock; import mockit.MockUp; import mockit.integration.junit4.JMockit; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.invocation.InvocationOnMock; import org.mockito.stubbing.Answer; import org.pentaho.di.core.util.Assert; import org.pentaho.platform.api.engine.IApplicationContext; import org.pentaho.platform.api.engine.IParameterProvider; import org.pentaho.platform.api.engine.IPentahoSession; import org.pentaho.platform.api.engine.IPentahoUrlFactory; import org.pentaho.platform.api.engine.IRuntimeContext; import org.pentaho.platform.api.engine.ISolutionEngine; import org.pentaho.platform.api.repository.IRuntimeElement; import org.pentaho.platform.api.repository.IRuntimeRepository; import org.pentaho.platform.engine.core.system.PentahoSystem; import org.pentaho.platform.engine.core.system.StandaloneApplicationContext; import org.pentaho.platform.engine.core.system.StandaloneSession; import org.pentaho.platform.engine.security.SecurityParameterProvider; import org.pentaho.platform.util.JVMParameterProvider; import org.pentaho.platform.util.UUIDUtil; import org.pentaho.platform.util.web.SimpleUrlFactory; import java.math.BigDecimal; import java.util.ArrayList; import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Map; import static org.mockito.Matchers.anyBoolean; import static org.mockito.Matchers.anyString; import static org.mockito.Mockito.*; @RunWith( JMockit.class ) public class RuntimeContextTest { IRuntimeRepository mockedRuntimeRepository; ISolutionEngine mockedSolutionEngine; MockUp<PentahoSystem> mockedPentahoSystem; private final IPentahoUrlFactory urlFactory = new SimpleUrlFactory( "" ); private final IPentahoSession session = new StandaloneSession( "system" ); private IRuntimeContext runtimeCtx; @Before public void before() { mockedRuntimeRepository = mock( IRuntimeRepository.class ); mockedSolutionEngine = mock( ISolutionEngine.class ); mockedPentahoSystem = new MockUp<PentahoSystem>() { @Mock public <T> T get( Class<T> type, IPentahoSession session ) { if ( type == IRuntimeRepository.class ) { return (T) mockedRuntimeRepository; } else if ( type == ISolutionEngine.class ) { return (T) mockedSolutionEngine; } throw new IllegalStateException( "Unsupported type: " + type.getSimpleName() ); } @Mock public void setApplicationContext( final IApplicationContext applicationContext ) { } @Mock public IApplicationContext getApplicationContext() { final String solutionPath = "."; final String applicationPath = ""; return new StandaloneApplicationContext( solutionPath, applicationPath ); } }; runtimeCtx = new RuntimeContext( "id", mockedSolutionEngine, "solutionName", makeRuntimeData( session ), session, null, "processId", urlFactory, makeParameterProviders( session ), new ArrayList<String>(), null ); } /** * Sanity test the basics - createNewInstance() works passing all combinations of arguments. * * @throws Exception */ @Test public void testCreateNewInstanceBasicSanity() throws Exception { when( mockedRuntimeRepository.newRuntimeElement( anyString(), anyString(), anyBoolean() ) ).thenAnswer( new Answer<IRuntimeElement>() { @Override public IRuntimeElement answer( final InvocationOnMock invocation ) throws Throwable { Object[] args = invocation.getArguments(); final String parentId = (String) args[0]; final String parentType = (String) args[1]; return new SimpleRuntimeElement( UUIDUtil.getUUIDAsString(), parentId, parentType, "sol1" ); } } ); final boolean persisted = true; final boolean notPersisted = false; final boolean forceImmediateWrite = true; final boolean dontForceImmediateWrite = false; final Map<String, String> noParams = new HashMap<>( ); Assert.assertNotNull( runtimeCtx.createNewInstance( persisted ) ); Assert.assertNotNull( runtimeCtx.createNewInstance( notPersisted ) ); Assert.assertNotNull( runtimeCtx.createNewInstance( persisted, noParams ) ); Assert.assertNotNull( runtimeCtx.createNewInstance( notPersisted, noParams ) ); Assert.assertNotNull( runtimeCtx.createNewInstance( persisted, noParams, forceImmediateWrite ) ); Assert.assertNotNull( runtimeCtx.createNewInstance( notPersisted, noParams, dontForceImmediateWrite ) ); verify( mockedRuntimeRepository, times( 6 ) ).newRuntimeElement( anyString(), anyString(), anyBoolean() ); verify( mockedRuntimeRepository, times( 3 ) ).newRuntimeElement( anyString(), anyString(), eq( true ) ); verify( mockedRuntimeRepository, times( 3 ) ).newRuntimeElement( anyString(), anyString(), eq( false ) ); } /** * Tests that params are passed and saved correctly to the underlying runtime element. * * @throws Exception */ @Test public void testCreateNewInstanceWithParams() throws Exception { final IRuntimeElement elem = new SimpleRuntimeElement( UUIDUtil.getUUIDAsString(), "parentId", "parentType", "sol1" ); when( mockedRuntimeRepository.newRuntimeElement( anyString(), anyString(), anyBoolean() ) ).thenAnswer( new Answer<IRuntimeElement>() { @Override public IRuntimeElement answer( final InvocationOnMock invocation ) throws Throwable { Object[] args = invocation.getArguments(); final String parentId = (String) args[0]; final String parentType = (String) args[1]; return elem; } } ); final boolean persisted = true; final boolean forceImmediateWrite = true; final List<Integer> list = new ArrayList<>(); final Map<String, Object> params = new HashMap<>(); final Date now = new Date(); final BigDecimal three = new BigDecimal( 3.0d ); params.put( "One", "One" ); params.put( "Two", new Long( 2 ) ); params.put( "Three", three ); params.put( "Date", now ); list.add( 1 ); list.add( 2 ); list.add( 3 ); params.put( "List", list ); runtimeCtx.createNewInstance( persisted, params, forceImmediateWrite ); Assert.assertTrue( elem.getStringProperty( "One" ).equals( "One" ) ); Assert.assertTrue( elem.getLongProperty( "Two", 0 ) == 2 ); Assert.assertTrue( elem.getBigDecimalProperty( "Three" ).equals( three ) ); Assert.assertTrue( elem.getDateProperty( "Date" ).equals( now ) ); Assert.assertNotNullOrEmpty( elem.getListProperty( "List" ) ); } /** * It seems that status and error level are one and alike by design. * Enforce a test on this. In addition achieve code coverage on these. * * @throws Exception */ @Test public void testErrorLevel() throws Exception { final RuntimeContext rctx = (RuntimeContext) runtimeCtx; Assert.assertTrue( rctx.getErrorLevel() == rctx.getStatus() ); } @Test public void testPromptNow() throws Exception { runtimeCtx.setPromptStatus( IRuntimeContext.PROMPT_NO ); Assert.assertFalse( runtimeCtx.isPromptPending() ); runtimeCtx.promptNow(); Assert.assertTrue( runtimeCtx.isPromptPending() ); } @Test public void testPromptNeeded() throws Exception { runtimeCtx.setPromptStatus( IRuntimeContext.PROMPT_NO ); Assert.assertFalse( runtimeCtx.isPromptPending() ); runtimeCtx.promptNeeded(); Assert.assertTrue( runtimeCtx.isPromptPending() ); } @Test public void testGetUrlFactory() throws Exception { Assert.assertNotNull( runtimeCtx.getUrlFactory() ); Assert.assertTrue( runtimeCtx.getUrlFactory() == urlFactory ); } private Map<String, IParameterProvider> makeParameterProviders( final IPentahoSession session ) { final Map<String, IParameterProvider> res = new HashMap<>(); res.put( "jvm", new JVMParameterProvider() ); res.put( SecurityParameterProvider.SCOPE_SECURITY, new SecurityParameterProvider( session ) ); return res; } private IRuntimeElement makeRuntimeData( final IPentahoSession session ) { return new SimpleRuntimeElement( UUIDUtil.getUUIDAsString(), session.getId( ), IParameterProvider.SCOPE_SESSION ); } }