How is the parallel runner running the feature files - dsl

I have set the following code in my java file:
#CucumberOptions(tags = {"~#ignore"})
public class ExamplesTest {
#BeforeClass
public static void before() {
System.setProperty("karate.env", "dev");
}
#Test
public void testParallel() {
String karateOutputPath = "target/surefire-reports";
KarateStats stats = CucumberRunner.parallel(getClass(), 1, karateOutputPath);
generateReport(karateOutputPath);
assertTrue("there are scenario failures", stats.getFailCount() == 0);
}
public static void generateReport(String karateOutputPath) {
Collection<File> jsonFiles = FileUtils.listFiles(new File(karateOutputPath), new String[] {"json"}, true);
List<String> jsonPaths = new ArrayList(jsonFiles.size());
jsonFiles.forEach(file -> jsonPaths.add(file.getAbsolutePath()));
Configuration config = new Configuration(new File("target"), "demo");
ReportBuilder reportBuilder = new ReportBuilder(jsonPaths, config);
reportBuilder.generateReports();
}
}
As you can see, i have set the thread count to 1 , but even if i increase it i see no difference in the execution time.
I am not very sure how the parallel run is happening.
Can someone please explain.

Currently the unit of parallelization is at the feature file level. This means:
if you have 1 feature there is no effect
if you have multiple features but one of them takes a very long time, the test will run for that amount of time

Related

Is it possible to see scenarios in feature files in the runner window while running parallel in karate?

When I run my tests with a parallel runner, I can't see scenarios in the feature files in which one failed or successful. I want to see these scenarios on the runner window in IntelliJ Idea. I am using parallel runner for cucumber reports.
Here is my code
#Test
public void testParallel() {
List<String> features = Arrays.asList("classpath:features");
Results results = Runner.path(features)
.outputCucumberJson(true).tags("~#ignore")
.karateEnv("deee")
.parallel(1);
generateReport(results.getReportDir());
assertTrue(results.getErrorMessages(), results.getFailCount() == 0);
}
public static void generateReport(String karateOutputPath) {
Collection<File> jsonFiles = FileUtils.listFiles(new File(karateOutputPath), new String[] {"json"}, true);
List<String> jsonPaths = new ArrayList<>(jsonFiles.size());
jsonFiles.forEach(file -> jsonPaths.add(file.getAbsolutePath()));
Configuration config = new Configuration(new File("target"), "deee");
ReportBuilder reportBuilder = new ReportBuilder(jsonPaths, config);
reportBuilder.generateReports();
}
The parallel runner does not integrate with the IDE view. It is designed for CI execution.
This other answer may explain the difference and why: https://stackoverflow.com/a/65578167/143475

BDD-JAVA- Is it possible to generate cucumber html reports with only scenario titles with out steps

