From 36cc61b512314f1570db60fd4015b0026d955089 Mon Sep 17 00:00:00 2001 From: root Date: Tue, 12 Mar 2024 17:26:54 +0000 Subject: [PATCH 1/4] chore(dependencies): Autobump korkVersion --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index 41486fce34..4710820e42 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,7 +1,7 @@ enablePublishing=false fiatVersion=1.43.0 includeProviders=basic,iap,ldap,oauth2,saml,x509 -korkVersion=7.219.0 +korkVersion=7.220.0 kotlinVersion=1.5.32 org.gradle.parallel=true spinnakerGradleVersion=8.32.1 From 87993d39bb891e5edcb36caa92ab602815b24f65 Mon Sep 17 00:00:00 2001 From: j-sandy <30489233+j-sandy@users.noreply.github.com> Date: Thu, 15 Feb 2024 15:43:25 +0530 Subject: [PATCH 2/4] fix(test/core): refactor constructor by passing context to HttpSecurity instance updated with spring boot 2.6.x While upgrading spring boot 2.6.15 and spring cloud 2021.0.8, encounter below errors during execution of tests under gate-core modules: ``` Cannot invoke "org.springframework.context.ApplicationContext.getBeanNamesForType(java.lang.Class)" because "context" is null java.lang.NullPointerException: Cannot invoke "org.springframework.context.ApplicationContext.getBeanNamesForType(java.lang.Class)" because "context" is null at org.springframework.security.config.annotation.web.configurers.ExpressionUrlAuthorizationConfigurer.(ExpressionUrlAuthorizationConfigurer.java:109) at org.springframework.security.config.annotation.web.builders.HttpSecurity.authorizeRequests(HttpSecurity.java:1265) at com.netflix.spinnaker.gate.config.AuthConfig.configure(AuthConfig.java:76) at com.netflix.spinnaker.gate.config.AuthConfigTest.test webhooks are unauthenticated by default(AuthConfigTest.groovy:51) Cannot invoke "org.springframework.context.ApplicationContext.getBeanNamesForType(java.lang.Class)" because "context" is null java.lang.NullPointerException: Cannot invoke "org.springframework.context.ApplicationContext.getBeanNamesForType(java.lang.Class)" because "context" is null at org.springframework.security.config.annotation.web.configurers.ExpressionUrlAuthorizationConfigurer.(ExpressionUrlAuthorizationConfigurer.java:109) at org.springframework.security.config.annotation.web.builders.HttpSecurity.authorizeRequests(HttpSecurity.java:1265) at com.netflix.spinnaker.gate.config.AuthConfig.configure(AuthConfig.java:76) at com.netflix.spinnaker.gate.config.AuthConfigTest.test webhooks can be configured to be authenticated(AuthConfigTest.groovy:86) ``` As per the reference given [here](https://stackoverflow.com/questions/71322261/nullpointerexception-at-org-springframework-security-config-annotation-web-confi), the implementation of spring-security-config got changed from 5.5.x to 5.6.x and it must require the ApplicationContext object. So, in order to fix this issue added a map containing ApplicationContext.class and its object to the constructor. --- .../spinnaker/gate/config/AuthConfigTest.groovy | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/gate-core/src/test/groovy/com/netflix/spinnaker/gate/config/AuthConfigTest.groovy b/gate-core/src/test/groovy/com/netflix/spinnaker/gate/config/AuthConfigTest.groovy index 730a52e93b..bd230754d9 100644 --- a/gate-core/src/test/groovy/com/netflix/spinnaker/gate/config/AuthConfigTest.groovy +++ b/gate-core/src/test/groovy/com/netflix/spinnaker/gate/config/AuthConfigTest.groovy @@ -18,15 +18,20 @@ package com.netflix.spinnaker.gate.config import com.netflix.spinnaker.fiat.shared.FiatPermissionEvaluator import com.netflix.spinnaker.fiat.shared.FiatStatus +import org.springframework.context.ApplicationContext import org.springframework.security.config.annotation.ObjectPostProcessor import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder import org.springframework.security.config.annotation.web.builders.HttpSecurity import org.springframework.security.web.util.matcher.AnyRequestMatcher +import org.springframework.context.support.GenericApplicationContext import spock.lang.Specification import java.util.stream.Collectors class AuthConfigTest extends Specification { + + private GenericApplicationContext context = new GenericApplicationContext() + @SuppressWarnings("GroovyAccessibility") def "test webhooks are unauthenticated by default"() { given: @@ -44,7 +49,7 @@ class AuthConfigTest extends Specification { def httpSecurity = new HttpSecurity( Mock(ObjectPostProcessor), Mock(AuthenticationManagerBuilder), - [:] + getSharedObjects() ) when: @@ -79,7 +84,7 @@ class AuthConfigTest extends Specification { def httpSecurity = new HttpSecurity( Mock(ObjectPostProcessor), Mock(AuthenticationManagerBuilder), - [:] + getSharedObjects() ) when: @@ -95,4 +100,11 @@ class AuthConfigTest extends Specification { .collect(Collectors.toList()) filtered.size() == 1 } + + private HashMap, Object> getSharedObjects(){ + HashMap map = new HashMap, Object>() + context.refresh() + map.put(ApplicationContext.class, context) + return map; + } } From 48c1261a82b5dff4d9ec7ca797682621fadd260b Mon Sep 17 00:00:00 2001 From: j-sandy <30489233+j-sandy@users.noreply.github.com> Date: Thu, 15 Feb 2024 18:16:47 +0530 Subject: [PATCH 3/4] fix(tests): fix enableRedisKeyspaceNotificationsInitializer bean creation issue during upgrade to spring boot 2.6.x While upgrading spring boot 2.6.15 and spring cloud 2021.0.8, encounter below errors during execution of tests under gate-api-tck and gate-plugins-test modules: ``` Failed to load ApplicationContext java.lang.IllegalStateException: Failed to load ApplicationContext at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:98) at org.springframework.test.context.support.DefaultTestContext.getApplicationContext(DefaultTestContext.java:124) at org.springframework.test.context.web.ServletTestExecutionListener.setUpRequestContextIfNecessary(ServletTestExecutionListener.java:190) at org.springframework.test.context.web.ServletTestExecutionListener.prepareTestInstance(ServletTestExecutionListener.java:132) at org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.java:248) at com.netflix.spinnaker.gate.plugins.test.GatePluginsTest$tests$1$1$invoke$$inlined$serviceFixture$1.invoke(PluginsTck.kt:78) at com.netflix.spinnaker.gate.plugins.test.GatePluginsTest$tests$1$1$invoke$$inlined$serviceFixture$1.invoke(PluginsTck.kt:76) ... Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'enableRedisKeyspaceNotificationsInitializer' defined in class path resource [com/netflix/spinnaker/gate/config/GateConfig.class]: Invocation of init method failed; nested exception is org.springframework.data.redis.RedisConnectionFailureException: Cannot get Jedis connection; nested exception is redis.clients.jedis.exceptions.JedisConnectionException: Could not get a resource from the pool at app//org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1804) at app//org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:620) at app//org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:542) at app//org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:335) at app//org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) at app//org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:333) at app//org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:208) at app//org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:955) at app//org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:920) at app//org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:583) at app//org.springframework.boot.SpringApplication.refresh(SpringApplication.java:745) at app//org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:423) at app//org.springframework.boot.SpringApplication.run(SpringApplication.java:307) at app//org.springframework.boot.test.context.SpringBootContextLoader.loadContext(SpringBootContextLoader.java:148) at app//org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContextInternal(DefaultCacheAwareContextLoaderDelegate.java:141) at app//org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:90) ... 171 more Caused by: org.springframework.data.redis.RedisConnectionFailureException: Cannot get Jedis connection; nested exception is redis.clients.jedis.exceptions.JedisConnectionException: Could not get a resource from the pool at app//org.springframework.data.redis.connection.jedis.JedisConnectionFactory.fetchJedisConnector(JedisConnectionFactory.java:292) at app//org.springframework.data.redis.connection.jedis.JedisConnectionFactory.getConnection(JedisConnectionFactory.java:514) at app//org.springframework.session.data.redis.config.annotation.web.http.RedisHttpSessionConfiguration$EnableRedisKeyspaceNotificationsInitializer.afterPropertiesSet(RedisHttpSessionConfiguration.java:331) at app//org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1863) at app//org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1800) ... 186 more Caused by: redis.clients.jedis.exceptions.JedisConnectionException: Could not get a resource from the pool at app//redis.clients.jedis.util.Pool.getResource(Pool.java:84) at app//redis.clients.jedis.JedisPool.getResource(JedisPool.java:370) at app//redis.clients.jedis.JedisPool.getResource(JedisPool.java:15) at app//org.springframework.data.redis.connection.jedis.JedisConnectionFactory.fetchJedisConnector(JedisConnectionFactory.java:283) ... 190 more Caused by: redis.clients.jedis.exceptions.JedisConnectionException: Failed to create socket. at app//redis.clients.jedis.DefaultJedisSocketFactory.createSocket(DefaultJedisSocketFactory.java:110) at app//redis.clients.jedis.Connection.connect(Connection.java:226) at app//redis.clients.jedis.BinaryClient.connect(BinaryClient.java:140) at app//redis.clients.jedis.BinaryJedis.connect(BinaryJedis.java:310) at app//redis.clients.jedis.BinaryJedis.initializeFromClientConfig(BinaryJedis.java:88) at app//redis.clients.jedis.BinaryJedis.(BinaryJedis.java:293) at app//redis.clients.jedis.Jedis.(Jedis.java:169) at app//redis.clients.jedis.JedisFactory.makeObject(JedisFactory.java:177) at app//org.apache.commons.pool2.impl.GenericObjectPool.create(GenericObjectPool.java:571) at app//org.apache.commons.pool2.impl.GenericObjectPool.borrowObject(GenericObjectPool.java:298) at app//org.apache.commons.pool2.impl.GenericObjectPool.borrowObject(GenericObjectPool.java:223) at app//redis.clients.jedis.util.Pool.getResource(Pool.java:75) ... 193 more Caused by: java.net.ConnectException: Connection refused at java.base/sun.nio.ch.Net.pollConnect(Native Method) at java.base/sun.nio.ch.Net.pollConnectNow(Net.java:672) at java.base/sun.nio.ch.NioSocketImpl.timedFinishConnect(NioSocketImpl.java:547) at java.base/sun.nio.ch.NioSocketImpl.connect(NioSocketImpl.java:602) at java.base/java.net.SocksSocketImpl.connect(SocksSocketImpl.java:327) at java.base/java.net.Socket.connect(Socket.java:633) at redis.clients.jedis.DefaultJedisSocketFactory.createSocket(DefaultJedisSocketFactory.java:80) ... 204 more ``` In order to fix this issue add `@TestConfiguration` to create the required beans for initialization of `enableRedisKeyspaceNotificationsInitializer` bean. --- gate-api-tck/gate-api-tck.gradle | 2 ++ .../spinnaker/gate/api/test/GateFixture.kt | 31 +++++++++++++++++++ gate-plugins-test/gate-plugins-test.gradle | 2 ++ .../gate/plugins/test/GatePluginsFixture.kt | 27 +++++++++++++++- 4 files changed, 61 insertions(+), 1 deletion(-) diff --git a/gate-api-tck/gate-api-tck.gradle b/gate-api-tck/gate-api-tck.gradle index 35e8d220a0..7dd6a08c93 100644 --- a/gate-api-tck/gate-api-tck.gradle +++ b/gate-api-tck/gate-api-tck.gradle @@ -3,6 +3,8 @@ apply from: "${project.rootDir}/gradle/kotlin-test.gradle" dependencies { implementation(project(":gate-web")) + implementation("io.spinnaker.kork:kork-jedis-test") + implementation("org.springframework.session:spring-session-data-redis") api("org.springframework.boot:spring-boot-starter-test") api("dev.minutest:minutest") diff --git a/gate-api-tck/src/main/kotlin/com/netflix/spinnaker/gate/api/test/GateFixture.kt b/gate-api-tck/src/main/kotlin/com/netflix/spinnaker/gate/api/test/GateFixture.kt index bdbeff87d7..6a2b81eee9 100644 --- a/gate-api-tck/src/main/kotlin/com/netflix/spinnaker/gate/api/test/GateFixture.kt +++ b/gate-api-tck/src/main/kotlin/com/netflix/spinnaker/gate/api/test/GateFixture.kt @@ -20,10 +20,20 @@ import com.netflix.spinnaker.gate.Main import dev.minutest.TestContextBuilder import dev.minutest.TestDescriptor import org.springframework.boot.test.context.SpringBootTest +import org.springframework.boot.test.context.TestConfiguration import org.springframework.test.context.TestContextManager import org.springframework.test.context.TestPropertySource +import org.springframework.context.annotation.Bean +import com.netflix.spinnaker.kork.jedis.EmbeddedRedis +import org.springframework.context.annotation.Primary +import org.springframework.data.redis.connection.RedisStandaloneConfiguration +import org.springframework.data.redis.connection.jedis.JedisConnectionFactory +import org.springframework.session.data.redis.config.annotation.SpringSessionRedisConnectionFactory +import org.springframework.test.context.ContextConfiguration +import redis.clients.jedis.JedisPool @SpringBootTest(classes = [Main::class]) +@ContextConfiguration(classes = [GateFixtureConfiguration::class]) @TestPropertySource(properties = ["spring.config.location=classpath:gate-test-app.yml"]) abstract class GateFixture @@ -39,3 +49,24 @@ inline fun TestContextBuilder.gateFixture( } } } + +@TestConfiguration +internal open class GateFixtureConfiguration { + @Bean(destroyMethod = "destroy") + fun embeddedRedis(): EmbeddedRedis { + return EmbeddedRedis.embed().also { redis -> redis.jedis.connect() }.also { redis -> redis.jedis.ping() } + } + + @Bean + @Primary + @SpringSessionRedisConnectionFactory + fun jedisConnectionFactory(embeddedRedis: EmbeddedRedis): JedisConnectionFactory { + return JedisConnectionFactory(RedisStandaloneConfiguration(embeddedRedis.host, embeddedRedis.port)) + } + + @Bean + @Primary + fun jedis(embeddedRedis: EmbeddedRedis): JedisPool { + return embeddedRedis.getPool(); + } +} diff --git a/gate-plugins-test/gate-plugins-test.gradle b/gate-plugins-test/gate-plugins-test.gradle index 2c3bf31579..3c4f990212 100644 --- a/gate-plugins-test/gate-plugins-test.gradle +++ b/gate-plugins-test/gate-plugins-test.gradle @@ -9,6 +9,8 @@ dependencies { testImplementation("io.spinnaker.kork:kork-plugins") testImplementation("io.spinnaker.kork:kork-plugins-tck") + testImplementation("io.spinnaker.kork:kork-jedis-test") + testImplementation("org.springframework.session:spring-session-data-redis") testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine") } diff --git a/gate-plugins-test/src/test/kotlin/com/netflix/spinnaker/gate/plugins/test/GatePluginsFixture.kt b/gate-plugins-test/src/test/kotlin/com/netflix/spinnaker/gate/plugins/test/GatePluginsFixture.kt index af93403da2..a709c94aca 100644 --- a/gate-plugins-test/src/test/kotlin/com/netflix/spinnaker/gate/plugins/test/GatePluginsFixture.kt +++ b/gate-plugins-test/src/test/kotlin/com/netflix/spinnaker/gate/plugins/test/GatePluginsFixture.kt @@ -30,6 +30,13 @@ import org.springframework.boot.test.context.TestConfiguration import org.springframework.test.context.ContextConfiguration import org.springframework.test.context.TestPropertySource import org.springframework.test.web.servlet.MockMvc +import org.springframework.context.annotation.Bean +import com.netflix.spinnaker.kork.jedis.EmbeddedRedis +import org.springframework.context.annotation.Primary +import org.springframework.data.redis.connection.RedisStandaloneConfiguration +import org.springframework.data.redis.connection.jedis.JedisConnectionFactory +import org.springframework.session.data.redis.config.annotation.SpringSessionRedisConnectionFactory +import redis.clients.jedis.JedisPool class GatePluginsFixture : PluginsTckFixture, GateTestService() { @@ -75,4 +82,22 @@ class GatePluginsFixture : PluginsTckFixture, GateTestService() { abstract class GateTestService @TestConfiguration -internal open class PluginTestConfiguration +internal open class PluginTestConfiguration { + @Bean(destroyMethod = "destroy") + fun embeddedRedis(): EmbeddedRedis { + return EmbeddedRedis.embed().also { redis -> redis.jedis.connect() }.also { redis -> redis.jedis.ping() } + } + + @Bean + @Primary + @SpringSessionRedisConnectionFactory + fun jedisConnectionFactory(embeddedRedis: EmbeddedRedis): JedisConnectionFactory { + return JedisConnectionFactory(RedisStandaloneConfiguration(embeddedRedis.host, embeddedRedis.port)) + } + + @Bean + @Primary + fun jedis(embeddedRedis: EmbeddedRedis): JedisPool { + return embeddedRedis.getPool(); + } +} From 5971baa3441a96fffd0159a96aec96aa251587d7 Mon Sep 17 00:00:00 2001 From: j-sandy <30489233+j-sandy@users.noreply.github.com> Date: Fri, 19 Jan 2024 19:57:09 +0530 Subject: [PATCH 4/4] refactor(web/test): remove circular reference from GateConfig class identified during upgrade to spring boot 2.6.x MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit While upgrading spring boot 2.6.15 and spring cloud 2021.0.8, encounter below errors in gate-web module during gate-web:test task execution and 17 tests fail with similar error: ``` Failed to load ApplicationContext java.lang.IllegalStateException: Failed to load ApplicationContext at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:98) at org.springframework.test.context.support.DefaultTestContext.getApplicationContext(DefaultTestContext.java:124) at org.springframework.test.context.web.ServletTestExecutionListener.setUpRequestContextIfNecessary(ServletTestExecutionListener.java:190) at org.springframework.test.context.web.ServletTestExecutionListener.prepareTestInstance(ServletTestExecutionListener.java:132) at org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.java:248) at org.spockframework.spring.SpringTestContextManager.prepareTestInstance(SpringTestContextManager.java:56) at org.spockframework.spring.SpringInterceptor.interceptInitializerMethod(SpringInterceptor.java:46) at org.spockframework.runtime.extension.AbstractMethodInterceptor.intercept(AbstractMethodInterceptor.java:24) at org.spockframework.runtime.extension.MethodInvocation.proceed(MethodInvocation.java:101) at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$prepare$2(NodeTestTask.java:123) at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) at org.junit.platform.engine.support.hierarchical.NodeTestTask.prepare(NodeTestTask.java:123) at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:90) at java.base/java.util.ArrayList.forEach(ArrayList.java:1511) at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:41) at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:155) at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141) at org.spockframework.runtime.model.MethodInfo.invoke(MethodInfo.java:148) at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139) at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138) at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95) at java.base/java.util.ArrayList.forEach(ArrayList.java:1511) at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:41) at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:155) at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141) at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137) at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139) at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138) at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95) at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.submit(SameThreadHierarchicalTestExecutorService.java:35) at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.execute(HierarchicalTestExecutor.java:57) at org.junit.platform.engine.support.hierarchical.HierarchicalTestEngine.execute(HierarchicalTestEngine.java:54) at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:107) at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:88) at org.junit.platform.launcher.core.EngineExecutionOrchestrator.lambda$execute$0(EngineExecutionOrchestrator.java:54) at org.junit.platform.launcher.core.EngineExecutionOrchestrator.withInterceptedStreams(EngineExecutionOrchestrator.java:67) at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:52) at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:114) at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:86) at org.junit.platform.launcher.core.DefaultLauncherSession$DelegatingLauncher.execute(DefaultLauncherSession.java:86) at org.junit.platform.launcher.core.SessionPerRequestLauncher.execute(SessionPerRequestLauncher.java:53) at org.gradle.api.internal.tasks.testing.junitplatform.JUnitPlatformTestClassProcessor$CollectAllTestClassesExecutor.processAllTestClasses(JUnitPlatformTestClassProcessor.java:99) at org.gradle.api.internal.tasks.testing.junitplatform.JUnitPlatformTestClassProcessor$CollectAllTestClassesExecutor.access$000(JUnitPlatformTestClassProcessor.java:79) at org.gradle.api.internal.tasks.testing.junitplatform.JUnitPlatformTestClassProcessor.stop(JUnitPlatformTestClassProcessor.java:75) at org.gradle.api.internal.tasks.testing.SuiteTestClassProcessor.stop(SuiteTestClassProcessor.java:62) at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:36) at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24) at org.gradle.internal.dispatch.ContextClassLoaderDispatch.dispatch(ContextClassLoaderDispatch.java:33) at org.gradle.internal.dispatch.ProxyDispatchAdapter$DispatchingInvocationHandler.invoke(ProxyDispatchAdapter.java:94) at org.gradle.api.internal.tasks.testing.worker.TestWorker$3.run(TestWorker.java:193) at org.gradle.api.internal.tasks.testing.worker.TestWorker.executeAndMaintainThreadName(TestWorker.java:129) at org.gradle.api.internal.tasks.testing.worker.TestWorker.execute(TestWorker.java:100) at org.gradle.api.internal.tasks.testing.worker.TestWorker.execute(TestWorker.java:60) at org.gradle.process.internal.worker.child.ActionExecutionWorker.execute(ActionExecutionWorker.java:56) at org.gradle.process.internal.worker.child.SystemApplicationClassLoaderWorker.call(SystemApplicationClassLoaderWorker.java:113) at org.gradle.process.internal.worker.child.SystemApplicationClassLoaderWorker.call(SystemApplicationClassLoaderWorker.java:65) at worker.org.gradle.process.internal.worker.GradleWorkerMain.run(GradleWorkerMain.java:69) at worker.org.gradle.process.internal.worker.GradleWorkerMain.main(GradleWorkerMain.java:74) Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'gateConfig': Unsatisfied dependency expressed through method 'setConfigureRedisAction' parameter 0; nested exception is org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name 'gateConfig': Requested bean is currently in creation: Is there an unresolvable circular reference? at app//org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredMethodElement.resolveMethodArguments(AutowiredAnnotationBeanPostProcessor.java:768) at app//org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredMethodElement.inject(AutowiredAnnotationBeanPostProcessor.java:720) at app//org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:119) at app//org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessProperties(AutowiredAnnotationBeanPostProcessor.java:399) at app//org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1431) at app//org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:619) at app//org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:542) at app//org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:335) at app//org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) at app//org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:333) at app//org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:208) at app//org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:955) at app//org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:920) at app//org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:583) at app//org.springframework.boot.SpringApplication.refresh(SpringApplication.java:745) at app//org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:423) at app//org.springframework.boot.SpringApplication.run(SpringApplication.java:307) at app//org.springframework.boot.test.context.SpringBootContextLoader.loadContext(SpringBootContextLoader.java:148) at app//org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContextInternal(DefaultCacheAwareContextLoaderDelegate.java:141) at app//org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:90) ... 61 more Caused by: org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name 'gateConfig': Requested bean is currently in creation: Is there an unresolvable circular reference? at app//org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.beforeSingletonCreation(DefaultSingletonBeanRegistry.java:355) at app//org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:227) at app//org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:333) at app//org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:208) at app//org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:410) at app//org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1352) at app//org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1195) at app//org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:582) at app//org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:542) at app//org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:335) at app//org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) at app//org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:333) at app//org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:208) at app//org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:276) at app//org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1391) at app//org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1311) at app//org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredMethodElement.resolveMethodArguments(AutowiredAnnotationBeanPostProcessor.java:760) ... 80 more ``` and ``` Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled. 2024-01-19 16:03:05.279 ERROR 705260 --- [ Test worker] o.s.b.d.LoggingFailureAnalysisReporter : [] *************************** APPLICATION FAILED TO START *************************** Description: The dependencies of some of the beans in the application context form a cycle: ┌──->──┐ | gateConfig └──<-──┘ Action: Relying upon circular references is discouraged and they are prohibited by default. Update your application to remove the dependency cycle between beans. As a last resort, it may be possible to break the cycle automatically by setting spring.main.allow-circular-references to true. 2024-01-19 16:03:05.283 ERROR 705260 --- [ Test worker] o.s.test.context.TestContextManager : [] Caught exception while allowing TestExecutionListener [org.springframework.test.context.web.ServletTestExecutionListener@e044b4a] to prepare test instance [com.netflix.spinnaker.gate.config.GateCorsAllowedOriginConfigSpec@7f8e4389] java.lang.IllegalStateException: Failed to load ApplicationContext ... ``` The root cause of circular reference identification is new feature "circular reference prohibition" introduced in [Spring Boot 2.6.x](https://github.com/spring-projects/spring-boot/wiki/Spring-Boot-2.6-Release-Notes#circular-references-prohibited-by-default). To fix this issue refactoring the GateConfig class with explicit setConfigureRedisAction() setter. --- .../com/netflix/spinnaker/gate/config/GateConfig.groovy | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/gate-web/src/main/groovy/com/netflix/spinnaker/gate/config/GateConfig.groovy b/gate-web/src/main/groovy/com/netflix/spinnaker/gate/config/GateConfig.groovy index e7914a8a2a..533238c39d 100644 --- a/gate-web/src/main/groovy/com/netflix/spinnaker/gate/config/GateConfig.groovy +++ b/gate-web/src/main/groovy/com/netflix/spinnaker/gate/config/GateConfig.groovy @@ -79,6 +79,7 @@ import static retrofit.Endpoints.newFixedEndpoint class GateConfig extends RedisHttpSessionConfiguration { private ServiceClientProvider serviceClientProvider + private ConfigureRedisAction configureRedisAction @Value('${server.session.timeout-in-seconds:3600}') void setSessionTimeout(int maxInactiveIntervalInSeconds) { @@ -90,6 +91,10 @@ class GateConfig extends RedisHttpSessionConfiguration { this.serviceClientProvider = serviceClientProvider } + void setConfigureRedisAction(ConfigureRedisAction configureRedisAction){ + this.configureRedisAction = configureRedisAction; + } + @Autowired GateConfig(@Value('${server.session.timeout-in-seconds:3600}') int maxInactiveIntervalInSeconds) { super.setMaxInactiveIntervalInSeconds(maxInactiveIntervalInSeconds)