Skip to content
This repository was archived by the owner on Apr 5, 2022. It is now read-only.

Commit 0ef5c92

Browse files
committed
SHDP-318 Fix composed annotations for tests
- MiniYarnClusterTest breaks with Spring 4.0.3 is now fixed per discussion in SPR-11641. - Composed annotation and a way a custom extended annotation should be created is refactored to follow Spring 4.x logic. - More tests to verify this behaviour. - YarnClusterInjectUtils now using annotationAttributes instead of annotation itself. This will automatically handle cases where attribute is re-defined in a custom annotation or generally defined in a composed annotation.
1 parent 95a329b commit 0ef5c92

File tree

5 files changed

+216
-12
lines changed

5 files changed

+216
-12
lines changed

spring-yarn/spring-yarn-test/src/main/java/org/springframework/yarn/test/context/MiniYarnClusterTest.java

Lines changed: 81 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,11 @@
2020
import java.lang.annotation.RetentionPolicy;
2121
import java.lang.annotation.Target;
2222

23+
import org.springframework.context.ApplicationContextInitializer;
24+
import org.springframework.context.ConfigurableApplicationContext;
2325
import org.springframework.context.annotation.Configuration;
2426
import org.springframework.test.context.ContextConfiguration;
27+
import org.springframework.yarn.test.YarnTestSystemConstants;
2528

2629
/**
2730
* Composed annotation having @{@link MiniYarnCluster},
@@ -43,14 +46,31 @@
4346
* </pre>
4447
*
4548
* <p>
46-
* Drawback of using a composed annotation like this is that the
47-
* &#064;{@link Configuration} is then applied from an annotation
48-
* class itself and user can't no longer add a static &#064;{@link Configuration}
49-
* class in a test class itself and expect Spring to pick it up from
50-
* there which is a normal behaviour in Spring testing support.
51-
* <p>
5249
* If user wants to use a simple composed annotation and use a
53-
* custom &#064;{@link Configuration}, one can simply duplicate
50+
* custom &#064;{@link Configuration}, there are two options.
51+
* <p>
52+
* Use classes attribute with &#064;{@link MiniYarnCluster} to override
53+
* default context configuration class.
54+
* <p>
55+
* <pre>
56+
* &#064;MiniYarnClusterTest(classes = AppTests.Config.class)
57+
* public class AppTests extends AbstractBootYarnClusterTests {
58+
*
59+
* &#064;Test
60+
* public void testApp() {
61+
* // test methods
62+
* }
63+
*
64+
* &#064;Configuration
65+
* public static class Config {
66+
* // custom config
67+
* }
68+
*
69+
* }
70+
* </pre>
71+
*
72+
* <p>
73+
* If more functionality is needed for composed annotation, one can simply duplicate
5474
* functionality of this &#064;{@code MiniYarnClusterTest} annotation.
5575
* <p>
5676
* <pre>
@@ -60,6 +80,8 @@
6080
* &#064;MiniYarnCluster
6181
* public &#064;interface CustomMiniYarnClusterTest {
6282
*
83+
* Class<?>[] classes() default { CustomMiniYarnClusterTest.Config.class };
84+
*
6385
* &#064;Configuration
6486
* public static class Config {
6587
*
@@ -86,4 +108,56 @@
86108
public static class Config {
87109
}
88110

111+
/**
112+
* @see MiniYarnCluster#configName()
113+
*/
114+
String configName() default YarnTestSystemConstants.DEFAULT_ID_MINIYARNCLUSTER_CONFIG;
115+
116+
/**
117+
* @see MiniYarnCluster#clusterName()
118+
*/
119+
String clusterName() default YarnTestSystemConstants.DEFAULT_ID_MINIYARNCLUSTER;
120+
121+
/**
122+
* @see MiniYarnCluster#id()
123+
*/
124+
String id() default YarnTestSystemConstants.DEFAULT_ID_CLUSTER;
125+
126+
/**
127+
* @see MiniYarnCluster#nodes()
128+
*/
129+
int nodes() default 1;
130+
131+
/**
132+
* @see ContextConfiguration#locations()
133+
*/
134+
String[] locations() default {};
135+
136+
/**
137+
* Defaults to empty configuration.
138+
*
139+
* @see ContextConfiguration#classes()
140+
*/
141+
Class<?>[] classes() default { MiniYarnClusterTest.Config.class };
142+
143+
/**
144+
* @see ContextConfiguration#initializers()
145+
*/
146+
Class<? extends ApplicationContextInitializer<? extends ConfigurableApplicationContext>>[] initializers() default {};
147+
148+
/**
149+
* @see ContextConfiguration#inheritLocations()
150+
*/
151+
boolean inheritLocations() default true;
152+
153+
/**
154+
* @see ContextConfiguration#inheritInitializers()
155+
*/
156+
boolean inheritInitializers() default true;
157+
158+
/**
159+
* @see ContextConfiguration#name()
160+
*/
161+
String name() default "";
162+
89163
}

spring-yarn/spring-yarn-test/src/main/java/org/springframework/yarn/test/context/YarnClusterInjectUtils.java

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -43,11 +43,10 @@ public static void handleClusterInject(GenericApplicationContext context,
4343
testClass, MiniYarnCluster.class);
4444

