TestNG&Allure: stop test execution after 1st failure - automated-tests

I have a flaky test which fails once per 10-20 attempts because of intermittently reproducible bug. I'd like to have this test to be marked as Failed after first failure. No further retries needed.
This is how the Test annotation looks like:
#Test(invocationCount = 20, threadPoolSize = 3)
The problem is that if it fails not in the last round - Allure report treat it as "Flaky" test and the report is green.
What I'm trying to achieve is terminate test method retrying after the first failure. This test should be red in Allure report.

The annotations are set before runtime, so once you are running the test, you cannot change the invocationCount.
What you can do, is to use a listener to stop the execution when it reaches onTestFailure.
So let's say you have the test class:
import org.testng.ITestContext;
import org.testng.annotations.Test;
import org.testng.asserts.Assertion;
import org.testng.annotations.Listeners;
#Listeners(TestListener.class)
public class CreateBookingTest extends TestConfig {
#Test(invocationCount = 20)
public void stopInvocationsTest(ITestContext testContext) {
int currentCount = testContext.getAllTestMethods()[0].getCurrentInvocationCount();
// We will force a failure in the invocation 5 (the 6th run).
if (currentCount==5) {
new Assertion().fail("Method failed in invocation " + currentCount);
}
}
}
Then the listener will abort th execution if there's a single failure and stop from running the rest of the tests:
import org.testng.ITestContext;
import org.testng.ITestListener;
import org.testng.ITestResult;
import org.testng.asserts.Assertion;
public class TestListener implements ITestListener {
#Override
public void onTestStart(ITestResult result) {
System.out.println("\nSTARTING: " + result.getMethod().getCurrentInvocationCount());
}
#Override
public void onTestSuccess(ITestResult result) {
System.out.println("PASSED: " + result.getMethod().getCurrentInvocationCount());
}
#Override
public void onTestFailure(ITestResult result) {
System.out.println("FAILED: " + result.getMethod().getCurrentInvocationCount());
new Assertion().fail("Aborting");
}
#Override
public void onTestSkipped(ITestResult result) {
}
#Override
public void onTestFailedButWithinSuccessPercentage(ITestResult result) {
}
#Override
public void onStart(ITestContext context) {
}
#Override
public void onFinish(ITestContext context) {
}
}

Related

Peformance issues when creating nodes using FXML [duplicate]

