blob: f13419ada3d0486d32126fef97eaad9a2548b9f0 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package groovy.util.logging
import groovy.test.GroovyTestCase
import java.lang.reflect.Field
import java.lang.reflect.Modifier
import java.util.logging.*
import groovy.mock.interceptor.MockFor
import org.codehaus.groovy.control.MultipleCompilationErrorsException
/**
* Test to make sure the @Log annotation is working correctly.
*/
class LogTest extends GroovyTestCase {
void testPrivateFinalStaticLogFieldAppears() {
Class clazz = new GroovyClassLoader().parseClass("""
@groovy.util.logging.Log
class MyClass {
} """)
assert clazz.declaredFields.find { Field field ->
field.name == "log" &&
Modifier.isPrivate(field.getModifiers()) &&
Modifier.isStatic(field.getModifiers()) &&
Modifier.isTransient(field.getModifiers()) &&
Modifier.isFinal(field.getModifiers())
}
}
void testPrivateFinalStaticNamedLogFieldAppears() {
Class clazz = new GroovyClassLoader().parseClass("""
@groovy.util.logging.Log('logger')
class MyClass {
} """)
assert clazz.declaredFields.find { Field field ->
field.name == "logger" &&
Modifier.isPrivate(field.getModifiers()) &&
Modifier.isStatic(field.getModifiers()) &&
Modifier.isTransient(field.getModifiers()) &&
Modifier.isFinal(field.getModifiers())
}
}
void testExplicitPrivateFinalStaticLogFieldAppears() {
Class clazz = new GroovyClassLoader().parseClass('''
import static groovy.transform.options.Visibility.*
@groovy.transform.VisibilityOptions(value = PRIVATE)
@groovy.util.logging.Log
class MyClass {
} ''')
assert clazz.declaredFields.find { Field field ->
field.name == "log" &&
Modifier.isPrivate(field.getModifiers()) &&
Modifier.isStatic(field.getModifiers()) &&
Modifier.isTransient(field.getModifiers()) &&
Modifier.isFinal(field.getModifiers())
}
}
void testPackagePrivateFinalStaticLogFieldAppears() {
Class clazz = new GroovyClassLoader().parseClass('''
import static groovy.transform.options.Visibility.*
@groovy.transform.VisibilityOptions(value = PACKAGE_PRIVATE)
@groovy.util.logging.Log
class MyClass {
} ''')
assert clazz.declaredFields.find { Field field ->
field.name == "log" &&
!Modifier.isPrivate(field.getModifiers()) &&
!Modifier.isProtected(field.getModifiers()) &&
!Modifier.isPublic(field.getModifiers()) &&
Modifier.isStatic(field.getModifiers()) &&
Modifier.isTransient(field.getModifiers()) &&
Modifier.isFinal(field.getModifiers())
}
}
void testProtectedFinalStaticLogFieldAppears() {
Class clazz = new GroovyClassLoader().parseClass('''
import static groovy.transform.options.Visibility.*
@groovy.transform.VisibilityOptions(value = PROTECTED)
@groovy.util.logging.Log
class MyClass {
} ''')
assert clazz.declaredFields.find { Field field ->
field.name == "log" &&
Modifier.isProtected(field.getModifiers()) &&
Modifier.isStatic(field.getModifiers()) &&
Modifier.isTransient(field.getModifiers()) &&
Modifier.isFinal(field.getModifiers())
}
}
void testPublicFinalStaticLogFieldAppears() {
Class clazz = new GroovyClassLoader().parseClass('''
import static groovy.transform.options.Visibility.*
@groovy.transform.VisibilityOptions(value = PUBLIC)
@groovy.util.logging.Log
class MyClass {
} ''')
assert clazz.declaredFields.find { Field field ->
field.name == "log" &&
Modifier.isPublic(field.getModifiers()) &&
Modifier.isStatic(field.getModifiers()) &&
Modifier.isTransient(field.getModifiers()) &&
Modifier.isFinal(field.getModifiers())
}
}
void testClassAlreadyHasLogField() {
shouldFail {
Class clazz = new GroovyClassLoader().parseClass("""
@groovy.util.logging.Log
class MyClass {
String log
} """)
assert clazz.newInstance()
}
}
void testClassAlreadyHasNamedLogField() {
shouldFail {
Class clazz = new GroovyClassLoader().parseClass("""
@groovy.util.logging.Log('logger')
class MyClass {
String logger
} """)
assert clazz.newInstance()
}
}
void testLogFromStaticMethods() {
Class clazz = new GroovyClassLoader().parseClass("""
@groovy.util.logging.Log
class MyClass {
static loggingMethod() {
log.info ("info called")
}
} """)
def logSpy = new LoggerSpy()
def logger = new MockFor(Logger)
logger.demand.getLogger { logSpy }
logger.use {
clazz.loggingMethod()
}
assert logSpy.infoParameter == 'info called'
}
void testLogInfo() {
Class clazz = new GroovyClassLoader().parseClass("""
@groovy.util.logging.Log
class MyClass {
def loggingMethod() {
log.severe ("severe called")
log.warning("warning called")
log.info ("info called")
log.fine ("fine called")
log.finer ("finer called")
log.finest ("finest called")
}
} """)
def logSpy = new LoggerSpy()
def logger = new MockFor(Logger)
logger.demand.getLogger { logSpy }
logger.use {
def s = clazz.newInstance()
s.loggingMethod()
}
assert logSpy.severeParameter == 'severe called'
assert logSpy.warningParameter == 'warning called'
assert logSpy.infoParameter == 'info called'
assert logSpy.fineParameter == 'fine called'
assert logSpy.finerParameter == 'finer called'
assert logSpy.finestParameter == 'finest called'
}
void testLogInfoWithName() {
Class clazz = new GroovyClassLoader().parseClass("""
@groovy.util.logging.Log('logger')
class MyClass {
def loggingMethod() {
logger.severe ("severe called")
logger.warning("warning called")
logger.info ("info called")
logger.fine ("fine called")
logger.finer ("finer called")
logger.finest ("finest called")
}
} """)
def logSpy = new LoggerSpy()
def logger = new MockFor(Logger)
logger.demand.getLogger { logSpy }
logger.use {
def s = clazz.newInstance()
s.loggingMethod()
}
assert logSpy.severeParameter == 'severe called'
assert logSpy.warningParameter == 'warning called'
assert logSpy.infoParameter == 'info called'
assert logSpy.fineParameter == 'fine called'
assert logSpy.finerParameter == 'finer called'
assert logSpy.finestParameter == 'finest called'
}
void testLogGuard() {
Class clazz = new GroovyClassLoader().parseClass("""
@groovy.util.logging.Log
class MyClass {
def loggingMethod() {
log.setLevel(java.util.logging.Level.OFF)
log.severe(prepareLogMessage())
log.warning(prepareLogMessage())
log.info (prepareLogMessage())
log.fine (prepareLogMessage())
log.finer (prepareLogMessage())
log.finest (prepareLogMessage())
}
def prepareLogMessage() {
return "formatted log message"
}
} """)
def logSpy = new LoggerSpy()
def logger = new MockFor(Logger)
logger.demand.getLogger { logSpy }
logger.use {
def s = clazz.newInstance()
s.loggingMethod()
}
assert !logSpy.severeParameter
assert !logSpy.warningParameter
assert !logSpy.infoParameter
assert !logSpy.fineParameter
assert !logSpy.finerParameter
assert !logSpy.finestParameter
}
void testInheritance() {
def clazz = new GroovyShell().evaluate("""
class MyParent {
private log
}
@groovy.util.logging.Log
class MyClass extends MyParent {
def loggingMethod() {
log.severe(prepareLogMessage())
log.warning(prepareLogMessage())
log.info (prepareLogMessage())
log.fine (prepareLogMessage())
log.finer (prepareLogMessage())
log.finest (prepareLogMessage())
}
def prepareLogMessage() {
"formatted log message"
}
}
return MyClass
""")
assert clazz.declaredFields.find { Field field ->
field.name == "log" &&
Modifier.isPrivate(field.getModifiers()) &&
Modifier.isStatic(field.getModifiers()) &&
Modifier.isTransient(field.getModifiers()) &&
Modifier.isFinal(field.getModifiers())
}
}
void testInheritance_ProtectedShadowing() {
shouldFail(MultipleCompilationErrorsException) {
new GroovyClassLoader().parseClass("""
class MyParent {
protected log
}
@groovy.util.logging.Log
class MyClass extends MyParent {
} """)
}
}
void testInheritance_PublicShadowing() {
shouldFail(MultipleCompilationErrorsException) {
new GroovyClassLoader().parseClass("""
class MyParent {
public log
}
@groovy.util.logging.Log
class MyClass extends MyParent {
} """)
}
}
void testDefaultCategory() {
Class clazz = new GroovyClassLoader().parseClass("""
@groovy.util.logging.Log
class MyClass {
static loggingMethod() {
log.info("info called")
}
}""")
LogFormatterSpy logFormatterSpy = registerLogFormatterSpy('MyClass')
clazz.newInstance().loggingMethod()
assert logFormatterSpy.messageReceived
}
void testCustomCategory() {
String categoryName = 'customCategory'
Class clazz = new GroovyClassLoader().parseClass("""
@groovy.util.logging.Log(category='$categoryName')
class MyClass {
static loggingMethod() {
log.info("info called")
}
}""")
LogFormatterSpy logFormatterSpy = registerLogFormatterSpy(categoryName)
clazz.newInstance().loggingMethod()
assert logFormatterSpy.messageReceived
}
private LogFormatterSpy registerLogFormatterSpy(String loggerName) {
Logger logger = Logger.getLogger(loggerName)
ConsoleHandler handler = new ConsoleHandler()
LogFormatterSpy loggerNameSpy = new LogFormatterSpy()
handler.setFormatter(loggerNameSpy)
logger.addHandler(handler)
return loggerNameSpy
}
}
@groovy.transform.PackageScope
class LoggerSpy extends Logger {
String severeParameter = null
String warningParameter = null
String infoParameter = null
String fineParameter = null
String finerParameter = null
String finestParameter = null
LoggerSpy() {
super(null, null)
}
@Override
void severe(String s) {
if (severeParameter) throw new AssertionError("Severe already called once with parameter $severeParameter")
severeParameter = s
}
@Override
void warning(String s) {
if (warningParameter) throw new AssertionError("Warning already called once with parameter $warningParameter")
warningParameter = s
}
@Override
void info(String s) {
if (infoParameter) throw new AssertionError("Info already called once with parameter $infoParameter")
infoParameter = s
}
@Override
void fine(String s) {
if (fineParameter) throw new AssertionError("Fine already called once with parameter $fineParameter")
fineParameter = s
}
@Override
void finer(String s) {
if (finerParameter) throw new AssertionError("Finer already called once with parameter $finerParameter")
finerParameter = s
}
@Override
void finest(String s) {
if (finestParameter) throw new AssertionError("Finest already called once with parameter $finestParameter")
finestParameter = s
}
}
class LogFormatterSpy extends Formatter {
boolean messageReceived = false
@Override
String format(LogRecord record) {
messageReceived = true
return record.message
}
}