4545
if (annotationDescriptor != null && annotationDescriptor.getAnnotation() != null) {
46-
MiniYarnCluster annotation = annotationDescriptor.getAnnotation();
47-
String clusterName = annotation.clusterName();
48-
String configName = annotation.configName();
49-
String id = annotation.id();
50-
int nodeCount = annotation.nodes();
46+
String clusterName = annotationDescriptor.getAnnotationAttributes().getString("clusterName");
47+
String configName = annotationDescriptor.getAnnotationAttributes().getString("configName");
48+
String id = annotationDescriptor.getAnnotationAttributes().getString("id");
49+
int nodeCount = annotationDescriptor.getAnnotationAttributes().getNumber("nodes");
5150

5251
BeanDefinitionBuilder builder = BeanDefinitionBuilder
5352
.genericBeanDefinition(ClusterDelegatingFactoryBean.class);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
/*
2+
* Copyright 2014 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package org.springframework.yarn.test.context;
17+
18+
import static org.junit.Assert.assertFalse;
19+
import static org.junit.Assert.assertNotNull;
20+
import static org.junit.Assert.assertTrue;
21+
22+
import javax.annotation.Resource;
23+
24+
import org.apache.hadoop.conf.Configuration;
25+
import org.junit.Test;
26+
import org.junit.runner.RunWith;
27+
import org.springframework.beans.factory.annotation.Autowired;
28+
import org.springframework.context.ApplicationContext;
29+
import org.springframework.context.annotation.Bean;
30+
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
31+
32+
/**
33+
* Tests for custom composed annotations.
34+
*
35+
* @author Janne Valkealahti
36+
*
37+
*/
38+
@RunWith(SpringJUnit4ClassRunner.class)
39+
@CustomMiniYarnClusterTest(classes=ComposedAnnotationCustomizeTests.Config.class)
40+
public class ComposedAnnotationCustomizeTests {
41+
42+
@Autowired
43+
private ApplicationContext ctx;
44+
45+
@Resource(name = "yarnConfiguration")
46+
Configuration configuration;
47+
48+
@Test
49+
public void testLoaderAndConfig() {
50+
assertNotNull(ctx);
51+
assertTrue(ctx.containsBean("yarnCluster"));
52+
assertTrue(ctx.containsBean("yarnConfiguration"));
53+
// bean from CustomMiniYarnClusterTest should not get created
54+
assertFalse(ctx.containsBean("myCustomBean"));
55+
assertTrue(ctx.containsBean("myCustomLocalBean"));
56+
Configuration config = (Configuration) ctx.getBean("yarnConfiguration");
57+
assertNotNull(config);
58+
}
59+
60+
@org.springframework.context.annotation.Configuration
61+
public static class Config {
62+
@Bean
63+
public String myCustomLocalBean() {
64+
return "myCustomLocalBean";
65+
}
66+
}
67+
68+
}

spring-yarn/spring-yarn-test/src/test/java/org/springframework/yarn/test/context/CustomMiniYarnClusterTest.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,8 @@
3737
@MiniYarnCluster
3838
public @interface CustomMiniYarnClusterTest {
3939

40+
Class<?>[] classes() default { CustomMiniYarnClusterTest.Config.class };
41+
4042
@Configuration
4143
public static class Config {
4244
@Bean
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
/*
2+
* Copyright 2014 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package org.springframework.yarn.test.context;
17+
18+
import static org.junit.Assert.assertNotNull;
19+
import static org.junit.Assert.assertTrue;
20+
21+
import org.apache.hadoop.conf.Configuration;
22+
import org.junit.Test;
23+
import org.junit.runner.RunWith;
24+
import org.springframework.beans.factory.annotation.Autowired;
25+
import org.springframework.context.ApplicationContext;
26+
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
27+
28+
/**
29+
* Tests using {@link MiniYarnClusterTest}.
30+
*
31+
* @author Janne Valkealahti
32+
*
33+
*/
34+
@RunWith(SpringJUnit4ClassRunner.class)
35+
@MiniYarnClusterTest(
36+
classes = MiniYarnClusterTestOverrideTests.Config.class,
37+
configName = "yarnCustomConfiguration",
38+
clusterName = "yarnCustomCluster",
39+
id = "custom")
40+
public class MiniYarnClusterTestOverrideTests {
41+
42+
@Autowired
43+
private ApplicationContext ctx;
44+
45+
@Test
46+
public void testLoaderAndConfig() {
47+
assertNotNull(ctx);
48+
assertTrue(ctx.containsBean("yarnCustomCluster"));
49+
assertTrue(ctx.containsBean("yarnCustomConfiguration"));
50+
Configuration config = (Configuration) ctx.getBean("yarnCustomConfiguration");
51+
assertNotNull(config);
52+
}
53+
54+
@org.springframework.context.annotation.Configuration
55+
public static class Config {
56+
// we're testing custom name so need to change config
57+
// so that spring-test doesn't cache our context and
58+
// we don't want to dirty context for all tests.
59+
}
60+
61+
}

0 commit comments

Comments
 (0)