Problem
I want to add custom made panels, built via javafx scene builder, to a gridpane at runtime. My custom made panel exsits of buttons, labels and so on.
My Attempt
I tried to extend from pane...
public class Celli extends Pane{
public Celli() throws IOException{
Parent root = FXMLLoader.load(getClass().getResource("Cell.fxml"));
this.getChildren().add(root);
}
}
... and then use this panel in the adding method of the conroller
#FXML
private void textChange(KeyEvent event) {
GridPane g = new GridPane();
for (int i=0 : i<100; i++){
g.getChildren().add(new Celli());
}
}
}
It works, but it performs very very poor.
What I am looking for
Is there a way to design panels via javafx scene builder (and as a result having this panels in fxml) and then add it to a gridpane at runtime without make use of this fxmlloader for each instance. I think it performs poor because of the fxml loader. When I add a standard button e.g. whitout fxml it is very much faster.
Short answer: No, it is not (as of JavaFX 2.x and 8.0). It may be in a future version (JFX >8)
Long answer:
The FXMLLoader is currently not designed to perform as a template provider that instantiates the same item over and over again. Rather it is meant to be a one-time-loader for large GUIs (or to serialize them).
The performance is poor because depending on the FXML file, on each call to load(), the FXMLLoader has to look up the classes and its properties via reflection. That means:
For each import statement, try to load each class until the class could successfully be loaded.
For each class, create a BeanAdapter that looks up all properties this class has and tries to apply the given parameters to the property.
The application of the parameters to the properties is done via reflection again.
There is also currently no improvement for subsequent calls to load() to the same FXML file done in the code. This means: no caching of found classes, no caching of BeanAdapters and so on.
There is a workaround for the performance of step 1, though, by setting a custom classloader to the FXMLLoader instance:
import java.io.IOException;
import java.net.URL;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
public class MyClassLoader extends ClassLoader{
private final Map<String, Class> classes = new HashMap<String, Class>();
private final ClassLoader parent;
public MyClassLoader(ClassLoader parent) {
this.parent = parent;
}
#Override
public Class<?> loadClass(String name) throws ClassNotFoundException {
Class<?> c = findClass(name);
if ( c == null ) {
throw new ClassNotFoundException( name );
}
return c;
}
#Override
protected Class<?> findClass( String className ) throws ClassNotFoundException {
// System.out.print("try to load " + className);
if (classes.containsKey(className)) {
Class<?> result = classes.get(className);
return result;
} else {
try {
Class<?> result = parent.loadClass(className);
// System.out.println(" -> success!");
classes.put(className, result);
return result;
} catch (ClassNotFoundException ignore) {
// System.out.println();
classes.put(className, null);
return null;
}
}
}
// ========= delegating methods =============
#Override
public URL getResource( String name ) {
return parent.getResource(name);
}
#Override
public Enumeration<URL> getResources( String name ) throws IOException {
return parent.getResources(name);
}
#Override
public String toString() {
return parent.toString();
}
#Override
public void setDefaultAssertionStatus(boolean enabled) {
parent.setDefaultAssertionStatus(enabled);
}
#Override
public void setPackageAssertionStatus(String packageName, boolean enabled) {
parent.setPackageAssertionStatus(packageName, enabled);
}
#Override
public void setClassAssertionStatus(String className, boolean enabled) {
parent.setClassAssertionStatus(className, enabled);
}
#Override
public void clearAssertionStatus() {
parent.clearAssertionStatus();
}
}
Usage:
public static ClassLoader cachingClassLoader = new MyClassLoader(FXMLLoader.getDefaultClassLoader());
FXMLLoader loader = new FXMLLoader(resource);
loader.setClassLoader(cachingClassLoader);
This significantly speeds up the performance. However, there is no workaround for step 2, so this might still be a problem.
However, there are already feature requests in the official JavaFX jira for this. It would be nice of you to support this requests.
Links:
FXMLLoader should be able to cache imports and properties between to load() calls:
https://bugs.openjdk.java.net/browse/JDK-8090848
add setAdapterFactory() to the FXMLLoader:
https://bugs.openjdk.java.net/browse/JDK-8102624
I have had a similar issue. I also had to load a custom fxml-based component several times, dynamically, and it was taking too long. The FXMLLoader.load method call was expensive, in my case.
My approach was to parallelize the component instantiation and it solved the problem.
Considering the example posted on the question, the controller method with multithread approach would be:
private void textChange(KeyEvent event) {
GridPane g = new GridPane();
// creates a thread pool with 10 threads
ExecutorService threadPool = Executors.newFixedThreadPool(10);
final List<Celli> listOfComponents = Collections.synchronizedList(new ArrayList<Celli>(100));
for (int i = 0; i < 100; i++) {
// parallelizes component loading
threadPool.execute(new Runnable() {
#Override
public void run() {
listOfComponents.add(new Celli());
}
});
}
// waits until all threads completion
try {
threadPool.shutdown();
threadPool.awaitTermination(3, TimeUnit.SECONDS);
} catch (InterruptedException e) {
// seems to be a improbable exception, but we have to deal with it
e.printStackTrace();
}
g.getChildren().addAll(listOfComponents);
}
Just adding code for "caching of already loaded classes" in #Sebastian sir given code. It is working for me. Please suggest changes in it for better performance.
#Override
public Class<?> loadClass(String name) throws ClassNotFoundException {
System.out.println("In Class loader");
Class result;
System.out.println(" >>>>>> Load class : "+name);
result = (Class)classes.get(name);
if(result != null){
System.out.println(" >>>>>> returning cached class.");
return result;
}else{
Class<?> c = findClass(name);
if ( c == null ) {
throw new ClassNotFoundException( name );
}
System.out.println(" >>>>>> loading new class for first time only");
return c;
}
}

HERE SDK TrafficUpdater.request(Geocordinate, TrafficUpdater.Listener) not returning traffic results

