Skip to content

Commit

Permalink
refactor(tests): convert groovy based test to java while upgrading sp…
Browse files Browse the repository at this point in the history
…ockframework to 2.2-groovy-3.0

While upgrading spockframework from 2.0-groovy-3.0 to 2.2-groovy-3.0, encountered below errors during test execution of kork-exceptions and kork-pubsub-aws modules:

```
java.lang.ExceptionInInitializerError
        at org.spockframework.mock.runtime.CglibMockFactory.createMock(CglibMockFactory.java:24)
        at org.spockframework.mock.runtime.ProxyBasedMockFactory.create(ProxyBasedMockFactory.java:45)
        at org.spockframework.mock.runtime.JavaMockFactory.createInternal(JavaMockFactory.java:58)
        at org.spockframework.mock.runtime.JavaMockFactory.create(JavaMockFactory.java:38)
        at org.spockframework.mock.runtime.CompositeMockFactory.create(CompositeMockFactory.java:44)
        at org.spockframework.lang.SpecInternals.createMock(SpecInternals.java:50)
        at org.spockframework.lang.SpecInternals.createMockImpl(SpecInternals.java:305)
        at org.spockframework.lang.SpecInternals.createMockImpl(SpecInternals.java:295)
        at org.spockframework.lang.SpecInternals.SpyImpl(SpecInternals.java:172)
        at com.netflix.spinnaker.kork.core.RetrySupportSpec.should retry until success or #maxRetries attempts is reached(RetrySupportSpec.groovy:28)
Caused by: net.sf.cglib.core.CodeGenerationException: java.lang.reflect.InaccessibleObjectException-->Unable to make protected final java.lang.Class java.lang.ClassLoader.defineClass(java.lang.String,byte[],int,int,java.security.ProtectionDomain) throws java.lang.ClassFormatError accessible: module java.base does not "opens java.lang" to unnamed module @4afcd809
        at app//net.sf.cglib.core.ReflectUtils.defineClass(ReflectUtils.java:464)
        at app//net.sf.cglib.core.AbstractClassGenerator.generate(AbstractClassGenerator.java:339)
        at app//net.sf.cglib.core.AbstractClassGenerator$ClassLoaderData$3.apply(AbstractClassGenerator.java:96)
        at app//net.sf.cglib.core.AbstractClassGenerator$ClassLoaderData$3.apply(AbstractClassGenerator.java:94)
        at app//net.sf.cglib.core.internal.LoadingCache$2.call(LoadingCache.java:54)
        at java.base@17.0.2/java.util.concurrent.FutureTask.run(FutureTask.java:264)
        at app//net.sf.cglib.core.internal.LoadingCache.createEntry(LoadingCache.java:61)
        at app//net.sf.cglib.core.internal.LoadingCache.get(LoadingCache.java:34)
        at app//net.sf.cglib.core.AbstractClassGenerator$ClassLoaderData.get(AbstractClassGenerator.java:119)
        at app//net.sf.cglib.core.AbstractClassGenerator.create(AbstractClassGenerator.java:294)
        at app//net.sf.cglib.core.KeyFactory$Generator.create(KeyFactory.java:221)
        at app//net.sf.cglib.core.KeyFactory.create(KeyFactory.java:174)
        at app//net.sf.cglib.core.KeyFactory.create(KeyFactory.java:153)
        at app//net.sf.cglib.proxy.Enhancer.<clinit>(Enhancer.java:73)
        ... 10 more
Caused by: java.lang.reflect.InaccessibleObjectException: Unable to make protected final java.lang.Class java.lang.ClassLoader.defineClass(java.lang.String,byte[],int,int,java.security.ProtectionDomain) throws java.lang.ClassFormatError accessible: module java.base does not "opens java.lang" to unnamed module @4afcd809
        at net.sf.cglib.core.ReflectUtils$1.run(ReflectUtils.java:61)
        at java.base/java.security.AccessController.doPrivileged(AccessController.java:569)
        at net.sf.cglib.core.ReflectUtils.<clinit>(ReflectUtils.java:52)
        at net.sf.cglib.core.KeyFactory$Generator.generateClass(KeyFactory.java:243)
        at net.sf.cglib.core.DefaultGeneratorStrategy.generate(DefaultGeneratorStrategy.java:25)
        at net.sf.cglib.core.AbstractClassGenerator.generate(AbstractClassGenerator.java:332)
        ... 22 more
```

