001/** 002 * Copyright (C) 2006-2023 Talend Inc. - www.talend.com 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016package org.talend.sdk.component.junit5.environment; 017 018import static java.util.Collections.singletonList; 019import static java.util.Optional.of; 020import static java.util.Optional.ofNullable; 021 022import java.lang.annotation.Annotation; 023import java.util.List; 024import java.util.stream.Stream; 025 026import org.junit.jupiter.api.extension.AfterEachCallback; 027import org.junit.jupiter.api.extension.BeforeEachCallback; 028import org.junit.jupiter.api.extension.ConditionEvaluationResult; 029import org.junit.jupiter.api.extension.ExecutionCondition; 030import org.junit.jupiter.api.extension.Extension; 031import org.junit.jupiter.api.extension.ExtensionContext; 032import org.junit.jupiter.api.extension.ParameterContext; 033import org.junit.jupiter.api.extension.ParameterResolutionException; 034import org.junit.jupiter.api.extension.ParameterResolver; 035import org.junit.jupiter.api.extension.TestInstancePostProcessor; 036import org.junit.jupiter.api.extension.TestTemplateInvocationContext; 037import org.junit.platform.commons.util.AnnotationUtils; 038import org.talend.sdk.component.junit.environment.DecoratingEnvironmentProvider; 039import org.talend.sdk.component.junit.environment.EnvironmentConfiguration; 040import org.talend.sdk.component.junit.environment.EnvironmentConfigurations; 041import org.talend.sdk.component.junit.environment.EnvironmentProvider; 042import org.talend.sdk.component.junit5.ComponentExtension; 043 044import lombok.AllArgsConstructor; 045 046@AllArgsConstructor 047public class EnvironmentalContext implements TestTemplateInvocationContext { 048 049 private final EnvironmentProvider provider; 050 051 private final String displayName; 052 053 private final ComponentExtension componentExtension; 054 055 @Override 056 public String getDisplayName(final int invocationIndex) { 057 return displayName; 058 } 059 060 @Override 061 public List<Extension> getAdditionalExtensions() { 062 return singletonList(new EnvironmentalLifecycle(provider, componentExtension, null)); 063 } 064 065 @AllArgsConstructor 066 public static class EnvironmentalLifecycle implements BeforeEachCallback, AfterEachCallback, ExecutionCondition, 067 ParameterResolver, TestInstancePostProcessor { 068 069 private final EnvironmentProvider provider; 070 071 private final ComponentExtension componentExtension; 072 073 private AutoCloseable closeable; 074 075 @Override 076 public void beforeEach(final ExtensionContext context) { 077 closeable = provider 078 .start(context.getRequiredTestClass(), 079 Stream 080 .concat(Stream.of(context.getRequiredTestClass().getAnnotations()), 081 Stream 082 .of(of(AnnotationUtils 083 .findRepeatableAnnotations(context.getRequiredTestClass(), 084 EnvironmentConfiguration.class)) 085 .filter(it -> !it.isEmpty()) 086 .map(l -> new Annotation[] { 087 new EnvironmentConfigurations() { 088 089 @Override 090 public Class<? extends Annotation> 091 annotationType() { 092 return EnvironmentConfigurations.class; 093 } 094 095 @Override 096 public EnvironmentConfiguration[] 097 value() { 098 return l 099 .toArray( 100 new EnvironmentConfiguration[0]); 101 } 102 } }) 103 .orElseGet(() -> new Annotation[0]))) 104 .toArray(Annotation[]::new)); 105 ofNullable(componentExtension).ifPresent(c -> { 106 c.doStart(context); 107 c.doInject(context); 108 }); 109 } 110 111 @Override 112 public void afterEach(final ExtensionContext context) { 113 ofNullable(componentExtension).ifPresent(c -> { 114 c.resetState(); 115 c.doStop(context); 116 }); 117 ofNullable(closeable).ifPresent(c -> { 118 try { 119 c.close(); 120 } catch (final Exception e) { 121 throw new IllegalStateException(e); 122 } 123 }); 124 } 125 126 @Override 127 public ConditionEvaluationResult evaluateExecutionCondition(final ExtensionContext context) { 128 return isActive() ? ConditionEvaluationResult.enabled("provider is active") 129 : ConditionEvaluationResult.disabled("provider is disabled"); 130 } 131 132 private boolean isActive() { 133 return DecoratingEnvironmentProvider.class.isInstance(provider) 134 && DecoratingEnvironmentProvider.class.cast(provider).isActive(); 135 } 136 137 @Override 138 public boolean supportsParameter(final ParameterContext parameterContext, 139 final ExtensionContext extensionContext) throws ParameterResolutionException { 140 return componentExtension != null 141 && componentExtension.supportsParameter(parameterContext, extensionContext); 142 } 143 144 @Override 145 public Object resolveParameter(final ParameterContext parameterContext, final ExtensionContext extensionContext) 146 throws ParameterResolutionException { 147 return componentExtension == null ? null 148 : componentExtension.resolveParameter(parameterContext, extensionContext); 149 } 150 151 @Override 152 public void postProcessTestInstance(final Object o, final ExtensionContext extensionContext) { 153 if (componentExtension != null) { 154 componentExtension.postProcessTestInstance(o, extensionContext); 155 } 156 } 157 } 158}