I have been working on integrating several HERE features into an app I am working on. Right now I am trying to add traffic data to the application. The default auto-updates aren't quite frequent enough for me (~1 min), so I am trying to use the TrafficUpdater.request(GeoCoordinate, TrafficUpdater.Listener) to manually retrieve traffic information every 5 seconds or so. The problem is, although the request line executes, the listener is never called, and I never receive any traffic updates. Below is my activity:
import android.os.CountDownTimer;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import com.here.android.mpa.common.GeoCoordinate;
import com.here.android.mpa.common.GeoPosition;
import com.here.android.mpa.common.MapSettings;
import com.here.android.mpa.common.OnEngineInitListener;
import com.here.android.mpa.common.PositioningManager;
import com.here.android.mpa.guidance.TrafficUpdater;
import com.here.android.mpa.mapping.Map;
import com.here.android.mpa.mapping.MapFragment;
import com.here.android.mpa.mapping.MapTrafficLayer;
import com.here.android.mpa.mapping.MapView;
import com.here.android.mpa.mapping.TrafficEvent;
import java.io.File;
import java.lang.ref.WeakReference;
public class MainActivity extends AppCompatActivity {
private Map map;
private MapFragment mapFragment;
private TrafficUpdater trafficUpdater;
private PositioningManager.OnPositionChangedListener onPositionChangedListener = new PositioningManager.OnPositionChangedListener() {
#Override
public void onPositionUpdated(PositioningManager.LocationMethod locationMethod, GeoPosition geoPosition, boolean b) {
onLocationUpdate(geoPosition);
}
#Override
public void onPositionFixChanged(PositioningManager.LocationMethod locationMethod, PositioningManager.LocationStatus locationStatus) {
}
};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
MapSettings.setIsolatedDiskCacheRootPath(
getApplicationContext().getExternalFilesDir(null) + File.separator + ".here-maps",
"MAP_SERVICE");
mapFragment = (MapFragment) getFragmentManager().findFragmentById(R.id.map);
mapFragment.init(new OnEngineInitListener() {
#Override
public void onEngineInitializationCompleted(Error error) {
if (error == Error.NONE) {
map = mapFragment.getMap();
initTracker();
}
}
});
}
private void initTracker() {
trafficUpdater = TrafficUpdater.getInstance();
trafficUpdater.enableUpdate(false);
PositioningManager positioningManager = PositioningManager.getInstance();
positioningManager.addListener(new WeakReference<PositioningManager.OnPositionChangedListener>(onPositionChangedListener));
mapFragment.getPositionIndicator().setVisible(true);
positioningManager.start(PositioningManager.LocationMethod.GPS_NETWORK);
}
private boolean isTimerRunning = false;
CountDownTimer trafficTimer = new CountDownTimer(5000,5000) {
#Override
public void onTick(long millisUntilFinished) {
}
#Override
public void onFinish() {
isTimerRunning = false;
getTrafficInfo();
}
};
private GeoPosition lastGeoPosition;
private void onLocationUpdate(GeoPosition geoPosition) {
map.setCenter(geoPosition.getCoordinate(), Map.Animation.NONE);
Log.i("____MAINACTIVITY", "location update");
lastGeoPosition = geoPosition;
if(!isTimerRunning) {
trafficTimer.cancel();
trafficTimer.start();
isTimerRunning = true;
}
}
private TrafficUpdater.Listener trafficListener = new TrafficUpdater.Listener() {
#Override
public void onStatusChanged(TrafficUpdater.RequestState requestState) {
Log.i("____MAINACTIVITY", requestState.name());
}
};
private void getTrafficInfo() {
if(lastGeoPosition != null) {
TrafficUpdater.RequestInfo requestInfo = trafficUpdater.request(lastGeoPosition.getCoordinate(), trafficListener);
Log.i("___MAINACTIVITY", requestInfo.getError().name());
}
}
}
I have tried several things to remedy this issue. First, I have checked all of my app permissions and project dashboard on the developer portal to ensure everything is setup properly, and it is. I was providing the listener as an anonymous method in the line we execute the request, and that did not work. I moved the listener to be a private member variable of the activity, and provided it that way, but it still isn't working. I've checked the RequestInfo returned by the method, and it always indicates an error code of NONE, so it seems as though no errors are occurring. Lastly, I set my updater frequency to once every 1.5 seconds (well above the default value), and I still receive nothing. Does anyone know a solution to this problem? I feel as though it's something simple that I'm missing. Updates from the Positioning Manager are coming through just fine, and the app is talking to our server with no problems, so I don't think it's a connectivity issue.
The traffic feed does provide updates only in a one minute time frame. To force the application to request this in a higher frequency won't provide fresher data. I would recommend to keep the default auto-updates.

jogl installation to native library

