Error in passing paramters from testng.xml in testng - parameter-passing

I am unable to access paramterised value defined in testng.xml.Tried defining parameter at test and method level too which i got from other similar queries here but the erros remains same
Error is- "Parameter 'myName' is required by #Test on method parameterTest but has not been marked #Optional or defined
in C:\Windows\Temp\testng-eclipse-281832880\testng-customsuite.xml"
Below is my snippet of code,followed by testng.xml and error
Code snippet for one and two params
testng.xml with both param types 1-at test and method level both, 2- at method level

The following works for me [ You just need to ensure that the same class is not being included more than once in the same <test> tag.
Here's a sample
package organized.chaos.testng;
import org.testng.annotations.Parameters;
import org.testng.annotations.Test;
public class EmployeeTestNG {
#Parameters ({"and", "abc"})
#Test
public void test1(String b, String a) {
System.err.println("****" + b + a);
}
#Test
#Parameters ("myName")
public void parameterTest(String myName) {
System.err.println("Parameterized value is " + myName);
}
}
Here's the TestNG suite xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="employee-suite">
<test name="Employee-test">
<classes>
<class name="organized.chaos.testng.EmployeeTestNG">
<parameter name="myName" value="TestNG"/>
<parameter name="and" value="KungFu"/>
<parameter name="abc" value="Panda"/>
<methods>
<include name="parameterTest"/>
<include name="test1"/>
</methods>
</class>
</classes>
</test>
</suite>
Here's the output
[TestNG] Running:
/Users/krmahadevan/githome/PlayGround/testbed/src/test/resources/employee.xml
Parameterized value is TestNG
****KungFuPanda
===============================================
employee-suite
Total tests run: 2, Failures: 0, Skips: 0
===============================================
Process finished with exit code 0

Related

BIML class nugget error: 'AstTableNode' does not contain a definition for 'GetTag' and no accessible extension method 'GetTag'

I have created a HelperFunctions.cs file containing the following:
using Varigence.Languages.Biml.Table;
public static class HelperFunctions
{
public static string GetDisplayTableName(AstTableNode table)
{
return table.GetTag("DatabaseName").ToUpper() + "_" + table.Schema.Name.ToUpper() + "_" + table.Name.ToUpper();
}
}
However it does not recognise GetTag() and throws the error :
'AstTableNode' does not contain a definition for 'GetTag' and no accessible extension method 'GetTag' accepting a first argument of type 'AstTableNode' could be found (are you missing a using directive or an assembly reference?).
What do I need to add to make this work?
Thanks
Jon
A static method needs to have the parameter prefixed with this
SO_63828312.cs
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Varigence.Biml.Extensions;
using Varigence.Languages.Biml.Table;
public static class HelperFunctions
{
public static string GetDisplayTableName(this AstTableNode table)
{
return table.GetTag("DatabaseName").ToUpper() + "_" + table.Schema.Name.ToUpper() + "_" + table.Name.ToUpper();
}
}
My static Biml defines a table, which needs a schema, which needs a database, which needs a connection. All of that to get us to a table that has an AnnotationType of Tag with a value of AW.
SO_63828312.T0.biml
<Biml xmlns="http://schemas.varigence.com/biml.xsd">
<Connections>
<OleDbConnection ConnectionString="Data Source=localhost\dev2017;Initial Catalog=tempdb;Provider=SQLNCLI11.1;Integrated Security=SSPI;Auto Translate=False;Packet Size=32767;" Name="AdventureWorks" />
</Connections>
<Databases>
<Database Name="AW" ConnectionName="AdventureWorks" />
</Databases>
<Schemas>
<Schema DatabaseName="AW" Name="dbo" />
</Schemas>
<Tables>
<Table Name="foo" SchemaName="AW.dbo">
<Annotations>
<Annotation Tag="DatabaseName" AnnotationType="Tag">AW</Annotation>
</Annotations>
<Columns>
<Column Name="Col1" DataType="Int32"></Column>
</Columns>
</Table>
</Tables>
</Biml>
Tier 1 execution. This begins our dynamic tiering. Since there's only one, I don't explicitly give it one but if you have multiple tiers, you'd want to provide a directive.
Here I enumerate my Tables collection (defined in a preceding tier) and for each table I find, I write the table name and the tag value
SO_63828312.T1.biml
<## code file="SO_63828312.cs" #>
<Biml xmlns="http://schemas.varigence.com/biml.xsd">
<#
string template = "<!-- {0}|{1} -->";
foreach(var t in this.RootNode.Tables)
{
WriteLine(string.Format(template, t.Name, t.GetDisplayTableName()));
}
#>
</Biml>

Output Spark application id in the logs with Log4j

I have a custom Log4j file for the Spark application. I would like to output Spark app id along with other attributes like message and date so the JSON string structure would look like this:
{"name":,"time":,"date":,"level":,"thread":,"message":,"app_id":}
Now, this structure looks like this:
{"name":,"time":,"date":,"level":,"thread":,"message":}
How can I define such layout for the Spark driver logs?
My log4j file looks like this:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<log4j:configuration xmlns:log4j='http://jakarta.apache.org/log4j/'>
<appender name="Json" class="org.apache.log4j.ConsoleAppender">
<layout class="org.apache.hadoop.log.Log4Json">
<param name="ConversionLayout" value=""/>
</layout>
</appender>
<root>
<level value="INFO"/>
<appender-ref ref="Json"/>
</root>
</log4j:configuration>
I doubt that org.apache.hadoop.log.Log4Json can be adjusted for this purpose. According to its javadoc and source code it might be rather cumbersome.
Although it looks like you are using Log4j 1x, its API is quite flexible and we can easily define our own layout by extending org.apache.log4j.Layout.
We'll need a case class that will be transformed into JSON according to the target structure:
case class LoggedMessage(name: String,
appId: String,
thread: String,
time: Long,
level: String,
message: String)
And Layout might be extended as follows. To access the value of "app_id", we'll use Log4j's Mapped Diagnostic Context
import org.apache.log4j.Layout
import org.apache.log4j.spi.LoggingEvent
import org.json4s.DefaultFormats
import org.json4s.native.Serialization.write
class JsonLoggingLayout extends Layout {
// required by the API
override def ignoresThrowable(): Boolean = false
// required by the API
override def activateOptions(): Unit = { /* nothing */ }
override def format(event: LoggingEvent): String = {
// we are using json4s for JSON serialization
implicit val formats = DefaultFormats
// retrieve app_id from Mapped Diagnostic Context
val appId = event.getMDC("app_id") match {
case null => "[no_app]" // logged messages outside our app
case defined: AnyRef => defined.toString
}
val message = LoggedMessage("TODO",
appId,
Thread.currentThread().getName,
event.getTimeStamp,
event.getLevel.toString,
event.getMessage.toString)
write(message) + "\n"
}
}
Finally, when the Spark session is created, we put the app_id value into MDC:
import org.apache.log4j.{Logger, MDC}
// create Spark session
MDC.put("app_id", session.sparkContext.applicationId)
logger.info("-------- this is info --------")
logger.warn("-------- THIS IS A WARNING --------")
logger.error("-------- !!! ERROR !!! --------")
This produces following logs:
{"name":"TODO","appId":"local-1550247707920","thread":"main","time":1550247708149,"level":"INFO","message":"-------- this is info --------"}
{"name":"TODO","appId":"local-1550247707920","thread":"main","time":1550247708150,"level":"WARN","message":"-------- THIS IS A WARNING --------"}
{"name":"TODO","appId":"local-1550247707920","thread":"main","time":1550247708150,"level":"ERROR","message":"-------- !!! ERROR !!! --------"}
And, of course, do not forget to refer the implementation in log4j config xml:
<appender name="Json" class="org.apache.log4j.ConsoleAppender">
<layout class="stackoverflow.q54706582.JsonLoggingLayout" />
</appender>

Insert XmlFile (or other) from camel route to mongoDB

I've been trying to insert a XML file into mongoDB with camel and I can't manage to make it work.
I've followed this tutorial for the first steps:
http://www.pretechsol.com/2014/09/apache-camel-mongodb-component-example.html
In my route, I convert it in JSON then use 'convertBodyTo(string.class) for mongo to recognize the file.
The code works well with regular route (sending the file to another folder for example). But when I run it for mongoDB, all I get in the console is my Process message again and again with my databased never being filled.As I don't receive any error message, I don't know how to find where the problem come from.
The mongoDB name, ip, users, password have been already checked multiple times.
I would be very grateful if someone could help me on this one. Here is the files I am using. (I will spare you the process file).
camel-context.xml:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://camel.apache.org/schema/spring
http://camel.apache.org/schema/spring/camel-spring.xsd">
<bean id="myDb" class="com.mongodb.Mongo">
<constructor-arg index="0">
<bean class="com.mongodb.MongoURI">
<constructor-arg index="0"
value="mongodb://username:password#192.168.3.29:27017/db" />
</bean>
</constructor-arg>
</bean>
<bean id="mongodb" class="org.apache.camel.component.mongodb.MongoDbComponent"></bean>
<camelContext xmlns="http://camel.apache.org/schema/spring">
<routeBuilder ref="camelRoute" />
</camelContext>
<bean id="camelRoute" class="infotel.camel.project01.CamelRoute" />
Here is my RoutingFile:
#Component
public class CamelRoute extends SpringRouteBuilder {
final Processor myProcessor = new MyProcessor();
final Processor myProcessorMongo = new MyProcessorMongo();
final XmlJsonDataFormat xmlJsonFormat = new XmlJsonDataFormat();
#Override
public void configure() {
xmlJsonFormat.setForceTopLevelObject(true);
from("file:xml_files?noop=true").marshal(xmlJsonFormat).convertBodyTo(String.class).process(myProcessorMongo)
.to("mongodb:myDb?database=test_bignav&collection=doc&operation=insert");
}
}
And finally here is my main:
public class MyMain {
public static void main(String[] args) throws Exception {
ApplicationContext context =
new ClassPathXmlApplicationContext("META-INF/spring/camel-context.xml");
}
}
Thanks a lot.
Edit:
Here is MyProcessorMongo edited to get the error:
public class MyProcessorMongo implements Processor{
public void process(Exchange exchange) throws Exception {
System.out.println("\n file transfered to mongo: "+ exchange.getIn().getHeader("CamelFileName"));
exchange.getProperty(Exchange.EXCEPTION_CAUGHT, Exception.class).printStackTrace();
}
}
Enable tracing with trace="true":
<camelContext trace="true" xmlns="http://camel.apache.org/schema/spring">
Dirty but quick, to get the error you can add this to you configure() method before your from :
.onException(Exception.class).handled(true).process(new Processor() {
#Override
public void process(Exchange exchange) {
exchange.getProperty(Exchange.EXCEPTION_CAUGHT, Exception.class).printStackTrace();
}
})
The handled(true) prevents your message from being processed again and again.
thanks for your help I have been able to get the error message.
The problem actually came from mongoDB itself and not camel or code. With the change on users the connection works and I'm able to insert document inside a collection.
Remove the ".process(myProcessorMongo)" from route configuration . Input xml-> json conversion->string conversion -> Mongodb. Above route will work. And you are passing the exchange object to myProcessorMongo but Out message is null so nothing will be inserted into MongoDB . Put exchange.getOut().getBody(); in the myProcessorMongo and print it.If its coming as null u have to get the input message from exchange Obj and set it back it in to Out message property in the exchange Object.

Inject test data to Junit reports for failed tests (failsafe plugin used)

I have several tests cases in a list using failsafe and Junit as per below:
#Test
public void testResults() {
for (TestCase test : TestCaseList) {
int result = test.getActualResult();
int expected = test.getExpectedResult();
if (result != expected) {
System.out.println("Failed test " + test.getTestInfo());
}
assertEquals(result, expected);
}
}
I want the report something like :
Failed test <test description here>
java.lang.AssertionError:
Expected: is <4>
but: was <2>
Instead of just:
java.lang.AssertionError:
Expected: is <4>
but: was <2>
Is there a way to do that with Junit or other framework?
You can add a message to the assert:
assertEquals(test.getTestInfo(), result, expected);
This creates the following report:
java.lang.AssertionError: <test description here>
Expected: is <4>
but: was <2>

Mapping Struts 2 Exception Handler to an Action

I have Struts 2 configured to redirect any java.lang.Exception to a special Action which logs the exception. My redirection works, but my Action always gets a null exception (even when I explicitly throw an Exception). Here is my struts.xml file:
<global-results>
<result name="errHandler" type="chain">
<param name="actionName">errorProcessor</param>
</result>
</global-results>
<global-exception-mappings>
<exception-mapping exception="java.lang.Exception" result="errHandler" />
</global-exception-mappings>
<action name="errorProcessor" class="myErrorProcessor">
<result name="error">/error.jsp</result>
</action>
<action name="throwExceptions" class="throwExceptions">
<result name="success">done.jsp</result>
</action>
In my error processor, I have the following:
public class myErrorProcessor extends ActionSupport {
private Exception exception;
public String execute() {
System.out.println("null check: " + (exception == null));
return "error";
}
public void setException(Exception exception) {
this.exception = exception;
}
public Exception getException() {
return exception;
}
}
In the throwsException class, I have the following:
public String execute() {
int x = 7 / 0;
return "success";
}
When I run my program, the Exception handler always gets a null exception. I am using the chain type to redirect to the exception handler. Do I need to implement some sort of ExceptionAware interface? Is the Struts 2 exception setter called something besides setException?
Note: I was trying to follow this tutorial when writing this program.
Using struts2 version 2.3.1.2 I do not get a null exception in my error handler everything works as advertised. Ensure you are using an unmodified defaultStack.
As far as credible sources, we can reference the interceptor documentation for ExceptionMappingInterceptor and Chaining Interceptor. The ExceptionMappingInterceptor pushes an ExceptionHolder onto the value stack which in turn exposes an exception property. The chaining interceptor copies all the properties on the value stack to the target. Since ExceptionHolder is on the stack if there is a setter for Exception it will be set.
Here are all the files which produce a working example:
struts.xml (kept quite similar to the questions):
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
"http://struts.apache.org/dtds/struts-2.3.dtd">
<struts>
<constant name="struts.devMode" value="true" />
<constant name="struts.ui.theme" value="simple" />
<package name="kenmcwilliams" namespace="/" extends="struts-default">
<global-results>
<result name="errHandler" type="chain">
<param name="actionName">errorProcessor</param>
</result>
</global-results>
<global-exception-mappings>
<exception-mapping exception="java.lang.Exception" result="errHandler" />
</global-exception-mappings>
<action name="errorProcessor" class="com.kenmcwilliams.test.myErrorProcessor">
<result name="error">/WEB-INF/content/error.jsp</result>
</action>
<action name="throwExceptions" class="com.kenmcwilliams.kensocketchat.action.Bomb">
<result name="success">/WEB-INF/content/bomb.jsp</result>
</action>
</package>
</struts>
MyErrorProcessor.java
package com.kenmcwilliams.test;
import com.opensymphony.xwork2.ActionSupport;
public class MyErrorProcessor extends ActionSupport {
private Exception exception;
#Override
public String execute() {
System.out.println("Is exception null: " + (exception == null));
System.out.println(""
+ exception.getMessage());
return "error";
}
public void setException(Exception exceptionHolder) {
this.exception = exceptionHolder;
}
public Exception getException() {
return exception;
}
}
Bomb (just throws RuntimeException):
package com.kenmcwilliams.kensocketchat.action;
import com.opensymphony.xwork2.ActionSupport;
public class Bomb extends ActionSupport{
#Override
public String execute() throws Exception{
throw new RuntimeException("Hello from Exception!");
}
}
View for bomb (/WEB-INF/content/bomb.jsp) [Never reachable]
<%#taglib prefix="s" uri="/struts-tags"%>
<%#page contentType="text/html" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>The Bomb!</title>
</head>
<body>
<h1>The Bomb!</h1>
</body>
</html>
View for error (/WEB-INF/content/error.jsp)
<%#taglib prefix="s" uri="/struts-tags"%>
<%#page contentType="text/html" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Global Error Handler</title>
</head>
<body>
<h1>Global Error Handler</h1>
<s:property value="exception.stackTrace"/>
</body>
</html>
Output:
I see error.jsp render and I see the following printed on the glassfish console:
INFO: Is exception null: false
INFO: Hello from Exception!
I was having the same issue you were having!
While it is much cleaner to have the exception field populated by Struts, it appears that this field population is not happening (as you stated). To get around this, I removed the exception field (and its getter/setter) from my Exception handler class (your myErrorProcessor class) and replaced that with a method to "manually" extract the exception from the ValueStack:
/**
* Finds exception object on the value stack
*
* #return the exception object on the value stack
*/
private Object findException() {
ActionContext ac = ActionContext.getContext();
ValueStack vs = ac.getValueStack();
Object exception = vs.findValue("exception");
return exception;
}
I can then use instanceof to make sure the exception Object is the type that I was expecting and then handle that exception accordingly (like writing messages found in a custom Exception object to a database).
Let me know how this works for you! :)