I am currently using an HTML formatter to generate the Cucumber HTML report. The report is pretty, but I want the reports to be generated with all scenarios only with the title so that my report is not huge and easy to know which scenarios failed.
To clarify more, when cucumber HTML report is generated. I am seeing headers are divided into Steps (Passed, Failed, Skipped, Pending, Undefined), Scenarios(Passed, Failed, Skipped, Pending, Undefined), Feature. I just wanted to customize and print only Scenarios and remove steps section
enter image description here
public class HtmlFormatter extends CucumberJSONFormatter {
private static final String TIMESTAMP_FORMAT = "d MMM yyyy HH:mm:ss:SSS z";
public HtmlFormatter(Appendable out) {
super(out);
}
#Override
public void done() {
super.done();
final List<String> jsonFiles = new ArrayList<>();
final ConfigReader configReader = new ConfigReader();
final File reportOutputDirectory = new File("reports/html");
final int numThreads = Integer.valueOf(configReader.getProperty("maxThreads", "4"));
//in case running from single feature file
if (Main.isFeatureFileExecution()) {
final String singleFeatureFileExecutionReportPath = "reports/"+configReader.getProperty( "repo","RepoNameNotFound" ) +"/json/report.json";
if (new File(singleFeatureFileExecutionReportPath).exists()) {
jsonFiles.add(singleFeatureFileExecutionReportPath);
}
}
String projectName = “X”;
boolean runWithJenkins = true;
boolean parallelTesting = true;
Configuration configuration = new Configuration(reportOutputDirectory, projectName);
configuration.setParallelTesting(parallelTesting);
configuration.setRunWithJenkins(runWithJenkins);
if (!jsonFiles.isEmpty()) {
ReportBuilder reportBuilder = new ReportBuilder(jsonFiles, configuration);
Reportable result = reportBuilder.generateReports();
}
}
Write your own custom reporter based on the HTML reporter. As you are just trying to remove a small bit of functionality from the reporter this shouldn't be to difficult. Then use your reporter when running cucumber.

ThreadStatic in powershell class

I am trying to use ThreadStaticAttribute in a powershell singelton class to create a new instance of the object for each thread but is not working.
class log {
[ThreadStaticAttribute()]
static [log] $logging;
log(){
}
static [log]GetInstance(){
if($null -eq [log]::logging){
[log]::logging=[log]::New()
}
return [log]::logging
}
}
This returns the same object for newly created threads instead of instantiating a new one. Any thoughts ?
I've had no reason to try this, but it did come up for me a long while back. The resource I use to get a handle on it was the below, but again, I never really did this, because things changed and no reason to.
ThreadStatic Attribute
The [ThreadStatic]attribute indicates that the variable has one
instance for each thread. This is a variation of the static
variables.
Static variables have one instance throughout the lifecycle of the
program. A variable marked with [ThreadStatic]has one instance per
thread in the program.
See the example for more details.
class Program
{
public static Int32 singleton = 0;
[ThreadStatic]
public static Int32 threadSingleton = 0;
static void Main(string[] args)
{
Program executingProgram = new Program();
Thread firstThread = new Thread(new ThreadStart(executingProgram.FirstThread));
Thread secondThread = new Thread(new ThreadStart(executingProgram.SecondThread));
firstThread.Start();
firstThread.Join();
secondThread.Start();
firstThread.Join();
Console.Read();
}
public void FirstThread()
{
singleton++;
threadSingleton++;
Console.WriteLine("Singleton = {0} ThreadSingleton = {1}", singleton.ToString(), threadSingleton.ToString());
}
public void SecondThread()
{
singleton++;
threadSingleton++;
Console.WriteLine("Singleton = {0} ThreadSingleton = {1}", singleton.ToString(), threadSingleton.ToString());
}
}
# Output
Singleton = 1 ThreadSingleton = 1
Singleton = 2 ThreadSingleton = 1

IEventProcessor - Set offset

We are using an EvenProcessor which are using the iterface IEventProcessor.
When I connect to our Azure Eventhub I always get "all" data, but I only want "live" data. Was reading about setting the Offset, using a DateTime but I dont know where. Have been trying around without and success. Is it possible? Attached some of the code below:
Greetings
public class EventProcessor : IEventProcessor
{
IDictionary<string, int> map;
PartitionContext partitionContext;
Stopwatch checkpointStopWatch;
public EventProcessor()
{
this.map = new Dictionary<string, int>();
}
public Task OpenAsync(PartitionContext context)
{
context.Lease.Offset = DateTime.Now.ToString(); // not working - still gives all data
this.partitionContext = context;
this.checkpointStopWatch = new Stopwatch();
this.checkpointStopWatch.Start();
return Task.FromResult<object>(null);
}

How to write an NLog target using Signalr

I'm trying to write a target for NLog to send messages out to connected clients using SignalR.
Here's what I have now. What I'm wondering is should I be using resolving the ConnectionManager like this -or- somehow obtain a reference to the hub (SignalrTargetHub) and call a SendMessage method on it?
Are there performance ramifications for either?
[Target("Signalr")]
public class SignalrTarget:TargetWithLayout
{
public SignalR.IConnectionManager ConnectionManager { get; set; }
public SignalrTarget()
{
ConnectionManager = AspNetHost.DependencyResolver.Resolve<IConnectionManager>();
}
protected override void Write(NLog.LogEventInfo logEvent)
{
dynamic clients = GetClients();
var logEventObject = new
{
Message = this.Layout.Render(logEvent),
Level = logEvent.Level.Name,
TimeStamp = logEvent.TimeStamp.ToString("yyyy-MM-dd HH:mm:ss.fff")
};
clients.onLoggedEvent(logEventObject);
}
private dynamic GetClients()
{
return ConnectionManager.GetClients<SignalrTargetHub>();
}
}
I ended up with the basic the same basic structure that I started with. Just a few tweaks to get the information I needed.
Added exception details.
Html encoded the final message.
[Target("Signalr")]
public class SignalrTarget:TargetWithLayout
{
protected override void Write(NLog.LogEventInfo logEvent)
{
var sb = new System.Text.StringBuilder();
sb.Append(this.Layout.Render(logEvent));
if (logEvent.Exception != null)
sb.AppendLine().Append(logEvent.Exception.ToString());
var message = HttpUtility.HtmlEncode(sb.ToString());
var logEventObject = new
{
Message = message,
Logger = logEvent.LoggerName,
Level = logEvent.Level.Name,
TimeStamp = logEvent.TimeStamp.ToString("HH:mm:ss.fff")
};
GetClients().onLoggedEvent(logEventObject);
}
private dynamic GetClients()
{
return AspNetHost.DependencyResolver.Resolve<IConnectionManager>().GetClients<SignalrTargetHub>();
}
}
In my simple testing it's working well. Still remains to be seen if this adds any significant load when under stress.

Resources