Skip to content

Commit

Permalink
[native clouds] add support for setup task
Browse files Browse the repository at this point in the history
  • Loading branch information
istraka committed Jan 23, 2023
1 parent 7bb6ffa commit 0e23daa
Show file tree
Hide file tree
Showing 10 changed files with 247 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package sunstone.api;


public abstract class AbstractSetupTask {
public abstract void setup() throws Exception;
public abstract void cleanup() throws Exception;
}
24 changes: 24 additions & 0 deletions clouds/clouds-core/src/main/java/sunstone/api/Setup.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package sunstone.api;

import org.junit.jupiter.api.extension.ExtendWith;
import sunstone.core.SunstoneExtension;

import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
* Define {@link AbstractSetupTask} that configure environment right after Cloud resources are deployed and before.
*
* The class may inject static/non-static resources using annotations annotated by {@link SunstoneInjectionAnnotation}
* that are brought bu modules like sunstone-clouds-aws or sunstone-clouds-azure.
*/
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE})
@ExtendWith(SunstoneExtension.class)
@Inherited
public @interface Setup {
Class<? extends AbstractSetupTask> [] value();
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
import org.junit.platform.commons.support.AnnotationSupport;
import org.junit.platform.commons.support.HierarchyTraversalMode;
import org.wildfly.extras.sunstone.api.impl.ObjectProperties;
import sunstone.api.AbstractSetupTask;
import sunstone.api.Setup;
import sunstone.api.SunstoneInjectionAnnotation;
import sunstone.api.SunstoneArchiveDeployTargetAnotation;
import sunstone.api.Deployment;
Expand All @@ -31,6 +33,7 @@
import java.io.IOException;
import java.io.InputStream;
import java.lang.annotation.Annotation;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
Expand Down Expand Up @@ -69,10 +72,44 @@ public void beforeAll(ExtensionContext ctx) throws Exception {
if (ctx.getRequiredTestClass().getAnnotationsByType(WithAwsCfTemplate.class).length > 0) {
handleAwsCloudFormationAnnotations(ctx);
}
if (ctx.getRequiredTestClass().getAnnotationsByType(Setup.class).length > 0) {
handleSetup(ctx);
}
performDeploymentOperation(ctx);
injectStaticResources(ctx, ctx.getRequiredTestClass());
}

static void handleSetup(ExtensionContext ctx) throws IllegalArgumentSunstoneException {
SunstoneStore store = new SunstoneStore(ctx);
if (ctx.getRequiredTestClass().getAnnotationsByType(Setup.class).length != 1) {
throw new RuntimeException();
}
Setup setup = ctx.getRequiredTestClass().getAnnotationsByType(Setup.class)[0];
for (Class<? extends AbstractSetupTask> setupTask : setup.value()) {
injectStaticResources(ctx, setupTask);
Optional<Constructor<?>> constructor = Arrays.stream(setupTask.getDeclaredConstructors())
.filter(c -> c.getParameterCount() == 0)
.findAny();
constructor.orElseThrow(() -> new IllegalArgumentSunstoneException("Setup task must have a constructor with 0 parameters"));
constructor.get().setAccessible(true);
AbstractSetupTask abstractSetupTask = null;
try {
abstractSetupTask = (AbstractSetupTask) constructor.get().newInstance();
injectInstanceResources(ctx, abstractSetupTask);
store.addClosable((AutoCloseable) abstractSetupTask::cleanup);
abstractSetupTask.setup();
} catch (InstantiationException e) {
throw new RuntimeException(e);
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
} catch (InvocationTargetException e) {
throw new RuntimeException(e);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}

static void handleAwsCloudFormationAnnotations(ExtensionContext ctx) {
Optional<SunstoneCloudDeployer> deployer = getDeployer(WithAwsCfTemplate.class);
deployer.orElseThrow(() -> new RuntimeException("Unable to load a service via SPI that handles " + WithAwsCfTemplate.class.getName() + " annotation."));
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package sunstone.core.di;


import sunstone.api.AbstractSetupTask;

abstract class AbstractStaticDITask extends AbstractSetupTask {
@DirectlyAnnotatedInject
static String directStaticInjectInAbstract;

@DirectlyAnnotatedInject
String directNonStaticInjectInAbstract;

@IndirectlyAnnotatedInject
static String indirectStaticInjectInAbstract;

@IndirectlyAnnotatedInject
String indirectNonStaticInjectInAbstract;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package sunstone.core.di;


import org.assertj.core.api.Assertions;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.Test;
import sunstone.api.Setup;

@Setup({StaticDITask.class})
public class SetupTaskDITest {

@AfterAll
public static void reset() {
StaticDITask.reset();
TestSunstoneResourceInjector.reset();
}

@Test
public void test() {
Assertions.assertThat(StaticDITask.setupCalled).isTrue();
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package sunstone.core.di;


import static org.assertj.core.api.Assertions.assertThat;

class StaticDITask extends AbstractStaticDITask {

@DirectlyAnnotatedInject
static String directStaticInject;

@DirectlyAnnotatedInject
String directNonStaticInject;

@IndirectlyAnnotatedInject
static String indirectStaticInject;

@IndirectlyAnnotatedInject
String indirectNonStaticInject;
static boolean setupCalled = false;
static boolean cleanupCalled = false;

@Override
public void setup() throws Exception {
setupCalled = true;
}

@Override
public void cleanup() throws Exception {
assertThat(directStaticInject).isEqualTo("set");
assertThat(directStaticInjectInAbstract).isEqualTo("set");
assertThat(indirectStaticInject).isEqualTo("set");
assertThat(indirectStaticInjectInAbstract).isEqualTo("set");
assertThat(directNonStaticInject).isEqualTo("set");
assertThat(directNonStaticInjectInAbstract).isEqualTo("set");
assertThat(indirectNonStaticInject).isEqualTo("set");
assertThat(indirectNonStaticInjectInAbstract).isEqualTo("set");
cleanupCalled = true;
}

public static void reset() {
setupCalled = false;
cleanupCalled = false;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package sunstone.core.setup;

import org.junit.platform.suite.api.SelectClasses;
import org.junit.platform.suite.api.Suite;
import sunstone.core.setup.suitetests.SetupCleanupSecondTest;
import sunstone.core.setup.suitetests.SetupFirstTest;

@Suite
@SelectClasses({SetupFirstTest.class, SetupCleanupSecondTest.class})
public class SetupSuite {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package sunstone.core.setup.suitetests;


import sunstone.api.AbstractSetupTask;

class RegularClassTask extends AbstractSetupTask {
static boolean setupCalled = false;
static boolean cleanupCalled = false;

@Override
public void setup() throws Exception {
setupCalled = true;
}

@Override
public void cleanup() throws Exception {
cleanupCalled = true;
}

public static void reset() {
setupCalled = false;
cleanupCalled = false;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package sunstone.core.setup.suitetests;


import org.assertj.core.api.Assertions;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.Test;

public class SetupCleanupSecondTest {

@Test
public void test() {
Assertions.assertThat(SetupFirstTest.StaticClassTask.cleanupCalled).isTrue();
Assertions.assertThat(RegularClassTask.cleanupCalled).isTrue();
}

@AfterAll
public static void reset() {
RegularClassTask.reset();
SetupFirstTest.StaticClassTask.reset();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package sunstone.core.setup.suitetests;


import org.assertj.core.api.Assertions;
import org.junit.jupiter.api.Test;
import sunstone.api.AbstractSetupTask;
import sunstone.api.Setup;

@Setup({SetupFirstTest.StaticClassTask.class, RegularClassTask.class})
public class SetupFirstTest {

@Test
public void test() {
Assertions.assertThat(StaticClassTask.setupCalled).isTrue();
Assertions.assertThat(RegularClassTask.setupCalled).isTrue();
}

static class StaticClassTask extends AbstractSetupTask {
static boolean setupCalled = false;
static boolean cleanupCalled = false;

@Override
public void setup() throws Exception {
setupCalled = true;
}

@Override
public void cleanup() throws Exception {
cleanupCalled = true;
}

public static void reset() {
setupCalled = false;
cleanupCalled = false;
}
}

}

0 comments on commit 0e23daa

Please sign in to comment.