From a515a2fb5924b4840e00cec6708442c99421bae4 Mon Sep 17 00:00:00 2001 From: Marcel Pfotenhauer Date: Tue, 25 Aug 2020 15:22:36 +0200 Subject: [PATCH 1/9] #135: update to Java 11 --- pom.xml | 5 +++-- .../neodymium/module/StatementBuilder.java | 19 ++++++++++++++++++- .../testclasses/datautils/DataUtilsTests.java | 6 +++--- .../datautils/DataUtilsTestsXml.java | 6 +++--- 4 files changed, 27 insertions(+), 9 deletions(-) diff --git a/pom.xml b/pom.xml index 4a6327440..19615381a 100644 --- a/pom.xml +++ b/pom.xml @@ -51,8 +51,8 @@ UTF-8 - 1.8 - 1.8 + 11 + 11 2.22.2 2.13.3 5.7.0 @@ -135,6 +135,7 @@ 8 + false diff --git a/src/main/java/com/xceptance/neodymium/module/StatementBuilder.java b/src/main/java/com/xceptance/neodymium/module/StatementBuilder.java index 035168ced..b162014c6 100644 --- a/src/main/java/com/xceptance/neodymium/module/StatementBuilder.java +++ b/src/main/java/com/xceptance/neodymium/module/StatementBuilder.java @@ -3,6 +3,7 @@ import java.lang.annotation.Annotation; import java.lang.annotation.Repeatable; import java.lang.reflect.AnnotatedElement; +import java.lang.reflect.InvocationTargetException; import java.util.Arrays; import java.util.LinkedList; import java.util.List; @@ -25,7 +26,7 @@ public static T instantiate(Class clazz) { try { - return clazz.newInstance(); + return clazz.getDeclaredConstructor().newInstance(); } catch (InstantiationException e) { @@ -35,6 +36,22 @@ public static T instantiate(Class clazz) { throw new RuntimeException(e); } + catch (IllegalArgumentException e) + { + throw new RuntimeException(e); + } + catch (InvocationTargetException e) + { + throw new RuntimeException(e); + } + catch (NoSuchMethodException e) + { + throw new RuntimeException(e); + } + catch (SecurityException e) + { + throw new RuntimeException(e); + } } @SuppressWarnings("unchecked") diff --git a/src/test/java/com/xceptance/neodymium/testclasses/datautils/DataUtilsTests.java b/src/test/java/com/xceptance/neodymium/testclasses/datautils/DataUtilsTests.java index 9de8d1baf..89f1899a3 100644 --- a/src/test/java/com/xceptance/neodymium/testclasses/datautils/DataUtilsTests.java +++ b/src/test/java/com/xceptance/neodymium/testclasses/datautils/DataUtilsTests.java @@ -210,7 +210,7 @@ public void testGetClass() throws Exception Assert.assertEquals("1234567890", testCompound.getClubCardNumber()); Assert.assertEquals(null, testCompound.getNotSet()); Assert.assertEquals(null, testCompound.getNullValue()); - Assert.assertEquals(new Double(12.34), testCompound.getNumberValue()); + Assert.assertEquals(Double.valueOf(12.34), testCompound.getNumberValue()); Assert.assertEquals("containing strange things like spaces and äüø", testCompound.getDescription()); Assert.assertEquals("4111111111111111", testCompound.getCreditCard().getCardNumber()); Assert.assertEquals("123", testCompound.getCreditCard().getCcv()); @@ -235,7 +235,7 @@ public void testGetClass() throws Exception public void testGetByPath() throws Exception { Double numberValue = DataUtils.get("$.numberValue", Double.class); - Assert.assertEquals(new Double(12.34), numberValue); + Assert.assertEquals(Double.valueOf(12.34), numberValue); String description = DataUtils.get("$.description", String.class); Assert.assertEquals("containing strange things like spaces and äüø", description); @@ -276,7 +276,7 @@ public void testGetClassByPath() throws Exception Assert.assertEquals("1234567890", testCompound.getClubCardNumber()); Assert.assertEquals(null, testCompound.getNotSet()); Assert.assertEquals(null, testCompound.getNullValue()); - Assert.assertEquals(new Double(12.34), testCompound.getNumberValue()); + Assert.assertEquals(Double.valueOf(12.34), testCompound.getNumberValue()); Assert.assertEquals("containing strange things like spaces and äüø", testCompound.getDescription()); Assert.assertEquals("4111111111111111", testCompound.getCreditCard().getCardNumber()); Assert.assertEquals("123", testCompound.getCreditCard().getCcv()); diff --git a/src/test/java/com/xceptance/neodymium/testclasses/datautils/DataUtilsTestsXml.java b/src/test/java/com/xceptance/neodymium/testclasses/datautils/DataUtilsTestsXml.java index acdd98051..704ce1aa0 100644 --- a/src/test/java/com/xceptance/neodymium/testclasses/datautils/DataUtilsTestsXml.java +++ b/src/test/java/com/xceptance/neodymium/testclasses/datautils/DataUtilsTestsXml.java @@ -210,7 +210,7 @@ public void testGetClass() throws Exception Assert.assertEquals(null, testCompound.getNotSet()); // our XML parer does not support explicit null value // Assert.assertEquals(null, testCompound.getNullValue()); - Assert.assertEquals(new Double(12.34), testCompound.getNumberValue()); + Assert.assertEquals(Double.valueOf(12.34), testCompound.getNumberValue()); Assert.assertEquals("containing strange things like spaces and äüø", testCompound.getDescription()); Assert.assertEquals("4111111111111111", testCompound.getCreditCard().getCardNumber()); Assert.assertEquals("123", testCompound.getCreditCard().getCcv()); @@ -235,7 +235,7 @@ public void testGetClass() throws Exception public void testGetByPath() throws Exception { Double numberValue = DataUtils.get("$.numberValue", Double.class); - Assert.assertEquals(new Double(12.34), numberValue); + Assert.assertEquals(Double.valueOf(12.34), numberValue); String description = DataUtils.get("$.description", String.class); Assert.assertEquals("containing strange things like spaces and äüø", description); @@ -277,7 +277,7 @@ public void testGetClassByPath() throws Exception Assert.assertEquals(null, testCompound.getNotSet()); // our XML parer does not support explicit null value // Assert.assertEquals(null, testCompound.getNullValue()); - Assert.assertEquals(new Double(12.34), testCompound.getNumberValue()); + Assert.assertEquals(Double.valueOf(12.34), testCompound.getNumberValue()); Assert.assertEquals("containing strange things like spaces and äüø", testCompound.getDescription()); Assert.assertEquals("4111111111111111", testCompound.getCreditCard().getCardNumber()); Assert.assertEquals("123", testCompound.getCreditCard().getCcv()); From c26e6554fd06e0cb347cce1d124a93469fd17c2e Mon Sep 17 00:00:00 2001 From: Marcel Pfotenhauer Date: Wed, 26 Aug 2020 15:30:53 +0200 Subject: [PATCH 2/9] #135: changed exception handling to multi-catch clause --- .../neodymium/module/StatementBuilder.java | 23 ++----------------- 1 file changed, 2 insertions(+), 21 deletions(-) diff --git a/src/main/java/com/xceptance/neodymium/module/StatementBuilder.java b/src/main/java/com/xceptance/neodymium/module/StatementBuilder.java index b162014c6..53f9e9c2b 100644 --- a/src/main/java/com/xceptance/neodymium/module/StatementBuilder.java +++ b/src/main/java/com/xceptance/neodymium/module/StatementBuilder.java @@ -28,27 +28,8 @@ public static T instantiate(Class clazz) { return clazz.getDeclaredConstructor().newInstance(); } - catch (InstantiationException e) - { - throw new RuntimeException(e); - } - catch (IllegalAccessException e) - { - throw new RuntimeException(e); - } - catch (IllegalArgumentException e) - { - throw new RuntimeException(e); - } - catch (InvocationTargetException e) - { - throw new RuntimeException(e); - } - catch (NoSuchMethodException e) - { - throw new RuntimeException(e); - } - catch (SecurityException e) + catch (InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException | NoSuchMethodException + | SecurityException e) { throw new RuntimeException(e); } From e2e34b1547745051e9b3089f6dd7f539ef649a7e Mon Sep 17 00:00:00 2001 From: Marcel Pfotenhauer Date: Thu, 27 Aug 2020 15:11:31 +0200 Subject: [PATCH 3/9] #119: removed scope for dependency since this is the default --- pom.xml | 1 - 1 file changed, 1 deletion(-) diff --git a/pom.xml b/pom.xml index 92c6ec798..13daa03cc 100644 --- a/pom.xml +++ b/pom.xml @@ -298,7 +298,6 @@ com.browserup browserup-proxy-mitm 2.1.1 - compile \ No newline at end of file From 8d183170919a08a51de8be78b36c1a7f37f696d8 Mon Sep 17 00:00:00 2001 From: Marcel Pfotenhauer Date: Thu, 27 Aug 2020 15:20:08 +0200 Subject: [PATCH 4/9] #135: added mor specific type of Exception to match a more narrow scope for this case --- .../com/xceptance/neodymium/module/StatementBuilder.java | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/main/java/com/xceptance/neodymium/module/StatementBuilder.java b/src/main/java/com/xceptance/neodymium/module/StatementBuilder.java index 53f9e9c2b..4f61f04ee 100644 --- a/src/main/java/com/xceptance/neodymium/module/StatementBuilder.java +++ b/src/main/java/com/xceptance/neodymium/module/StatementBuilder.java @@ -3,7 +3,6 @@ import java.lang.annotation.Annotation; import java.lang.annotation.Repeatable; import java.lang.reflect.AnnotatedElement; -import java.lang.reflect.InvocationTargetException; import java.util.Arrays; import java.util.LinkedList; import java.util.List; @@ -28,8 +27,7 @@ public static T instantiate(Class clazz) { return clazz.getDeclaredConstructor().newInstance(); } - catch (InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException | NoSuchMethodException - | SecurityException e) + catch (ReflectiveOperationException e) { throw new RuntimeException(e); } @@ -54,7 +52,7 @@ public static List getAnnotations(AnnotatedElement obj { annotations.addAll(Arrays.asList((T[]) annotation.getClass().getMethod("value").invoke(annotation))); } - catch (Exception e) + catch (ReflectiveOperationException e) { throw new RuntimeException(e); } @@ -90,7 +88,7 @@ public static List getDeclaredAnnotations(AnnotatedEle { annotations.addAll(Arrays.asList((T[]) annotation.getClass().getMethod("value").invoke(annotation))); } - catch (Exception e) + catch (ReflectiveOperationException e) { throw new RuntimeException(e); } From 49c49b5ba05a526d7c9c04e39d7d1892d9627d5c Mon Sep 17 00:00:00 2001 From: Marcel Pfotenhauer Date: Fri, 28 Aug 2020 10:18:52 +0200 Subject: [PATCH 5/9] #117: added final to several variables and extracted a seperate method to improve the readability of the code --- .../multibrowser/BrowserRunnerHelper.java | 77 ++++++++++--------- 1 file changed, 39 insertions(+), 38 deletions(-) diff --git a/src/main/java/com/xceptance/neodymium/module/statement/browser/multibrowser/BrowserRunnerHelper.java b/src/main/java/com/xceptance/neodymium/module/statement/browser/multibrowser/BrowserRunnerHelper.java index 922096efd..363829e5e 100644 --- a/src/main/java/com/xceptance/neodymium/module/statement/browser/multibrowser/BrowserRunnerHelper.java +++ b/src/main/java/com/xceptance/neodymium/module/statement/browser/multibrowser/BrowserRunnerHelper.java @@ -278,44 +278,12 @@ else if (safariBrowsers.contains(browserName)) private static BrowserUpProxy setupEmbeddedProxy() { // instantiate the proxy - BrowserUpProxy proxy = new BrowserUpProxyServer(); + final BrowserUpProxy proxy = new BrowserUpProxyServer(); if (Neodymium.configuration().useLocalProxyWithSelfSignedCertificate()) { - ImpersonatingMitmManager mitmManager = null; - if (Neodymium.configuration().localProxyGenerateSelfSignedCertificate()) - { - CertificateAndKeySource certSource; - File certFile = new File("./config/embeddedLocalProxySelfSignedRootCertificate.p12"); - if (certFile.canRead()) - { - certSource = new KeyStoreFileCertificateSource(CERT_FORMAT, certFile, CERT_NAME, CERT_PASSWORD); - } - else - { - // create a dynamic CA root certificate generator using default settings (2048-bit RSA keys) - RootCertificateGenerator rootCertificateGenerator = RootCertificateGenerator.builder().build(); - // save the dynamically-generated CA root certificate for installation in a browser - rootCertificateGenerator.saveRootCertificateAndKey(CERT_FORMAT, certFile, CERT_NAME, CERT_PASSWORD); - certSource = rootCertificateGenerator; - } - // tell the MitmManager to use the root certificate we just generated - mitmManager = ImpersonatingMitmManager.builder().rootCertificateSource(certSource).build(); - } - else - { - // configure the MITM using the provided certificate - String type = Neodymium.configuration().localProxyCertificateArchiveType(); - String file = Neodymium.configuration().localProxyCertificateArchiveFile(); - String cName = Neodymium.configuration().localProxyCertificateName(); - String cPassword = Neodymium.configuration().localProxyCertificatePassword(); - if (StringUtils.isAnyBlank(type, file, cName, cPassword)) - { - throw new RuntimeException("The local proxy certificate isn't fully configured. Please check: certificate archive type, certificate archive file, certificate name and certificate password."); - } - KeyStoreFileCertificateSource fileCertificateSource = new KeyStoreFileCertificateSource(type, new File(file), cName, cPassword); - mitmManager = ImpersonatingMitmManager.builder().rootCertificateSource(fileCertificateSource).build(); - } + final CertificateAndKeySource rootCertificateSource = getLocalProxyRootCertSource(); + final ImpersonatingMitmManager mitmManager = ImpersonatingMitmManager.builder().rootCertificateSource(rootCertificateSource).build(); proxy.setMitmManager(mitmManager); } else @@ -328,9 +296,9 @@ private static BrowserUpProxy setupEmbeddedProxy() proxy.start(); // default basic authentication via the proxy - String host = Neodymium.configuration().host(); - String bUsername = Neodymium.configuration().basicAuthUsername(); - String bPassword = Neodymium.configuration().basicAuthPassword(); + final String host = Neodymium.configuration().host(); + final String bUsername = Neodymium.configuration().basicAuthUsername(); + final String bPassword = Neodymium.configuration().basicAuthPassword(); if (StringUtils.isNoneBlank(host, bUsername, bPassword)) { proxy.autoAuthorization(host, bUsername, bPassword, AuthType.BASIC); @@ -339,6 +307,39 @@ private static BrowserUpProxy setupEmbeddedProxy() return proxy; } + private static CertificateAndKeySource getLocalProxyRootCertSource() + { + if (Neodymium.configuration().localProxyGenerateSelfSignedCertificate()) + { + final File certFile = new File("./config/embeddedLocalProxySelfSignedRootCertificate.p12"); + if (certFile.canRead()) + { + return new KeyStoreFileCertificateSource(CERT_FORMAT, certFile, CERT_NAME, CERT_PASSWORD); + } + else + { + // create a dynamic CA root certificate generator using default settings (2048-bit RSA keys) + final RootCertificateGenerator rootCertificateGenerator = RootCertificateGenerator.builder().build(); + // save the dynamically-generated CA root certificate for installation in a browser + rootCertificateGenerator.saveRootCertificateAndKey(CERT_FORMAT, certFile, CERT_NAME, CERT_PASSWORD); + return rootCertificateGenerator; + } + } + else + { + // configure the MITM using the provided certificate + final String type = Neodymium.configuration().localProxyCertificateArchiveType(); + final String file = Neodymium.configuration().localProxyCertificateArchiveFile(); + final String cName = Neodymium.configuration().localProxyCertificateName(); + final String cPassword = Neodymium.configuration().localProxyCertificatePassword(); + if (StringUtils.isAnyBlank(type, file, cName, cPassword)) + { + throw new RuntimeException("The local proxy certificate isn't fully configured. Please check: certificate archive type, certificate archive file, certificate name and certificate password."); + } + return new KeyStoreFileCertificateSource(type, new File(file), cName, cPassword); + } + } + public static Proxy createProxyCapabilities() { final String proxyHost = Neodymium.configuration().getProxyHost() + ":" + Neodymium.configuration().getProxyPort(); From 5e992f7cf489a01dbf76692c91510508b61b0acd Mon Sep 17 00:00:00 2001 From: Marcel Pfotenhauer Date: Fri, 28 Aug 2020 10:20:46 +0200 Subject: [PATCH 6/9] #117: delete self signed certificate for embedded proxy once the VM is terminated --- .../multibrowser/BrowserRunnerHelper.java | 31 +++++++++++-------- 1 file changed, 18 insertions(+), 13 deletions(-) diff --git a/src/main/java/com/xceptance/neodymium/module/statement/browser/multibrowser/BrowserRunnerHelper.java b/src/main/java/com/xceptance/neodymium/module/statement/browser/multibrowser/BrowserRunnerHelper.java index 363829e5e..7141f140b 100644 --- a/src/main/java/com/xceptance/neodymium/module/statement/browser/multibrowser/BrowserRunnerHelper.java +++ b/src/main/java/com/xceptance/neodymium/module/statement/browser/multibrowser/BrowserRunnerHelper.java @@ -60,6 +60,8 @@ public final class BrowserRunnerHelper private static List safariBrowsers = new LinkedList(); + private final static Object mutex = new Object(); + static { chromeBrowsers.add(BrowserType.ANDROID); @@ -282,7 +284,7 @@ private static BrowserUpProxy setupEmbeddedProxy() if (Neodymium.configuration().useLocalProxyWithSelfSignedCertificate()) { - final CertificateAndKeySource rootCertificateSource = getLocalProxyRootCertSource(); + final CertificateAndKeySource rootCertificateSource = createLocalProxyRootCertSource(); final ImpersonatingMitmManager mitmManager = ImpersonatingMitmManager.builder().rootCertificateSource(rootCertificateSource).build(); proxy.setMitmManager(mitmManager); } @@ -307,22 +309,25 @@ private static BrowserUpProxy setupEmbeddedProxy() return proxy; } - private static CertificateAndKeySource getLocalProxyRootCertSource() + private static CertificateAndKeySource createLocalProxyRootCertSource() { if (Neodymium.configuration().localProxyGenerateSelfSignedCertificate()) { - final File certFile = new File("./config/embeddedLocalProxySelfSignedRootCertificate.p12"); - if (certFile.canRead()) - { - return new KeyStoreFileCertificateSource(CERT_FORMAT, certFile, CERT_NAME, CERT_PASSWORD); - } - else + synchronized (mutex) { - // create a dynamic CA root certificate generator using default settings (2048-bit RSA keys) - final RootCertificateGenerator rootCertificateGenerator = RootCertificateGenerator.builder().build(); - // save the dynamically-generated CA root certificate for installation in a browser - rootCertificateGenerator.saveRootCertificateAndKey(CERT_FORMAT, certFile, CERT_NAME, CERT_PASSWORD); - return rootCertificateGenerator; + final File certFile = new File("./config/embeddedLocalProxySelfSignedRootCertificate.p12"); + if (certFile.canRead()) + { + return new KeyStoreFileCertificateSource(CERT_FORMAT, certFile, CERT_NAME, CERT_PASSWORD); + } + else + { + // create a dynamic CA root certificate generator using default settings (2048-bit RSA keys) + final RootCertificateGenerator rootCertificateGenerator = RootCertificateGenerator.builder().build(); + // save the dynamically-generated CA root certificate for installation in a browser + rootCertificateGenerator.saveRootCertificateAndKey(CERT_FORMAT, certFile, CERT_NAME, CERT_PASSWORD); + return rootCertificateGenerator; + } } } else From 1fe9c0775483550ce8d0c12700a1292fbbb2c4d9 Mon Sep 17 00:00:00 2001 From: Marcel Pfotenhauer Date: Fri, 28 Aug 2020 10:20:57 +0200 Subject: [PATCH 7/9] #117: delete self signed certificate for embedded proxy once the VM is terminated --- .../statement/browser/multibrowser/BrowserRunnerHelper.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/com/xceptance/neodymium/module/statement/browser/multibrowser/BrowserRunnerHelper.java b/src/main/java/com/xceptance/neodymium/module/statement/browser/multibrowser/BrowserRunnerHelper.java index 7141f140b..2a672db67 100644 --- a/src/main/java/com/xceptance/neodymium/module/statement/browser/multibrowser/BrowserRunnerHelper.java +++ b/src/main/java/com/xceptance/neodymium/module/statement/browser/multibrowser/BrowserRunnerHelper.java @@ -316,6 +316,7 @@ private static CertificateAndKeySource createLocalProxyRootCertSource() synchronized (mutex) { final File certFile = new File("./config/embeddedLocalProxySelfSignedRootCertificate.p12"); + certFile.deleteOnExit(); if (certFile.canRead()) { return new KeyStoreFileCertificateSource(CERT_FORMAT, certFile, CERT_NAME, CERT_PASSWORD); From e2fc56f2ed3258dd7d83ea49ac6803e6c5ab3da5 Mon Sep 17 00:00:00 2001 From: Hartmut Arlt Date: Fri, 28 Aug 2020 13:06:54 +0200 Subject: [PATCH 8/9] Fixed some typos (comments only) in neodymium.properties. --- config/neodymium.properties | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/config/neodymium.properties b/config/neodymium.properties index 17ba144c3..e9b68470a 100644 --- a/config/neodymium.properties +++ b/config/neodymium.properties @@ -107,10 +107,10 @@ # ############################# # -# SelenidetAddons properties +# SelenideAddons properties # ############################# -# The following properties are taken into account if you use functions form the SelenidUtils class. +# The following properties are taken into account if you use functions form the SelenideUtils class. # # How often should Selenide try to match a condition if the element is affected by staleness # neodymium.selenideAddons.staleElement.retry.count = 3 @@ -245,7 +245,7 @@ neodymium.webDriver.keepBrowserOpenOnFailure = false # ############################# -# Create a local proxy to use it for basic authentication, header manipulations or similar things +# Create a local proxy to use it for basic authentication, header manipulations or similar things # neodymium.localproxy = false # The following settings are required if a (self signed) certificate is used to authenticate the man in the middle(MITM) proxy From 45fbe26b5f824eae4a1b630d619365b92e523606 Mon Sep 17 00:00:00 2001 From: Marcel Pfotenhauer Date: Fri, 28 Aug 2020 13:53:48 +0200 Subject: [PATCH 9/9] #131: simplified implementation --- .../neodymium/tests/NeodymiumTest.java | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/src/test/java/com/xceptance/neodymium/tests/NeodymiumTest.java b/src/test/java/com/xceptance/neodymium/tests/NeodymiumTest.java index 48e199ff8..aca970ba7 100644 --- a/src/test/java/com/xceptance/neodymium/tests/NeodymiumTest.java +++ b/src/test/java/com/xceptance/neodymium/tests/NeodymiumTest.java @@ -1,7 +1,8 @@ package com.xceptance.neodymium.tests; import java.io.File; -import java.io.FileOutputStream; +import java.io.IOException; +import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.text.MessageFormat; import java.util.ArrayList; @@ -11,6 +12,7 @@ import java.util.Map; import java.util.stream.Collectors; +import org.apache.commons.io.FileUtils; import org.junit.AfterClass; import org.junit.Assert; import org.junit.runner.Description; @@ -105,17 +107,14 @@ public void checkDescription(Class clazz, String[] expectedTestDescription) t */ public static void writeMapToPropertiesFile(Map map, File file) { + String propertiesString = map.entrySet().stream() + .map(entry -> entry.getKey() + "=" + entry.getValue()) + .collect(Collectors.joining(System.lineSeparator())); try { - String propertiesString = map.keySet().stream() - .map(key -> key + "=" + map.get(key)) - .collect(Collectors.joining("\r\n")); - - FileOutputStream outputStream = new FileOutputStream(file); - outputStream.write(propertiesString.getBytes()); - outputStream.close(); + FileUtils.writeStringToFile(file, propertiesString, StandardCharsets.UTF_8); } - catch (Exception e) + catch (IOException e) { throw new RuntimeException(e); }