001package org.apache.maven.plugins.enforcer; 002 003/* 004 * Licensed to the Apache Software Foundation (ASF) under one 005 * or more contributor license agreements. See the NOTICE file 006 * distributed with this work for additional information 007 * regarding copyright ownership. The ASF licenses this file 008 * to you under the Apache License, Version 2.0 (the 009 * "License"); you may not use this file except in compliance 010 * with the License. You may obtain a copy of the License at 011 * 012 * http://www.apache.org/licenses/LICENSE-2.0 013 * 014 * Unless required by applicable law or agreed to in writing, 015 * software distributed under the License is distributed on an 016 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 017 * KIND, either express or implied. See the License for the 018 * specific language governing permissions and limitations 019 * under the License. 020 */ 021 022import static org.junit.jupiter.api.Assertions.*; 023 024import org.apache.maven.enforcer.rule.api.EnforcerRule; 025import org.apache.maven.enforcer.rule.api.EnforcerRuleException; 026import org.apache.maven.enforcer.rule.api.EnforcerRuleHelper; 027import org.apache.maven.plugin.MojoExecutionException; 028import org.apache.maven.plugin.logging.Log; 029import org.junit.jupiter.api.Test; 030import org.junit.jupiter.api.extension.ExtendWith; 031import org.mockito.InjectMocks; 032import org.mockito.Mockito; 033import org.mockito.junit.jupiter.MockitoExtension; 034import org.mockito.junit.jupiter.MockitoSettings; 035import org.mockito.quality.Strictness; 036 037/** 038 * Exhaustively check the enforcer mojo. 039 * 040 * @author <a href="mailto:brianf@apache.org">Brian Fox</a> 041 */ 042@ExtendWith( MockitoExtension.class ) 043@MockitoSettings( strictness = Strictness.LENIENT ) 044public class TestEnforceMojo 045{ 046 047 @InjectMocks 048 EnforceMojo mojo; 049 050 @Test 051 public void testEnforceMojo() 052 throws MojoExecutionException 053 { 054 setupBasics( false ); 055 056 try 057 { 058 mojo.execute(); 059 fail( "Expected a Mojo Execution Exception." ); 060 } 061 catch ( MojoExecutionException e ) 062 { 063 System.out.println( "Caught Expected Exception:" + e.getLocalizedMessage() ); 064 } 065 066 EnforcerRule[] rules = new EnforcerRule[10]; 067 rules[0] = new MockEnforcerRule( true ); 068 rules[1] = new MockEnforcerRule( true ); 069 mojo.setRules( rules ); 070 071 mojo.execute(); 072 073 try 074 { 075 mojo.setFailFast( false ); 076 mojo.setFail( true ); 077 mojo.execute(); 078 fail( "Expected a Mojo Execution Exception." ); 079 } 080 catch ( MojoExecutionException e ) 081 { 082 System.out.println( "Caught Expected Exception:" + e.getLocalizedMessage() ); 083 } 084 085 try 086 { 087 mojo.setFailFast( true ); 088 mojo.setFail( true ); 089 mojo.execute(); 090 fail( "Expected a Mojo Execution Exception." ); 091 } 092 catch ( MojoExecutionException e ) 093 { 094 System.out.println( "Caught Expected Exception:" + e.getLocalizedMessage() ); 095 } 096 097 ( (MockEnforcerRule) rules[0] ).setFailRule( false ); 098 ( (MockEnforcerRule) rules[1] ).setFailRule( false ); 099 mojo.execute(); 100 101 } 102 103 @Test 104 public void testCaching() 105 throws MojoExecutionException 106 { 107 setupBasics( true ); 108 109 MockEnforcerRule[] rules = new MockEnforcerRule[10]; 110 111 // check that basic caching works. 112 rules[0] = new MockEnforcerRule( false, "", true, true ); 113 rules[1] = new MockEnforcerRule( false, "", true, true ); 114 mojo.setRules( rules ); 115 116 EnforceMojo.cache.clear(); 117 mojo.execute(); 118 119 assertTrue( rules[0].executed, "Expected this rule to be executed." ); 120 assertFalse( rules[1].executed, "Expected this rule not to be executed." ); 121 122 // check that skip caching works. 123 rules[0] = new MockEnforcerRule( false, "", true, true ); 124 rules[1] = new MockEnforcerRule( false, "", true, true ); 125 mojo.setRules( rules ); 126 127 EnforceMojo.cache.clear(); 128 mojo.ignoreCache = true; 129 mojo.execute(); 130 131 assertTrue( rules[0].executed, "Expected this rule to be executed." ); 132 assertTrue( rules[1].executed, "Expected this rule to be executed." ); 133 134 mojo.ignoreCache = false; 135 136 // check that different ids are compared. 137 rules[0] = new MockEnforcerRule( false, "1", true, true ); 138 rules[1] = new MockEnforcerRule( false, "2", true, true ); 139 rules[2] = new MockEnforcerRule( false, "2", true, true ); 140 mojo.setRules( rules ); 141 142 EnforceMojo.cache.clear(); 143 mojo.execute(); 144 145 assertTrue( rules[0].executed, "Expected this rule to be executed." ); 146 assertTrue( rules[1].executed, "Expected this rule to be executed." ); 147 assertFalse( rules[2].executed, "Expected this rule not to be executed." ); 148 149 // check that future overrides are working 150 rules[0] = new MockEnforcerRule( false, "1", true, true ); 151 rules[1] = new MockEnforcerRule( false, "1", false, true ); 152 rules[2] = null; 153 mojo.setRules( rules ); 154 155 EnforceMojo.cache.clear(); 156 mojo.execute(); 157 158 assertTrue( rules[0].executed, "Expected this rule to be executed." ); 159 assertTrue( rules[1].executed, "Expected this rule to be executed." ); 160 161 // check that future isResultValid is used 162 rules[0] = new MockEnforcerRule( false, "1", true, true ); 163 rules[1] = new MockEnforcerRule( false, "1", true, false ); 164 rules[2] = null; 165 mojo.setRules( rules ); 166 167 EnforceMojo.cache.clear(); 168 mojo.execute(); 169 170 assertTrue( rules[0].executed, "Expected this rule to be executed." ); 171 assertTrue( rules[1].executed, "Expected this rule to be executed." ); 172 173 } 174 175 @Test 176 public void testCachePersistence1() 177 throws MojoExecutionException 178 { 179 setupBasics( true ); 180 181 MockEnforcerRule[] rules = new MockEnforcerRule[10]; 182 183 // check that basic caching works. 184 rules[0] = new MockEnforcerRule( false, "", true, true ); 185 rules[1] = new MockEnforcerRule( false, "", true, true ); 186 mojo.setRules( rules ); 187 188 EnforceMojo.cache.clear(); 189 mojo.execute(); 190 191 assertTrue( rules[0].executed, "Expected this rule to be executed." ); 192 assertFalse( rules[1].executed, "Expected this rule not to be executed." ); 193 194 } 195 196 @Test 197 public void testCachePersistence2() 198 throws MojoExecutionException 199 { 200 setupBasics( true ); 201 202 MockEnforcerRule[] rules = new MockEnforcerRule[10]; 203 204 // check that basic caching works. 205 rules[0] = new MockEnforcerRule( false, "", true, true ); 206 rules[1] = new MockEnforcerRule( false, "", true, true ); 207 mojo.setRules( rules ); 208 209 mojo.execute(); 210 211 assertFalse( rules[0].executed, "Expected this rule not to be executed." ); 212 assertFalse( rules[1].executed, "Expected this rule not to be executed." ); 213 214 } 215 216 @Test 217 public void testCachePersistence3() 218 throws MojoExecutionException 219 { 220 System.gc(); 221 222 try 223 { 224 Thread.sleep( 1000 ); 225 } 226 catch ( InterruptedException e ) 227 { 228 } 229 230 setupBasics( true ); 231 232 MockEnforcerRule[] rules = new MockEnforcerRule[10]; 233 234 // check that basic caching works. 235 rules[0] = new MockEnforcerRule( false, "", true, true ); 236 rules[1] = new MockEnforcerRule( false, "", true, true ); 237 mojo.setRules( rules ); 238 239 mojo.execute(); 240 241 assertFalse( rules[0].executed, "Expected this rule not to be executed." ); 242 assertFalse( rules[1].executed, "Expected this rule not to be executed." ); 243 244 } 245 246 @Test 247 public void testLoggingOnEnforcerRuleExceptionWithMessage() 248 throws MojoExecutionException, EnforcerRuleException 249 { 250 // fail=false because this is out of scope here (also allows for cleaner test code without catch block) 251 setupBasics( false ); 252 253 // the regular kind of EnforcerRuleException: 254 EnforcerRuleException ruleException = new EnforcerRuleException( "testMessage" ); 255 256 EnforcerRule ruleMock = Mockito.mock( EnforcerRule.class ); 257 Mockito.doThrow( ruleException ).when( ruleMock ).execute( Mockito.any( EnforcerRuleHelper.class ) ); 258 259 mojo.setRules( new EnforcerRule[] { ruleMock } ); 260 261 Log logSpy = setupLogSpy(); 262 263 mojo.execute(); 264 265 Mockito.verify( logSpy ).debug( Mockito.anyString(), Mockito.same( ruleException ) ); 266 267 Mockito.verify( logSpy, Mockito.never() ).warn( Mockito.anyString(), Mockito.any( Throwable.class ) ); 268 269 Mockito.verify( logSpy ).warn( Mockito.matches( ".* failed with message:" + System.lineSeparator() 270 + ruleException.getMessage() ) ); 271 } 272 273 @Test 274 public void testLoggingOnEnforcerRuleExceptionWithoutMessage() 275 throws MojoExecutionException, EnforcerRuleException 276 { 277 // fail=false because this is out of scope here (also allows for cleaner test code without catch block) 278 setupBasics( false ); 279 280 // emulate behaviour of various rules that just catch Exception and wrap into EnforcerRuleException: 281 NullPointerException npe = new NullPointerException(); 282 EnforcerRuleException enforcerRuleException = new EnforcerRuleException( npe.getLocalizedMessage(), npe ); 283 284 EnforcerRule ruleMock = Mockito.mock( EnforcerRule.class ); 285 Mockito.doThrow( enforcerRuleException ).when( ruleMock ).execute( Mockito.any( EnforcerRuleHelper.class ) ); 286 287 mojo.setRules( new EnforcerRule[] { ruleMock } ); 288 289 Log logSpy = setupLogSpy(); 290 291 mojo.execute(); 292 293 Mockito.verify( logSpy ).warn( Mockito.contains( "failed without a message" ), 294 Mockito.same( enforcerRuleException ) ); 295 296 Mockito.verify( logSpy ).warn( Mockito.matches( ".* failed with message:" + System.lineSeparator() + "null" ) ); 297 } 298 299 private void setupBasics( boolean fail ) 300 { 301 mojo.setFail( fail ); 302 mojo.setSession( EnforcerTestUtils.getMavenSession() ); 303 mojo.setProject( new MockProject() ); 304 } 305 306 private Log setupLogSpy() 307 { 308 Log spy = Mockito.spy( mojo.getLog() ); 309 mojo.setLog( spy ); 310 return spy; 311 } 312}