How can we add jogl to native java library so that we can run a jogl program like any other java program using notepad without any ide like netbeans, eclipse.
I have downloaded jogl. To test it i have run the following example program given in the documentation.
But i get an error saying the package javax.media.opengl doesnot exist.
i read the installation guide in tutorialspoint.But it is given for an ide.
can't we run the jogl program using notepad.
import javax.media.opengl.GLAutoDrawable;
import javax.media.opengl.GLCapabilities;
import javax.media.opengl.GLEventListener;
import javax.media.opengl.GLProfile;
import javax.media.opengl.awt.GLCanvas;
import javax.swing.JFrame;
public class BasicFrame implements GLEventListener
{
#Override
public void display(GLAutoDrawable arg0)
{
// method body
}
#Override
public void dispose(GLAutoDrawable arg0)
{ //method body
}
#Override
public void init(GLAutoDrawable arg0)
{
// method body
}
#Override
public void reshape(GLAutoDrawable arg0, int arg1, int arg2, int arg3, int arg4) {
// method body
}
public static void main(String[] args)
{
//getting the capabilities object of GL2 profile
final GLProfile profile = GLProfile.get(GLProfile.GL2);
GLCapabilities capabilities = new GLCapabilities(profile);
// The canvas
final GLCanvas glcanvas = new GLCanvas(capabilities);
BasicFrame b = new BasicFrame();
glcanvas.addGLEventListener(b);
glcanvas.setSize(400, 400);
//creating frame
final Frame frame = new Frame (" Basic Frame");
//adding canvas to frame
frame.add(glcanvas);
frame.setSize( 640, 480 );
frame.setVisible(true);
}
}

samsung gear live audio encoding

I'm currently working on an Android Wear app, and I'm looking toward audio recording. I've followed the tutorial on the Android developper website, and it works well on my Nexus 7, but not on the Samsung Gear Live I have for testing. The application just goes crashing all the time.
Digging a bit into the problem, I might have figured out that it was a problem with 2 parameters for the recorder to work: either the OutputFormat, or the AudioEncoder. I tried pairing and trying all the OutputFormat and AudioEncoder available, but without any luck.
So here's my question: did someone encounter the same problem? And if so, did you find the right combination of Format/Encoder?
I don't paste my code as it's exactly the same as in the documentation. Here is the link if you want to have a look: http://developer.android.com/guide/topics/media/audio-capture.html
Thank you in advance for your answers and your time :)
The root problem is that you cannot use MediaRecorder, even though the Android audio capture example does, but instead you need to use the AudioRecord class.
Also, I'd recommend streaming the raw data back to your phone to assemble it into an audio file as that is very thorny on a wearable.
For more, see this answer for more.
I have included a sample below that I got working.
import android.app.Activity;
import android.content.Intent;
import android.media.AudioFormat;
import android.media.AudioRecord;
import android.media.MediaRecorder;
import android.os.Bundle;
import android.speech.RecognizerIntent;
import android.support.wearable.view.WatchViewStub;
import android.util.Log;
import android.widget.TextView;
import android.view.View;
import java.util.List;
public class MainActivity extends Activity {
private static final String TAG = MainActivity.class.getName();
private static final int SPEECH_REQUEST_CODE = 1;
private static final int RECORDER_SAMPLERATE = 44100;
private static final int RECORDER_CHANNELS = AudioFormat.CHANNEL_IN_STEREO;
private static final int RECORDER_AUDIO_ENCODING = AudioFormat.ENCODING_PCM_16BIT;
private TextView mTextView;
private AudioRecord recorder;
private int bufferSize = 0;
private Thread recordingThread = null;
private volatile boolean isRecording;
#Override
protected void onCreate(Bundle savedInstanceState) {
Log.v(TAG, "Creating MainActivity");
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final WatchViewStub stub = (WatchViewStub) findViewById(R.id.watch_view_stub);
stub.setOnLayoutInflatedListener(new WatchViewStub.OnLayoutInflatedListener() {
#Override
public void onLayoutInflated(WatchViewStub stub) {
mTextView = (TextView) stub.findViewById(R.id.text);
}
});
bufferSize =
AudioRecord.getMinBufferSize(RECORDER_SAMPLERATE,
RECORDER_CHANNELS, RECORDER_AUDIO_ENCODING);
}
public void handleRecordButtonClick(View view) {
startAudioCapture();
}
public void handleStopButtonClick(View view) {
stopAudioCapture();
}
private void startAudioCapture() {
Log.v(TAG, "Starting audio capture");
recorder = new AudioRecord(MediaRecorder.AudioSource.MIC,
RECORDER_SAMPLERATE, RECORDER_CHANNELS, RECORDER_AUDIO_ENCODING, bufferSize);
if (recorder.getState() == AudioRecord.STATE_INITIALIZED) {
recorder.startRecording();
isRecording = true;
Log.v(TAG, "Successfully started recording");
recordingThread = new Thread(new Runnable() {
#Override
public void run() {
processRawAudioData();
}
}, "AudioRecorder Thread");
recordingThread.start();
} else {
Log.v(TAG, "Failed to started recording");
}
}
private void stopAudioCapture() {
Log.v(TAG, "Stop audio capture");
recorder.stop();
isRecording = false;
recorder.release();
}
private void processRawAudioData() {
byte data[] = new byte[bufferSize];
int read = 0;
while(isRecording) {
read = recorder.read(data, 0, bufferSize);
if(AudioRecord.ERROR_INVALID_OPERATION != read) {
Log.v(TAG, "Successfully read " + data.length + " bytes of audio");
}
}
}
}

