You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

CvalCheckerTest.java 14KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342
  1. /*
  2. * Copyright 2000-2014 Vaadin Ltd.
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License"); you may not
  5. * use this file except in compliance with the License. You may obtain a copy of
  6. * 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, WITHOUT
  12. * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
  13. * License for the specific language governing permissions and limitations under
  14. * the License.
  15. */
  16. package com.vaadin.tools;
  17. import static com.vaadin.tools.CvalAddonsChecker.VAADIN_ADDON_LICENSE;
  18. import static com.vaadin.tools.CvalAddonsChecker.VAADIN_ADDON_NAME;
  19. import static com.vaadin.tools.CvalAddonsChecker.VAADIN_ADDON_TITLE;
  20. import static com.vaadin.tools.CvalAddonsChecker.VAADIN_ADDON_VERSION;
  21. import static com.vaadin.tools.CvalChecker.GRACE_DAYS_MSECS;
  22. import static com.vaadin.tools.CvalChecker.cacheLicenseInfo;
  23. import static com.vaadin.tools.CvalChecker.deleteCache;
  24. import static com.vaadin.tools.CvalChecker.parseJson;
  25. import java.io.ByteArrayOutputStream;
  26. import java.io.File;
  27. import java.io.FileDescriptor;
  28. import java.io.FileOutputStream;
  29. import java.io.IOException;
  30. import java.io.PrintStream;
  31. import java.lang.reflect.Method;
  32. import java.net.URL;
  33. import java.net.URLClassLoader;
  34. import java.util.jar.JarOutputStream;
  35. import java.util.jar.Manifest;
  36. import java.util.prefs.Preferences;
  37. import org.junit.Assert;
  38. import org.junit.Before;
  39. import org.junit.Test;
  40. import com.vaadin.tools.CvalChecker.CvalInfo;
  41. import com.vaadin.tools.CvalChecker.CvalServer;
  42. import com.vaadin.tools.CvalChecker.InvalidCvalException;
  43. import com.vaadin.tools.CvalChecker.UnreachableCvalServerException;
  44. /**
  45. * The CvalChecker test.
  46. */
  47. public class CvalCheckerTest {
  48. static final String productNameCval = "test.cval";
  49. static final String productTitleCval = "Vaadin Test";
  50. static final String productNameAgpl = "test.agpl";
  51. static final String productTitleAgpl = "Vaadin Test";
  52. static final String productNameApache = "test.apache";
  53. static final String VALID_KEY = "valid";
  54. static final String INVALID_KEY = "invalid";
  55. static final String responseJson = "{'licenseKey':'" + VALID_KEY + "',"
  56. + "'licensee':'Test User','type':'normal',"
  57. + "'expiredEpoch':'1893511225000'," + "'product':{'name':'"
  58. + productNameCval + "', 'version': 2}}";
  59. private static ByteArrayOutputStream outContent;
  60. // A provider returning a valid license if productKey is valid or null if
  61. // invalid
  62. static final CvalServer validLicenseProvider = new CvalServer() {
  63. @Override
  64. String askServer(String productName, String productKey, int timeout) {
  65. return VALID_KEY.equals(productKey) ? responseJson : null;
  66. }
  67. };
  68. // A provider returning a valid evaluation license
  69. static final CvalServer validEvaluationLicenseProvider = new CvalServer() {
  70. @Override
  71. String askServer(String productName, String productKey, int timeout) {
  72. return responseJson.replace("normal", "evaluation");
  73. }
  74. };
  75. // A provider returning an expired license with a server message
  76. static final CvalServer expiredLicenseProviderWithMessage = new CvalServer() {
  77. @Override
  78. String askServer(String productName, String productKey, int timeout) {
  79. return responseJson
  80. .replace("'expired",
  81. "'message':'Custom\\\\nServer\\\\nMessage','expired':true,'expired");
  82. }
  83. };
  84. // A provider returning an expired license with a server message
  85. static final CvalServer expiredLicenseProvider = new CvalServer() {
  86. @Override
  87. String askServer(String productName, String productKey, int timeout) {
  88. return responseJson.replace("'expired", "'expired':true,'expired");
  89. }
  90. };
  91. // A provider returning an expired epoch license
  92. static final CvalServer expiredEpochLicenseProvider = new CvalServer() {
  93. @Override
  94. String askServer(String productName, String productKey, int timeout) {
  95. long ts = System.currentTimeMillis() - GRACE_DAYS_MSECS - 1000;
  96. return responseJson.replace("1893511225000", "" + ts);
  97. }
  98. };
  99. // A provider returning an unlimited license
  100. static final CvalServer unlimitedLicenseProvider = new CvalServer() {
  101. @Override
  102. String askServer(String productName, String productKey, int timeout) {
  103. return responseJson.replaceFirst("1893511225000", "");
  104. }
  105. };
  106. // An unreachable provider
  107. static final CvalServer unreachableLicenseProvider = new CvalServer() {
  108. @Override
  109. String askServer(String productName, String productKey, int timeout)
  110. throws IOException {
  111. // Normally there is no route for this ip in public routers, so we
  112. // should get a timeout.
  113. licenseUrl = "http://localhost:9999/";
  114. return super.askServer(productName, productKey, 1000);
  115. }
  116. };
  117. private CvalChecker licenseChecker;
  118. private String licenseName;
  119. @Before
  120. public void setup() {
  121. licenseChecker = new CvalChecker()
  122. .setLicenseProvider(validLicenseProvider);
  123. licenseName = CvalChecker.computeLicenseName(productNameCval);
  124. System.getProperties().remove(licenseName);
  125. deleteCache(productNameCval);
  126. }
  127. @Test
  128. public void testValidateProduct() throws Exception {
  129. deleteCache(productNameCval);
  130. // If the license key in our environment is null, throw an exception
  131. try {
  132. licenseChecker.validateProduct(productNameCval, "2.1",
  133. productTitleCval);
  134. Assert.fail();
  135. } catch (InvalidCvalException expected) {
  136. Assert.assertEquals(productNameCval, expected.name);
  137. }
  138. Assert.assertFalse(cacheExists(productNameCval));
  139. // If the license key is empty, throw an exception
  140. System.setProperty(licenseName, "");
  141. try {
  142. licenseChecker.validateProduct(productNameCval, "2.1",
  143. productTitleCval);
  144. Assert.fail();
  145. } catch (InvalidCvalException expected) {
  146. Assert.assertEquals(productNameCval, expected.name);
  147. }
  148. Assert.assertFalse(cacheExists(productNameCval));
  149. // If license key is invalid, throw an exception
  150. System.setProperty(licenseName, "invalid");
  151. try {
  152. licenseChecker.validateProduct(productNameCval, "2.1",
  153. productTitleCval);
  154. Assert.fail();
  155. } catch (InvalidCvalException expected) {
  156. Assert.assertEquals(productNameCval, expected.name);
  157. }
  158. Assert.assertFalse(cacheExists(productNameCval));
  159. // Fail if version is bigger
  160. System.setProperty(licenseName, VALID_KEY);
  161. try {
  162. licenseChecker.validateProduct(productNameCval, "3.0",
  163. productTitleCval);
  164. Assert.fail();
  165. } catch (InvalidCvalException expected) {
  166. Assert.assertEquals(productNameCval, expected.name);
  167. }
  168. Assert.assertFalse(cacheExists(productNameCval));
  169. // Success if license key and version are valid
  170. System.setProperty(licenseName, VALID_KEY);
  171. licenseChecker
  172. .validateProduct(productNameCval, "2.1", productTitleCval);
  173. Assert.assertTrue(cacheExists(productNameCval));
  174. // Success if license and cache file are valid, although the license
  175. // server is offline
  176. licenseChecker.setLicenseProvider(unreachableLicenseProvider);
  177. licenseChecker
  178. .validateProduct(productNameCval, "2.1", productTitleCval);
  179. Assert.assertTrue(cacheExists(productNameCval));
  180. // Fail if license key changes although cache file were validated
  181. // previously and it is ok, we are offline
  182. try {
  183. System.setProperty(licenseName, INVALID_KEY);
  184. licenseChecker.validateProduct(productNameCval, "2.1",
  185. productTitleCval);
  186. Assert.fail();
  187. } catch (InvalidCvalException expected) {
  188. Assert.fail();
  189. } catch (UnreachableCvalServerException expected) {
  190. Assert.assertEquals(productNameCval, expected.name);
  191. }
  192. Assert.assertFalse(cacheExists(productNameCval));
  193. // Fail with unreachable exception if license has never verified and
  194. // server is offline
  195. try {
  196. System.setProperty(licenseName, VALID_KEY);
  197. licenseChecker.validateProduct(productNameCval, "2.1",
  198. productTitleCval);
  199. Assert.fail();
  200. } catch (InvalidCvalException expected) {
  201. Assert.fail();
  202. } catch (UnreachableCvalServerException expected) {
  203. Assert.assertEquals(productNameCval, expected.name);
  204. }
  205. Assert.assertFalse(cacheExists(productNameCval));
  206. // Fail when expired flag comes in the server response, although the
  207. // expired is valid.
  208. deleteCache(productNameCval);
  209. licenseChecker.setLicenseProvider(expiredLicenseProviderWithMessage);
  210. try {
  211. licenseChecker.validateProduct(productNameCval, "2.1",
  212. productTitleCval);
  213. Assert.fail();
  214. } catch (InvalidCvalException expected) {
  215. Assert.assertEquals(productNameCval, expected.name);
  216. // Check that we use server customized message if it comes
  217. Assert.assertTrue(expected.getMessage().contains("Custom"));
  218. }
  219. Assert.assertTrue(cacheExists(productNameCval));
  220. // Check an unlimited license
  221. licenseChecker.setLicenseProvider(unlimitedLicenseProvider);
  222. licenseChecker
  223. .validateProduct(productNameCval, "2.1", productTitleCval);
  224. Assert.assertTrue(cacheExists(productNameCval));
  225. // Fail if expired flag does not come, but expired epoch is in the past
  226. System.setProperty(licenseName, VALID_KEY);
  227. deleteCache(productNameCval);
  228. licenseChecker.setLicenseProvider(expiredEpochLicenseProvider);
  229. try {
  230. licenseChecker.validateProduct(productNameCval, "2.1",
  231. productTitleCval);
  232. Assert.fail();
  233. } catch (InvalidCvalException expected) {
  234. Assert.assertEquals(productNameCval, expected.name);
  235. }
  236. Assert.assertTrue(cacheExists(productNameCval));
  237. }
  238. /*
  239. * Creates a new .jar file with a MANIFEST.MF with all vaadin license info
  240. * attributes set, and add the .jar to the classpath
  241. */
  242. static void addLicensedJarToClasspath(String productName, String licenseType)
  243. throws Exception {
  244. // Create a manifest with Vaadin CVAL license
  245. Manifest testManifest = new Manifest();
  246. testManifest.getMainAttributes().putValue("Manifest-Version", "1.0");
  247. testManifest.getMainAttributes().putValue(VAADIN_ADDON_LICENSE,
  248. licenseType);
  249. testManifest.getMainAttributes().putValue(VAADIN_ADDON_NAME,
  250. productName);
  251. testManifest.getMainAttributes().putValue(VAADIN_ADDON_TITLE,
  252. "Test " + productName);
  253. testManifest.getMainAttributes().putValue(VAADIN_ADDON_VERSION, "2");
  254. // Create a temporary Jar
  255. String tmpDir = System.getProperty("java.io.tmpdir");
  256. File testJarFile = new File(tmpDir + "vaadin." + productName + ".jar");
  257. testJarFile.deleteOnExit();
  258. JarOutputStream target = new JarOutputStream(new FileOutputStream(
  259. testJarFile), testManifest);
  260. target.close();
  261. // Add the new jar to our classpath (use reflection)
  262. URL url = new URL("file://" + testJarFile.getAbsolutePath());
  263. final Method addURL = URLClassLoader.class.getDeclaredMethod("addURL",
  264. new Class[] { URL.class });
  265. addURL.setAccessible(true);
  266. final URLClassLoader urlClassLoader = (URLClassLoader) Thread
  267. .currentThread().getContextClassLoader();
  268. addURL.invoke(urlClassLoader, new Object[] { url });
  269. }
  270. static boolean cacheExists(String productName) {
  271. return cachedPreferences(productName) != null;
  272. }
  273. static String cachedPreferences(String productName) {
  274. // ~/Library/Preferences/com.apple.java.util.prefs.plist
  275. // .java/.userPrefs/com/google/gwt/dev/shell/prefs.xml
  276. // HKEY_CURRENT_USER\SOFTWARE\JavaSoft\Prefs
  277. Preferences p = Preferences.userNodeForPackage(CvalInfo.class);
  278. return p.get(productName, null);
  279. }
  280. static void saveCache(String productName, String key, Boolean expired,
  281. Long expireTs, String type) {
  282. String json = responseJson.replace(productNameCval, productName);
  283. if (expired != null && expired) {
  284. expireTs = System.currentTimeMillis() - GRACE_DAYS_MSECS - 1000;
  285. }
  286. if (expireTs != null) {
  287. json = json.replace("1893511225000", "" + expireTs);
  288. }
  289. if (key != null) {
  290. json = json.replace(VALID_KEY, key);
  291. }
  292. if (type != null) {
  293. json = json.replace("normal", type);
  294. }
  295. cacheLicenseInfo(parseJson(json));
  296. }
  297. static void captureSystemOut() {
  298. outContent = new ByteArrayOutputStream();
  299. System.setOut(new PrintStream(outContent));
  300. }
  301. static String readSystemOut() {
  302. restoreSystemOut();
  303. return outContent.toString();
  304. }
  305. static void restoreSystemOut() {
  306. System.setOut(new PrintStream(new FileOutputStream(FileDescriptor.out)));
  307. }
  308. }