codeconsole commented on code in PR #15666: URL: https://github.com/apache/grails-core/pull/15666#discussion_r3611349411
########## grails-core/src/test/groovy/grails/util/GrailsUtilStackFiltererSpec.groovy: ########## @@ -0,0 +1,172 @@ +/* + * 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 + * + * https://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 grails.util + +import grails.config.Config +import grails.core.GrailsApplication +import org.grails.exceptions.reporting.DefaultStackTraceFilterer +import org.grails.exceptions.reporting.StackTraceFilterer +import spock.lang.Specification + +import java.lang.reflect.Field + +/** + * Verifies that {@link GrailsUtil#initializeStackFilterer} resolves the configured filterer class + * from the application's config and propagates {@code grails.exceptionresolver.logFullStackTraceOnFilter} + * to {@link DefaultStackTraceFilterer} instances. Before initialization the FALLBACK_FILTERER + * (a {@link DefaultStackTraceFilterer} singleton) is used so CLI/test/main paths work unchanged. + */ +class GrailsUtilStackFiltererSpec extends Specification { Review Comment: Added grails-test-examples/app2/src/integration-test/groovy/app2/GrailsUtilStackFiltererIntegrationSpec.groovy. Boots app2 with grails.logging.stackTraceFiltererClass=app2.RecordingStackTraceFilterer (via a distinct @TestPropertySource-scoped context so ErrorsControllerSpec/NotFoundHandlerSpec keep the default context), hits a new TestController action that calls GrailsUtil.deepSanitize directly, and asserts the configured class -- not the default -- handled it. That is the one thing the unit specs cannot prove: that the bootstrap wiring actually fires in a real app. ########## grails-core/src/test/groovy/grails/util/GrailsUtilStackFiltererSpec.groovy: ########## @@ -0,0 +1,172 @@ +/* + * 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 + * + * https://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 grails.util + +import grails.config.Config +import grails.core.GrailsApplication +import org.grails.exceptions.reporting.DefaultStackTraceFilterer +import org.grails.exceptions.reporting.StackTraceFilterer +import spock.lang.Specification + +import java.lang.reflect.Field + +/** + * Verifies that {@link GrailsUtil#initializeStackFilterer} resolves the configured filterer class + * from the application's config and propagates {@code grails.exceptionresolver.logFullStackTraceOnFilter} + * to {@link DefaultStackTraceFilterer} instances. Before initialization the FALLBACK_FILTERER + * (a {@link DefaultStackTraceFilterer} singleton) is used so CLI/test/main paths work unchanged. + */ +class GrailsUtilStackFiltererSpec extends Specification { + + StackTraceFilterer previous + + def setup() { + previous = currentFilterer() + setFilterer(fallbackFilterer()) + } + + def cleanup() { + setFilterer(previous) + } + + def 'deepSanitize uses the fallback filterer before initializeStackFilterer is called'() { Review Comment: Fixed -- dropped the assertion on the state the test itself just installed; the case now only asserts noExceptionThrown() (deepSanitize succeeds with no application wired). ########## grails-core/src/test/groovy/grails/util/GrailsUtilStackFiltererSpec.groovy: ########## @@ -0,0 +1,172 @@ +/* + * 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 + * + * https://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 grails.util + +import grails.config.Config +import grails.core.GrailsApplication +import org.grails.exceptions.reporting.DefaultStackTraceFilterer +import org.grails.exceptions.reporting.StackTraceFilterer +import spock.lang.Specification + +import java.lang.reflect.Field + +/** + * Verifies that {@link GrailsUtil#initializeStackFilterer} resolves the configured filterer class + * from the application's config and propagates {@code grails.exceptionresolver.logFullStackTraceOnFilter} + * to {@link DefaultStackTraceFilterer} instances. Before initialization the FALLBACK_FILTERER + * (a {@link DefaultStackTraceFilterer} singleton) is used so CLI/test/main paths work unchanged. + */ +class GrailsUtilStackFiltererSpec extends Specification { + + StackTraceFilterer previous + + def setup() { + previous = currentFilterer() + setFilterer(fallbackFilterer()) + } + + def cleanup() { + setFilterer(previous) + } + + def 'deepSanitize uses the fallback filterer before initializeStackFilterer is called'() { + when: + GrailsUtil.deepSanitize(new RuntimeException('boom')) + + then: + noExceptionThrown() + currentFilterer().is(fallbackFilterer()) + } + + def 'initializeStackFilterer is a no-op when application is null'() { + when: + GrailsUtil.initializeStackFilterer(null) + + then: + currentFilterer().is(fallbackFilterer()) + } + + def 'initializeStackFilterer wires the class declared by grails.logging.stackTraceFiltererClass'() { + given: + def application = Mock(GrailsApplication) + def config = Mock(Config) + config.getProperty('grails.logging.stackTraceFiltererClass', Class, DefaultStackTraceFilterer) >> RecordingStackTraceFilterer + config.getProperty('grails.exceptionresolver.logFullStackTraceOnFilter', Boolean, true) >> true + application.getConfig() >> config + + when: + GrailsUtil.initializeStackFilterer(application) + GrailsUtil.deepSanitize(new RuntimeException('boom')) + + then: + currentFilterer() instanceof RecordingStackTraceFilterer + RecordingStackTraceFilterer.lastInstance.recursiveCalls == 1 + } + + def 'initializeStackFilterer propagates logFullStackTraceOnFilter to DefaultStackTraceFilterer instances'() { + given: + def application = Mock(GrailsApplication) + def config = Mock(Config) + config.getProperty('grails.logging.stackTraceFiltererClass', Class, DefaultStackTraceFilterer) >> DefaultStackTraceFilterer + config.getProperty('grails.exceptionresolver.logFullStackTraceOnFilter', Boolean, true) >> false + application.getConfig() >> config + + and: 'captured StackTrace logger output' + def originalErr = System.err + def baos = new ByteArrayOutputStream() + System.setErr(new PrintStream(baos, true)) + + when: + GrailsUtil.initializeStackFilterer(application) + GrailsUtil.deepSanitize(new RuntimeException('boom')) + + then: + System.err.flush() + !baos.toString().contains('ERROR StackTrace') Review Comment: Fixed -- both tests now check for StackTraceFilterer.FULL_STACK_TRACE_MESSAGE ('Full Stack Trace:'), the actual marker DefaultStackTraceFilterer emits, and I added the positive-control case (default/enabled emission) alongside the disabled one so the negative assertion is proven meaningful. -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: [email protected] For queries about this service, please contact Infrastructure at: [email protected]
