PageRenderTime 63ms CodeModel.GetById 23ms RepoModel.GetById 1ms app.codeStats 0ms

/configuration/src/test/java/io/airlift/configuration/ConfigurationFactoryTest.java

https://gitlab.com/github-cloud-corp/airlift
Java | 464 lines | 399 code | 49 blank | 16 comment | 0 complexity | d34b39dc457f375bf4c52a655b3e5463 MD5 | raw file
  1. /*
  2. * Copyright 2010 Proofpoint, Inc.
  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 io.airlift.configuration;
  17. import com.google.common.collect.Maps;
  18. import com.google.inject.Binder;
  19. import com.google.inject.CreationException;
  20. import com.google.inject.Guice;
  21. import com.google.inject.Injector;
  22. import com.google.inject.Module;
  23. import com.google.inject.spi.Message;
  24. import io.airlift.testing.Assertions;
  25. import org.testng.Assert;
  26. import org.testng.annotations.Test;
  27. import javax.validation.constraints.Max;
  28. import javax.validation.constraints.Min;
  29. import javax.validation.constraints.NotNull;
  30. import java.util.List;
  31. import java.util.Map;
  32. import java.util.TreeMap;
  33. public class ConfigurationFactoryTest
  34. {
  35. @Test
  36. public void testAnnotatedGettersThrows()
  37. {
  38. Map<String, String> properties = new TreeMap<String, String>();
  39. properties.put("string-value", "some value");
  40. properties.put("boolean-value", "true");
  41. TestMonitor monitor = new TestMonitor();
  42. try {
  43. createInjector(properties, monitor, new Module()
  44. {
  45. public void configure(Binder binder)
  46. {
  47. ConfigurationModule.bindConfig(binder).to(AnnotatedGetter.class);
  48. }
  49. });
  50. Assert.fail("Expected an exception in object creation due to conflicting configuration");
  51. } catch (CreationException e) {
  52. monitor.assertNumberOfErrors(2);
  53. Assertions.assertContainsAllOf(e.getMessage(), "not a valid setter", "getStringValue") ;
  54. Assertions.assertContainsAllOf(e.getMessage(), "not a valid setter", "isBooleanValue") ;
  55. }
  56. }
  57. @Test
  58. public void testAnnotatedSetters()
  59. {
  60. Map<String, String> properties = new TreeMap<String, String>();
  61. properties.put("string-value", "some value");
  62. properties.put("boolean-value", "true");
  63. TestMonitor monitor = new TestMonitor();
  64. Injector injector = createInjector(properties, monitor, new Module()
  65. {
  66. public void configure(Binder binder)
  67. {
  68. ConfigurationModule.bindConfig(binder).to(AnnotatedSetter.class);
  69. }
  70. });
  71. AnnotatedSetter annotatedSetter = injector.getInstance(AnnotatedSetter.class);
  72. monitor.assertNumberOfErrors(0);
  73. monitor.assertNumberOfWarnings(0);
  74. Assert.assertNotNull(annotatedSetter);
  75. Assert.assertEquals(annotatedSetter.getStringValue(), "some value");
  76. Assert.assertEquals(annotatedSetter.isBooleanValue(), true);
  77. }
  78. @Test
  79. public void testConfigurationDespiteLegacyConfig()
  80. {
  81. Map<String, String> properties = new TreeMap<String, String>();
  82. properties.put("string-a", "this is a");
  83. properties.put("string-b", "this is b");
  84. TestMonitor monitor = new TestMonitor();
  85. Injector injector = createInjector(properties, monitor, new Module()
  86. {
  87. public void configure(Binder binder)
  88. {
  89. ConfigurationModule.bindConfig(binder).to(LegacyConfigPresent.class);
  90. }
  91. });
  92. LegacyConfigPresent legacyConfigPresent = injector.getInstance(LegacyConfigPresent.class);
  93. monitor.assertNumberOfErrors(0);
  94. monitor.assertNumberOfWarnings(0);
  95. Assert.assertNotNull(legacyConfigPresent);
  96. Assert.assertEquals(legacyConfigPresent.getStringA(), "this is a");
  97. Assert.assertEquals(legacyConfigPresent.getStringB(), "this is b");
  98. }
  99. @Test
  100. public void testConfigurationThroughLegacyConfig()
  101. {
  102. Map<String, String> properties = new TreeMap<String, String>();
  103. properties.put("string-value", "this is a");
  104. properties.put("string-b", "this is b");
  105. TestMonitor monitor = new TestMonitor();
  106. Injector injector = createInjector(properties, monitor, new Module()
  107. {
  108. public void configure(Binder binder)
  109. {
  110. ConfigurationModule.bindConfig(binder).to(LegacyConfigPresent.class);
  111. }
  112. });
  113. LegacyConfigPresent legacyConfigPresent = injector.getInstance(LegacyConfigPresent.class);
  114. monitor.assertNumberOfErrors(0);
  115. monitor.assertNumberOfWarnings(1);
  116. monitor.assertMatchingWarningRecorded("string-value", "replaced", "Use 'string-a'");
  117. Assert.assertNotNull(legacyConfigPresent);
  118. Assert.assertEquals(legacyConfigPresent.getStringA(), "this is a");
  119. Assert.assertEquals(legacyConfigPresent.getStringB(), "this is b");
  120. }
  121. @Test
  122. public void testConfigurationWithRedundantLegacyConfig()
  123. {
  124. Map<String, String> properties = new TreeMap<String, String>();
  125. properties.put("string-value", "this is a");
  126. properties.put("string-a", "this is a");
  127. properties.put("string-b", "this is b");
  128. TestMonitor monitor = new TestMonitor();
  129. Injector injector = createInjector(properties, monitor, new Module()
  130. {
  131. public void configure(Binder binder)
  132. {
  133. ConfigurationModule.bindConfig(binder).to(LegacyConfigPresent.class);
  134. }
  135. });
  136. LegacyConfigPresent legacyConfigPresent = injector.getInstance(LegacyConfigPresent.class);
  137. monitor.assertNumberOfErrors(0);
  138. monitor.assertNumberOfWarnings(1);
  139. monitor.assertMatchingWarningRecorded("string-value", "replaced", "Use 'string-a'");
  140. Assert.assertNotNull(legacyConfigPresent);
  141. Assert.assertEquals(legacyConfigPresent.getStringA(), "this is a");
  142. Assert.assertEquals(legacyConfigPresent.getStringB(), "this is b");
  143. }
  144. @Test
  145. public void testConfigurationWithConflictingLegacyConfigThrows()
  146. {
  147. Map<String, String> properties = new TreeMap<String, String>();
  148. properties.put("string-value", "this is the old value");
  149. properties.put("string-a", "this is a");
  150. properties.put("string-b", "this is b");
  151. TestMonitor monitor = new TestMonitor();
  152. try {
  153. createInjector(properties, monitor, new Module()
  154. {
  155. public void configure(Binder binder)
  156. {
  157. ConfigurationModule.bindConfig(binder).to(LegacyConfigPresent.class);
  158. }
  159. });
  160. Assert.fail("Expected an exception in object creation due to conflicting configuration");
  161. } catch (CreationException e) {
  162. monitor.assertNumberOfErrors(1);
  163. monitor.assertNumberOfWarnings(1);
  164. monitor.assertMatchingWarningRecorded("string-value", "replaced", "Use 'string-a'");
  165. Assertions.assertContainsAllOf(e.getMessage(), "string-value", "conflicts with property", "string-a") ;
  166. }
  167. }
  168. @Test
  169. public void testConfigurationDespiteDeprecatedConfig()
  170. {
  171. Map<String, String> properties = new TreeMap<String, String>();
  172. properties.put("string-b", "this is b");
  173. TestMonitor monitor = new TestMonitor();
  174. Injector injector = createInjector(properties, monitor, new Module()
  175. {
  176. public void configure(Binder binder)
  177. {
  178. ConfigurationModule.bindConfig(binder).to(DeprecatedConfigPresent.class);
  179. }
  180. });
  181. DeprecatedConfigPresent deprecatedConfigPresent = injector.getInstance(DeprecatedConfigPresent.class);
  182. monitor.assertNumberOfErrors(0);
  183. monitor.assertNumberOfWarnings(0);
  184. Assert.assertNotNull(deprecatedConfigPresent);
  185. Assert.assertEquals(deprecatedConfigPresent.getStringA(), "defaultA");
  186. Assert.assertEquals(deprecatedConfigPresent.getStringB(), "this is b");
  187. }
  188. @Test
  189. public void testConfigurationThroughDeprecatedConfig()
  190. {
  191. Map<String, String> properties = new TreeMap<String, String>();
  192. properties.put("string-a", "this is a");
  193. properties.put("string-b", "this is b");
  194. TestMonitor monitor = new TestMonitor();
  195. Injector injector = createInjector(properties, monitor, new Module()
  196. {
  197. public void configure(Binder binder)
  198. {
  199. ConfigurationModule.bindConfig(binder).to(DeprecatedConfigPresent.class);
  200. }
  201. });
  202. DeprecatedConfigPresent deprecatedConfigPresent = injector.getInstance(DeprecatedConfigPresent.class);
  203. monitor.assertNumberOfErrors(0);
  204. monitor.assertNumberOfWarnings(1);
  205. monitor.assertMatchingWarningRecorded("string-a", "deprecated and should not be used");
  206. Assert.assertNotNull(deprecatedConfigPresent);
  207. Assert.assertEquals(deprecatedConfigPresent.getStringA(), "this is a");
  208. Assert.assertEquals(deprecatedConfigPresent.getStringB(), "this is b");
  209. }
  210. @Test
  211. public void testDefunctPropertyInConfigThrows()
  212. {
  213. Map<String, String> properties = Maps.newTreeMap();
  214. properties.put("string-value", "this is a");
  215. properties.put("defunct-value", "this shouldn't work");
  216. TestMonitor monitor = new TestMonitor();
  217. try {
  218. createInjector(properties, monitor, new Module()
  219. {
  220. public void configure(Binder binder)
  221. {
  222. ConfigurationModule.bindConfig(binder).to(DefunctConfigPresent.class);
  223. }
  224. });
  225. Assert.fail("Expected an exception in object creation due to use of defunct config");
  226. } catch (CreationException e) {
  227. monitor.assertNumberOfErrors(1);
  228. monitor.assertNumberOfWarnings(0);
  229. monitor.assertMatchingErrorRecorded("Defunct property", "'defunct-value", "cannot be configured");
  230. }
  231. }
  232. @Test
  233. public void testSuccessfulBeanValidation()
  234. {
  235. Map<String, String> properties = Maps.newHashMap();
  236. properties.put("string-value", "has a value");
  237. properties.put("int-value", "50");
  238. TestMonitor monitor = new TestMonitor();
  239. Injector injector = createInjector(properties, monitor, new Module()
  240. {
  241. public void configure(Binder binder)
  242. {
  243. ConfigurationModule.bindConfig(binder).to(BeanValidationClass.class);
  244. }
  245. });
  246. BeanValidationClass beanValidationClass = injector.getInstance(BeanValidationClass.class);
  247. monitor.assertNumberOfErrors(0);
  248. monitor.assertNumberOfWarnings(0);
  249. Assert.assertNotNull(beanValidationClass);
  250. Assert.assertEquals(beanValidationClass.getStringValue(), "has a value");
  251. Assert.assertEquals(beanValidationClass.getIntValue(), 50);
  252. }
  253. @Test
  254. public void testFailedBeanValidation()
  255. {
  256. Map<String, String> properties = Maps.newHashMap();
  257. // string-value left at invalid default
  258. properties.put("int-value", "5000"); // out of range
  259. TestMonitor monitor = new TestMonitor();
  260. try {
  261. Injector injector = createInjector(properties, monitor, new Module()
  262. {
  263. public void configure(Binder binder)
  264. {
  265. ConfigurationModule.bindConfig(binder).to(BeanValidationClass.class);
  266. }
  267. });
  268. } catch (CreationException e) {
  269. monitor.assertNumberOfErrors(2);
  270. monitor.assertNumberOfWarnings(0);
  271. monitor.assertMatchingErrorRecorded("Constraint violation", "intValue", "must be less than or equal to 100", "BeanValidationClass");
  272. monitor.assertMatchingErrorRecorded("Constraint violation", "stringValue", "may not be null", "BeanValidationClass");
  273. }
  274. }
  275. private Injector createInjector(Map<String, String> properties, TestMonitor monitor, Module module)
  276. {
  277. ConfigurationFactory configurationFactory = new ConfigurationFactory(properties, monitor);
  278. List<Message> messages = new ConfigurationValidator(configurationFactory, null).validate(module);
  279. return Guice.createInjector(new ConfigurationModule(configurationFactory), module, new ValidationErrorModule(messages));
  280. }
  281. public static class AnnotatedGetter {
  282. private String stringValue;
  283. private boolean booleanValue;
  284. @Config("string-value")
  285. public String getStringValue()
  286. {
  287. return stringValue;
  288. }
  289. public void setStringValue(String stringValue)
  290. {
  291. this.stringValue = stringValue;
  292. }
  293. @Config("boolean-value")
  294. public boolean isBooleanValue()
  295. {
  296. return booleanValue;
  297. }
  298. public void setBooleanValue(boolean booleanValue)
  299. {
  300. this.booleanValue = booleanValue;
  301. }
  302. }
  303. public static class AnnotatedSetter {
  304. private String stringValue;
  305. private boolean booleanValue;
  306. public String getStringValue()
  307. {
  308. return stringValue;
  309. }
  310. @Config("string-value")
  311. public void setStringValue(String stringValue)
  312. {
  313. this.stringValue = stringValue;
  314. }
  315. public boolean isBooleanValue()
  316. {
  317. return booleanValue;
  318. }
  319. @Config("boolean-value")
  320. public void setBooleanValue(boolean booleanValue)
  321. {
  322. this.booleanValue = booleanValue;
  323. }
  324. }
  325. public static class LegacyConfigPresent
  326. {
  327. private String stringA = "defaultA";
  328. private String stringB = "defaultB";
  329. public String getStringA()
  330. {
  331. return stringA;
  332. }
  333. @Config("string-a")
  334. @LegacyConfig("string-value")
  335. public void setStringA(String stringValue)
  336. {
  337. this.stringA = stringValue;
  338. }
  339. public String getStringB()
  340. {
  341. return stringB;
  342. }
  343. @Config("string-b")
  344. public void setStringB(String stringValue)
  345. {
  346. this.stringB = stringValue;
  347. }
  348. }
  349. public static class DeprecatedConfigPresent
  350. {
  351. private String stringA = "defaultA";
  352. private String stringB = "defaultB";
  353. @Deprecated
  354. public String getStringA()
  355. {
  356. return stringA;
  357. }
  358. @Deprecated
  359. @Config("string-a")
  360. public void setStringA(String stringValue)
  361. {
  362. this.stringA = stringValue;
  363. }
  364. public String getStringB()
  365. {
  366. return stringB;
  367. }
  368. @Config("string-b")
  369. public void setStringB(String stringValue)
  370. {
  371. this.stringB = stringValue;
  372. }
  373. }
  374. @DefunctConfig("defunct-value")
  375. public static class DefunctConfigPresent
  376. {
  377. private String stringValue;
  378. private boolean booleanValue;
  379. public String getStringValue()
  380. {
  381. return stringValue;
  382. }
  383. @Config("string-value")
  384. public void setStringValue(String stringValue)
  385. {
  386. this.stringValue = stringValue;
  387. }
  388. }
  389. public static class BeanValidationClass
  390. {
  391. @NotNull
  392. private String stringValue = null;
  393. private int myIntValue;
  394. public String getStringValue()
  395. {
  396. return stringValue;
  397. }
  398. @Config("string-value")
  399. public void setStringValue(String value)
  400. {
  401. this.stringValue = value;
  402. }
  403. @Min(1)
  404. @Max(100)
  405. public int getIntValue()
  406. {
  407. return myIntValue;
  408. }
  409. @Config("int-value")
  410. public void setIntValue(int value)
  411. {
  412. this.myIntValue = value;
  413. }
  414. }
  415. }