Connection reset error - when running mvn clean install to run features - java

We have generated a karate test project using the Maven archetype, to test several different API services.
We have a feature file that conducts a test with an endpoint, which works fine when this endpoint is locally running on our machine. However, we would like to run these karate tests in a CI environment where we use a url to our (deployed) service on a dev environment. When we run mvn clean install on our CI pipeline, we get an error when running the feature:
com.intuit.karate.exception.KarateException:
MyFeatureTest.feature:8 -
java.net.SocketException: Connection reset
Our configuration
pom.xml:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.mycompany.app</groupId>
<artifactId>our-karate-tests</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<java.version>1.8</java.version>
<maven.compiler.version>3.6.0</maven.compiler.version>
<karate.version>0.9.5</karate.version>
</properties>
<dependencies>
<dependency>
<groupId>com.intuit.karate</groupId>
<artifactId>karate-apache</artifactId>
<version>${karate.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.intuit.karate</groupId>
<artifactId>karate-junit4</artifactId>
<version>${karate.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<testResources>
<testResource>
<directory>src/test/java</directory>
<excludes>
<exclude>**/*.java</exclude>
</excludes>
</testResource>
</testResources>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>${maven.compiler.version}</version>
<configuration>
<encoding>UTF-8</encoding>
<source>${java.version}</source>
<target>${java.version}</target>
<compilerArgument>-Werror</compilerArgument>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.22.2</version>
</plugin>
</plugins>
</build>
</project>
MyFeatureTest.java
import com.intuit.karate.KarateOptions;
import com.intuit.karate.junit4.Karate;
import com.junit.runner.RunWith;
#RunWith(Karate.class)
#KarateOptions(features="classpath:MyFeatureTest.feature")
public class MyFeatureTest {
}
MyFeatureTest.feature
Feature: test an endpoint
Background:
* url 'https://dev.myapplication.com/api/signin'
* configure ssl = true
Scenario: test request
Given request {"username":"john", "password":"doe"}
When method post
Then status 200
And match response == {resp:"success"}
What we have tried:
We are able to call the service through Postman without any problem (both locally and the deployed service). We have also tried executing different methods, for example get. The strange part out of all this is that the connection reset error occurs in our CI environment, but when we run the feature locally, we get a org.apache.http.conn.ConnectTimeoutException: connect to https://dev.myapplication.com:443 failed: connection timeout.
We have a feeling it is related to the karate-apache client, but we have also tried to use apache-jersey. Unfortunately, we get the same problem when we use the jersey client as well. We also thought it might be related to SSL. However, even when using a non ssl service (and remove the ssl configuration from the feature), the same problem occurs. We have tried to test responses from non-https websites like web.archive.org as well as https ones like google.com, in a futile attempt as well where we simply test a GET request. Still, the same issue occurs.

Sounds very much like you have an HTTP proxy to deal with.
Refer to the docs if that is the case: https://github.com/intuit/karate#configure
* configure proxy = 'http://my.proxy.host:8080'

Related

How to use #pact maven plugin to verify a provider without port

Per https://docs.pact.io/implementation_guides/jvm/provider/maven/#2-define-the-pacts-between-your-consumers-and-providers
: Protocol, Host, and Port are required.
My spring boot rest app is on kubernetes, I have endpoint URL like https://fruitbasket.net/abc
If I don't specify the port tag, and run mvn pact:verify; test fail and it seems like :8080 get appended during run time
https://fruitbasket.net/:8080/abc
Essentially, messing up the request endpoint.
Please note: I having fixed IP address and port isn't realistic.
How can I specify the provider host URL without port?
plugin config:
<plugin>
<groupId>au.com.dius.pact.provider</groupId>
<artifactId>maven</artifactId>
<version>4.1.0</version>
<configuration>
<serviceProviders>
<name>marketplace</name>
<protocol>https</protocol>
<host>fruitbasket.net</host>
</serviceProvider>
</serviceProviders>
</configuration>
</plugin>
in my current project we use this config
<plugin>
<groupId>au.com.dius.pact.provider</groupId>
<artifactId>maven</artifactId>
<version>4.2.0</version>
<configuration>
<pactBrokerUrl>https://mypactbroker</pactBrokerUrl>
<trimSnapshot>true</trimSnapshot>
</configuration>
</plugin>
with the annotation #PactBroker(scheme = "https")on the test class.
The pom.xml is not correct. You are missing to open serviceProvider tag

Running embedded H2 database with mvn jetty:run

I've been trying to figure out how to run an embedded database through a profile and be able to run REST calls through postman.
This is what I have so far:
<profile>
<id>developRest</id>
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>sql-maven-plugin</artifactId>
<version>1.5</version>
<dependencies>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<version>${h2.version}</version>
</dependency>
</dependencies>
<configuration>
<driver>org.h2.Driver</driver>
<url>jdbc:h2:mem:test</url>
<username>sa</username>
<password>sa</password>
</configuration>
<executions>
<execution>
<id>my-execution</id>
<goals>
<goal>execute</goal>
</goals>
<configuration>
<autocommit>true</autocommit>
<srcFiles>
<srcFile>src/test/resources/table-ddl.sql</srcFile>
<srcFile>src/test/resources/insert-into-table.sql</srcFile>
</srcFiles>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.mortbay.jetty</groupId>
<artifactId>jetty-maven-plugin</artifactId>
<version>${jetty.version}</version>
<configuration>
<webApp>
<descriptor>src/main/webapp/WEB-INF/jetty.xml</descriptor>
</webApp>
<stopKey></stopKey>
<stopPort></stopPort>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<version>${h2.version}</version>
</dependency>
</dependencies>
</profile>
I've played around with phases but nothing really seems to stick. When I run this with mvn sql:execute#my-execution jetty:run, the servlet runs but once I call a rest method I get
Failed to execute goal org.codehaus.mojo:sql-maven-plugin:1.5:execute (my-execution) on project myProject: The parameters 'driver', 'url' for goal org.codehaus.mojo:sql-maven-plugin:1.5:execute are missing or invalid
What am I missing that will get the driver and url to be valid? Thanks for your help.
Update: Used mvn -PdevelopRest sql:execute#my-execution jetty:run to get rid of the driver and url error but still stuck with:
### Error querying database. Cause: org.h2.jdbc.JdbcSQLException: Table "myTable" not found; SQL statement:
When calling a GET from postman. Any Thoughts?
I find it hard to believe that you get a Maven error when you call a REST method (Failed to execute goal ...).
That aside, I think your real problem is this: you are using H2 as an in-memory database, that means that it's available as long as your application runs. When your application goes away, so does your database.
In the context of Maven, where you have multiple plugins executing, the database does not outlive the execution of a single plugin. Your my-execution instantiates an in-memory database, which then goes away. The jetty-maven-plugin creates its own in-memory database, which then does not have any of the DDL/SQL that went into the previous one.
There is probably a number of ways to fix this, like these:
Don't use an in-memory database, rather have H2 write out files, e.g. jdbc:h2:/data/test, or, since you're using Maven: jdbc:h2:${project.build.directory}/data/test
Don't initialize the database using the sql-maven-plugin, but directly inside the application. You could do that:
With some custom code, that you only put on the test classpath
By adding the DDL/SQL to the connection string of the application ("Execute SQL on Connection"), like so:
jdbc:h2:mem:test;INIT=runscript from '~/table-ddl.sql'\\;runscript from '~/insert-into-table.sql'";
H2 is an awesome database. Good luck!

maven war application setting up contextroot

i am building a war application file using the below maven config, however when i start the application in tomcat the Context Root is set to "/CommerceApi-0.0.1-SNAPSHOT/"
I want this to be set to "/api",
any ideas?, below is the pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>CommerceApi</groupId>
<artifactId>CommerceApi</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>
<build>
<sourceDirectory>src</sourceDirectory>
<resources>
<resource>
<directory>src</directory>
<excludes>
<exclude>**/*.java</exclude>
</excludes>
</resource>
</resources>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.3</version>
<configuration>
<source>1.6</source>
<target>1.6</target>
</configuration>
</plugin>
<plugin>
<artifactId>maven-war-plugin</artifactId>
<version>2.6</version>
<configuration>
<warSourceDirectory>WebContent</warSourceDirectory>
<failOnMissingWebXml>false</failOnMissingWebXml>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-mapper-asl</artifactId>
<version>1.9.13</version>
</dependency>
<dependency>
<groupId>CommerceApiCommon</groupId>
<artifactId>CommerceApiCommon</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
</dependencies>
</project>
There are three ways to do it:
1. If you are not using Eclipse/MyEclipse to deploy the application onto application server -
You need to make use of maven-war plugin, you can specify warName in configuration section.
<plugin>
<artifactId>maven-war-plugin</artifactId>
<version>3.0.0</version>
<configuration>
<warName>customwarname</warName>
</configuration>
</plugin>
2. If you are using Eclipse/MyEclipse to deploy the application onto application server -
If you are using eclipse and deploying war using eclipse then you can use following maven configuration.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-eclipse-plugin</artifactId>
<version>2.10</version>
<configuration>
<wtpversion>2.0</wtpversion>
<wtpContextName>customwarname</wtpContextName>
</configuration>
</plugin>
Then, run following commands to update eclipse settings.
mvn eclipse:eclipse -Dwtpversion=2.0
Restart Eclipse and then navigate to project properties, Properties->Web to view the reflected changes in root-context value or navigate to Deployment Assembly of the project to view the changes
Note that above can be achieved using m2eclipse by adding a new plugin.
3. Application server specific:
You should prefer to follow server agnostic approach, but if are required to do it then you can configure root context url in server specific configuration file. You can find detailed approach here
Your application is not in charge to define its own context path. That's task of the container, the Tomcat in your case. Tomcat offers several options of how to set the context path. You may define the context path it in a context file or specify the context path in the manager application. If you use Jenkins or other CI tools you'd be able to specify the context path there, as well.
Best you read up on the options you have regarding your particular Tomcat version.
There are several options. Some are described in Define Servlet Context in WAR-File
Using tomcat you can also define the context.xml path: http://maven.apache.org/plugins/maven-war-plugin/war-mojo.html#containerConfigXML and maybe configure it in there: https://tomcat.apache.org/tomcat-7.0-doc/config/context.html
the fastest way os probably to change the final name (see other stackoverflow question).

Specify tag for test cases using soapui-pro-maven-plugin

It's possible to specify a tag for a test case in SOAP UI like this:
I'm using the SOAP UI Maven plugin to execute a functional test suite in different environments and it would be useful to be able to exclude some of the test cases by specifying a tag in the invocation.
It looks like there is no configuration parameter for the Maven plugin to specify a tag (so that only a subset of the tests cross cutting different test suites can be executed):
https://www.soapui.org/test-automation/maven/maven-2-x.html
However it is possible to specify a tag when running via the GUI or command line:
http://readyapi.smartbear.com/features/automation/testrunner/cli
You can see from the above link that it is possible to specify tests which are tagged by using the -T switch.
Is this just a limitation of the Maven plugin?
Is it possible to simulate specifying a tag by reading an environmental variable during the Groovy startup script execution and disabling test cases which don't have the specified tag?
The Maven invocation is as follows:
mvn test -Dmyenv="dev" com.smartbear.soapui:soapui-pro-maven-plugin:5.2.1:test
The pom.xml looks like this:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>testing</groupId>
<artifactId>testing</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>pom</packaging>
<prerequisites>
<maven>3.0.5</maven>
</prerequisites>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
</dependencies>
<pluginRepositories>
<pluginRepository>
<id>SmartBearPluginRepository</id>
<url>http://www.soapui.org/repository/maven2/</url>
</pluginRepository>
<pluginRepository>
<id>mvnPluginRepository</id>
<url>http://mirrors.ibiblio.org/pub/mirrors/maven/mule/dependencies/maven2/</url>
</pluginRepository>
<pluginRepository>
<id>codehausPluginRepository</id>
<url>https://nexus.codehaus.org/content/groups/snapshots-group/org/codehaus/mojo/</url>
</pluginRepository>
</pluginRepositories>
<build>
<plugins>
<plugin>
<groupId>com.smartbear.soapui</groupId>
<artifactId>soapui-pro-maven-plugin</artifactId>
<version>5.2.1</version>
<dependencies>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.6</version>
</dependency>
<dependency>
<groupId>postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>9.1-901-1.jdbc4</version>
</dependency>
<dependency>
<groupId>org.reflections</groupId>
<artifactId>reflections-maven</artifactId>
<version>0.9.9-RC1</version>
</dependency>
</dependencies>
<configuration>
<projectFile>${basedir}/my-project</projectFile>
<outputFolder>${basedir}/surefire-reports</outputFolder>
<printReport>true</printReport>
<junitReport>true</junitReport>
<exportAll>true</exportAll>
<reportFormat>HTML</reportFormat>
<testFailIgnore>true</testFailIgnore>
<coverage>true</coverage>
<environment>${myenv}</environment>
</configuration>
<executions>
<execution>
<phase>test</phase>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.10</version>
<configuration>
<skipTests>true</skipTests>
</configuration>
</plugin>
</plugins>
</build>
Please correct me if I am wrong about any of this or if there is a better way as I am rather new to using SOAP UI. If you give a significantly better answer, I will accept yours. I really hope that Smartbear will support a way of specifying tags in the Maven plugin.
I have established that it is not possible to specify a tag via the Maven plugin and that the server version of SOAP UI costs a large amount of money, so it's not possible in my situation to use the command line method of specifying a tag.
I thought about simulating test tags/categories by moving all of the tests that I want to include/exclude for an environment to a number of test suites. Unfortunately it appears to be only possible to run either only one test suite (by specifying one the the "testSuite" parameter) or all of the test suites (by leaving "testSuite" blank).
I thought I might be able to pull out the tag for a test case or suite using a Groovy script and use that to determine whether it should be run or not, but as far as I can tell, it's not possible to get the tag information for a test case or testSuite (object model API documentation).
I settled on marking the test suites to be excluded with a custom property (testingOnly) and disabling those for a particular environment (Dev) in the project level "Setup Script":
// When running tests for the Dev environment, skip test suites with the property testingOnly=true
def disableSuitesWithProperty(def propertyName) {
project.testSuiteList.each { testSuite ->
def isPropertyTrue = testSuite.getProperty(propertyName)?.getValue()?.toBoolean() ?: false;
if(isPropertyTrue) {
log.info "[Project Setup Script] Will Skip Test Suite: ${testSuite.name}";
testSuite.setDisabled(true);
}
else {
log.info "[Project Setup Script] Will Execute Test Suite: ${testSuite.name}";
testSuite.setDisabled(false);
}
}
}
if ("Dev".equals(project.getActiveEnvironmentName())) {
disableSuitesWithProperty("testingOnly");
}
The suites are reenabled in the project level "TearDown Script":
// Reenable all test suites after all tests have run
for (testSuite in project.testSuiteList) {
log.info "[Project TearDown Script] Reenabling Test Suite: ${testSuite.name}";
testSuite.setDisabled(false);
}
Are you looking to specify an environment variable to the Surefire plugin? If so, this should work:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<argLine>-Dmyenv=dev</argLine>
</configuration>
</plugin>

How to make Jenkins job fail in case of java exception?

I have Jenkins job. I run maven java-executor plugin as follows:
compile exec:java
here is the pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.proj.utills</groupId>
<artifactId>db-upgrade</artifactId>
<version>0.0.1-SNAPSHOT</version>
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.2.1</version>
<configuration>
<mainClass>com.proj.db.RunMe</mainClass>
<arguments>
<argument>
${TARGET_ENV}
</argument>
</arguments>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.3.2</version>
<configuration>
<source>1.7</source>
<target>1.7</target>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>com.microsoft.sqlserver</groupId>
<artifactId>sqljdbc4</artifactId>
<version>3.0</version>
</dependency>
</dependencies>
</project>
I would like that Jenkins job fail when I got exception in Java code. For now it success even in case of exception. How can I do it?
Thanks
You can use the log parser plugin
EDIT: Excerpt from the plugin's documentation
Job Configuration
Go to menu: Jenkins -> job name -> Configure
Go to section : Post-build Actions
Check the "Console output (build log) parsing" checkbox.
"Mark build Unstable on Warning" option: check to have parsed warnings mark the build 'unstable'.
"Mark build Failed on Error" option : check to have parsed errors mark the build 'failed'.
"Select Parsing Rules" : select the set of rules to use for parsing the logs of this job's builds
(Notice that this list is derived from the global configuration )
I use the Log Parser Plugin for cases like this. just configure what you are looking for. In your case it might be as simple as looking for 'Exception'. I used to parse the output of shell scripts, to find sql errors (but still ignoring some that I don't care about).
You may try the Jenkins Text Finder plugin, downgrade the BUILD status from successful to UNSTABLE/FAIL when the regular expression setting is met. More detail refer to the link above.
I got exactly the same problem and did not like this parsing log solution.
For me a -B (to enable the batch mode) did the work nicely
build:
- mvn -B deploy

Categories