| /* |
| * 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 |
| * |
| * 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 org.apache.ignite.internal.testframework; |
| |
| import java.lang.annotation.ElementType; |
| import java.lang.annotation.Repeatable; |
| import java.lang.annotation.Retention; |
| import java.lang.annotation.RetentionPolicy; |
| import java.lang.annotation.Target; |
| import org.junit.jupiter.api.AfterEach; |
| import org.junit.jupiter.api.BeforeEach; |
| |
| /** |
| * Annotation that defines a scope with specific system property configured.<br/> |
| * <br/> |
| * Might be used on class level or on method level. Multiple annotations might be applied to the same class/method.<br/> |
| * <br/> |
| * In short, these two approaches are basically equivalent:<br/> |
| * <br/> |
| * Short: |
| * <pre>{@code @WithSystemProperty(key = "name", value = "val") |
| * public class SomeTest { |
| * } |
| * }</pre> |
| * Long: |
| * <pre>{@code public class SomeTest { |
| * private static Object oldVal; |
| * |
| * @BeforeClass |
| * public static void beforeClass() { |
| * oldVal = System.getProperty("name"); |
| * |
| * System.setProperty("name", "val"); |
| * } |
| * |
| * @AfterClass |
| * public static void afterClass() { |
| * if (oldVal == null) |
| * System.clearProperty("name"); |
| * else |
| * System.setProperty("name", oldVal); |
| * } |
| * } |
| * }</pre> |
| * <p> |
| * Same applies to methods with the difference that annotation translates into something like {@link BeforeEach} and |
| * {@link AfterEach}. |
| * <br/><br/> |
| * <pre>{@code public class SomeTest { |
| * @Test |
| * @WithSystemProperty(key = "name", value = "val") |
| * public void test() { |
| * // ... |
| * } |
| * } |
| * }</pre> |
| * is equivalent to: |
| * <pre>{@code public class SomeTest { |
| * @Test |
| * public void test() { |
| * Object oldVal = System.getProperty("name"); |
| * |
| * try { |
| * // ... |
| * } |
| * finally { |
| * if (oldVal == null) |
| * System.clearProperty("name"); |
| * else |
| * System.setProperty("name", oldVal); |
| * } |
| * } |
| * } |
| * }</pre> |
| * For class level annotation it applies system properties for the whole class hierarchy (ignoring interfaces, there's |
| * no linearization implemented). More specific classes have higher priority and set their properties last. It all |
| * starts with {@link Object} which, of course, is not annotated.<br/> |
| * <br/> |
| * Test methods do not inherit their annotations from overridden methods of super class.<br/> |
| * <br/> |
| * If more than one annotation is presented on class/method then they will be applied in the same order as they |
| * appear in code. It is achieved with the help of {@link Repeatable} feature of Java annotations - |
| * {@link SystemPropertiesList} is automatically generated in such cases. |
| * For that reason it is not recommended using {@link SystemPropertiesList} directly. |
| * |
| * @see System#setProperty(String, String) |
| * @see SystemPropertiesExtension |
| * @see SystemPropertiesList |
| */ |
| @Repeatable(SystemPropertiesList.class) |
| @Retention(RetentionPolicy.RUNTIME) |
| @Target({ElementType.TYPE, ElementType.METHOD}) |
| public @interface WithSystemProperty { |
| /** The name of the system property. */ |
| String key(); |
| |
| /** The value of the system property. */ |
| String value(); |
| } |