Retrieving mouse-clicks in Graphstream

Since I couldn't find any specific place to discuss this, I thought I'd post here...
I'm using graphstream 1.1 (http://graphstream-project.org/), a graph visualization library for java, to develop a data visualization tool. I'm needing to retrieve mouseclicks on nodes to display related data, but after following the library tutorial, it's still not clear for me how to do this. Does anyone that used this could help me out here with a more straightfoward answer? The tutorial I'm following is at:
http://graphstream-project.org/doc/Tutorials/Graph-Visualisation_1.0/#retrieving-mouse-clicks-on-the-viewer
public class Clicks implements ViewerListener {
protected boolean loop;
public static void main(String args[]) {
new Clicks();
}
public Clicks() {
// We do as usual to display a graph. This
// connect the graph outputs to the viewer.
// The viewer is a sink of the graph.
Graph graph = new SingleGraph("Clicks");
Viewer viewer = graph.display();
// The default action when closing the view is to quit
// the program.
viewer.setCloseFramePolicy(Viewer.CloseFramePolicy.HIDE_ONLY);
// We connect back the viewer to the graph,
// the graph becomes a sink for the viewer.
// We also install us as a viewer listener to
// intercept the graphic events.
ViewerPipe fromViewer = viewer.newViewerPipe();
fromViewer.addViewerListener(this);
fromViewer.addSink(graph);
// Then we need a loop to wait for events.
// In this loop we will need to call the
// pump() method to copy back events that have
// already occured in the viewer thread inside
// our thread.
while(loop) {
fromViewer.pump();
}
}
viewClosed(String id) {
loop = false;
}
buttonPushed(String id) {
System.out.println("Button pushed on node "+id);
}
buttonReleased(String id) {
System.out.println("Button released on node "+id);
}
}
Just got it solved! I sent an e-mail to their mailing group. The tutorial code on the website was lacking some information. Those three functions need to be public void, and other 'imports' must be added:
import org.graphstream.ui.swingViewer.Viewer;
import org.graphstream.ui.swingViewer.ViewerListener;
import org.graphstream.ui.swingViewer.ViewerPipe;
Here a simple code to show you how to add click event to the nodes of a given graph in graphstream library. This code show how you can change the node's background by clicking on it. The colors are choosen randomly:
public class TutoMouseClicked{
Graph graph;
public TutoMouseClicked(){
}
public void run(){
//Build a simple graph with one node
graph = new SingleGraph("TutoMouseClicked", false, true);
graph.setAttribute("ui.quality");
graph.setAttribute("ui.antialias");
Node n1 = graph.addNode("n1");
n1.setAttribute("ui.style", "size: 100px;");
Viewer viewer = graph.display();
viewer.getDefaultView().setMouseManager(new TutoMouseManage());
}
public static void main(String args[]) {
new TutoMouseClicked().run();
}
}
And the class TutoMouseManage that implements MouseManager interface:
public class TutoMouseManage implements MouseManager{
/**
* The view this manager operates upon.
*/
protected View view;
/**
* The graph to modify according to the view actions.
*/
protected GraphicGraph graph;
protected GraphicElement element;
#Override
public void init(GraphicGraph gg, View view) {
this.graph = gg;
this.view = view;
view.addMouseListener(this);
view.addMouseMotionListener(this);
}
#Override
public void release() {
view.removeMouseListener(this);
view.removeMouseMotionListener(this);
}
#Override
public void mouseClicked(MouseEvent me) {
element = view.findNodeOrSpriteAt(me.getX(), me.getY());
if(element != null){
Random r = new Random();
element.setAttribute("ui.style", "fill-color: rgb("+r.nextInt(256)+","+r.nextInt(256)+","+r.nextInt(256)+");");
}
}
#Override
public void mousePressed(MouseEvent me) {
}
#Override
public void mouseReleased(MouseEvent me) {
}
#Override
public void mouseEntered(MouseEvent me) {
}
#Override
public void mouseExited(MouseEvent me) {
}
#Override
public void mouseDragged(MouseEvent me) {
}
#Override
public void mouseMoved(MouseEvent me) {
}
}
you can adapt this code to get what you need, add any other mouse event you want: mouse released, mouse pressed, mouse dragged and all mouse events.

Resources