In order to fix this issue, converted the groovy based test classes `RetrySupportSpec.groovy` and `SQSSubscriberSpec.groovy` as java test classes.
  • Loading branch information
j-sandy committed Aug 1, 2024
1 parent 4cccd3f commit 832939a
Show file tree
Hide file tree
Showing 7 changed files with 277 additions and 228 deletions.
7 changes: 4 additions & 3 deletions kork-exceptions/kork-exceptions.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,10 @@ dependencies {
api(platform(project(":spinnaker-dependencies")))
api "com.google.code.findbugs:jsr305"

testImplementation "org.spockframework:spock-core"
testRuntimeOnly "cglib:cglib-nodep"
testRuntimeOnly "org.objenesis:objenesis"
testImplementation "org.mockito:mockito-core"
testImplementation "org.junit.jupiter:junit-jupiter-api"
testImplementation "org.junit.jupiter:junit-jupiter-params"
testRuntimeOnly "org.junit.jupiter:junit-jupiter-engine"

testImplementation "com.hubspot.jinjava:jinjava"
}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
/*
* Copyright 2024 OpsMx, Inc.
*
* Licensed 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 com.netflix.spinnaker.kork.core;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.spy;

import java.time.Duration;
import java.util.function.Supplier;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.CsvSource;

public class RetrySupportTest {

RetrySupport retrySupport;
int attemptCounter;

@BeforeEach
public void setup() {
retrySupport = spy(new RetrySupport());
attemptCounter = 0;

doNothing().when(retrySupport).sleep(10000);
doNothing().when(retrySupport).sleep(20000);
doNothing().when(retrySupport).sleep(40000);
doNothing().when(retrySupport).sleep(80000);
}

@ParameterizedTest(name = "should retry until success or {1} attempts is reached")
@CsvSource({"3,10,4,'empty'", "11,10,10,'Failed after 10 attempts'"})
void testRetryFailureWithMaxretries(int fail, int retry, int attempt, String msg) {
// given
String exceptionMessage = null;
int failures = fail;
int maxRetries = retry;
int expectedAttempts = attempt;
String expectedExceptionMessage = msg.equalsIgnoreCase("empty") ? null : msg;

Supplier fn =
() -> {
if (attemptCounter++ < failures) {
throw new IllegalStateException("Failed after " + attemptCounter + " attempts");
}
return null;
};

// when
try {
retrySupport.retry(fn, maxRetries, Duration.ofMillis(10000), false);
} catch (Exception e) {
exceptionMessage = e.getMessage();
}

// then
assertEquals(attemptCounter, expectedAttempts);
assertEquals(exceptionMessage, expectedExceptionMessage);
}

@Test
void testSleepExponentially() {
// given
int failures = 4;
int maxRetries = 20;
int expectedAttempts = 5;

Supplier fn =
() -> {
if (attemptCounter++ < failures) {
throw new IllegalStateException("Failed after " + attemptCounter + " attempts");
}
return null;
};

// when
retrySupport.retry(fn, maxRetries, Duration.ofMillis(10000), true);

// then
assertEquals(attemptCounter, expectedAttempts);
}
}
4 changes: 4 additions & 0 deletions kork-pubsub-aws/kork-pubsub-aws.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -36,4 +36,8 @@ dependencies {
testImplementation "org.spockframework:spock-core"
testRuntimeOnly "cglib:cglib-nodep"
testRuntimeOnly "org.objenesis:objenesis"

testImplementation "org.mockito:mockito-core"
testImplementation "org.junit.jupiter:junit-jupiter-api"
testRuntimeOnly "org.junit.jupiter:junit-jupiter-engine"
}
Original file line number Diff line number Diff line change
Expand Up @@ -2