Skip to content

Commit

Permalink
Fix for #184 Implemented test retry handler for tests
Browse files Browse the repository at this point in the history
  • Loading branch information
ishubin committed Jan 3, 2015
1 parent 33f2ef5 commit 67d50e0
Show file tree
Hide file tree
Showing 10 changed files with 247 additions and 92 deletions.
81 changes: 6 additions & 75 deletions src/main/java/net/mindengine/galen/GalenMain.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,7 @@
import java.io.StringWriter;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Date;
import java.util.LinkedList;
import java.util.*;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
Expand Down Expand Up @@ -306,62 +304,17 @@ private void runTestsInThreads(final EventHandler eventHandler, List<GalenTest>
ExecutorService executor = Executors.newFixedThreadPool(amountOfThreads);

Pattern filterPattern = createTestFilter(arguments.getFilter());
final List<GalenTestInfo> testInfos = new LinkedList<GalenTestInfo>();


tests = filterTests(tests, eventHandler);

tellBeforeTestSuite(listener, tests);

final ReentrantLock testInfoLock = new ReentrantLock();



List<GalenTestInfo> testInfos = Collections.synchronizedList(new LinkedList<GalenTestInfo>());

for (final GalenTest test : tests) {
if (matchesPattern(test.getName(), filterPattern)) {
Runnable thread = new Runnable() {
@Override
public void run() {

GalenTestInfo info = new GalenTestInfo(test.getName(), test);
TestReport report = new TestReport();

info.setStartedAt(new Date());
info.setReport(report);


testInfoLock.lock();
try {
testInfos.add(info);
TestSession session = TestSession.register(info);
session.setReport(report);
session.setListener(listener);
}
catch (Exception ex) {
ex.printStackTrace();
}
finally {
testInfoLock.unlock();
}

eventHandler.invokeBeforeTestEvents(info);

tellTestStarted(listener, test);
try {
test.execute(report, listener);
}
catch(Throwable ex) {
info.setException(ex);
report.error(ex);
ex.printStackTrace();
}
info.setEndedAt(new Date());

eventHandler.invokeAfterTestEvents(info);
tellTestFinished(listener, test);

TestSession.clear();
}
};
executor.execute(thread);
executor.execute(new TestRunnable(test, listener, eventHandler, testInfos));
}
}
executor.shutdown();
Expand Down Expand Up @@ -413,28 +366,6 @@ private void tellAfterTestSuite(SuiteListener listener, List<GalenTestInfo> test
}
}

private void tellTestFinished(TestListener testListener, GalenTest test) {
try {
if (testListener != null) {
testListener.onTestFinished(test);
}
}
catch (Exception e) {
e.printStackTrace();
}
}

private void tellTestStarted(TestListener testListener, GalenTest test) {
try {
if (testListener != null) {
testListener.onTestStarted(test);
}
}
catch (Exception e) {
e.printStackTrace();
}
}

private void createAllReports(List<GalenTestInfo> testInfos, GalenArguments arguments) {
if (arguments.getTestngReport() != null) {
createTestngReport(arguments.getTestngReport(), testInfos);
Expand Down
126 changes: 126 additions & 0 deletions src/main/java/net/mindengine/galen/TestRunnable.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
/*******************************************************************************
* Copyright 2015 Ivan Shubin http://mindengine.net
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
******************************************************************************/
package net.mindengine.galen;

import net.mindengine.galen.reports.GalenTestInfo;
import net.mindengine.galen.reports.TestReport;
import net.mindengine.galen.runner.CompleteListener;
import net.mindengine.galen.runner.EventHandler;
import net.mindengine.galen.runner.TestListener;
import net.mindengine.galen.runner.events.TestRetryEvent;
import net.mindengine.galen.tests.GalenTest;
import net.mindengine.galen.tests.TestSession;

import java.util.Date;
import java.util.List;

/**
* Used for running the test and invoking all test related events like: before, after, testRetry
*/
public class TestRunnable implements Runnable {
private final GalenTest test;
private final CompleteListener listener;
private final EventHandler eventHandler;
private final List<GalenTestInfo> testInfos;

public TestRunnable(GalenTest test, CompleteListener listener, EventHandler eventHandler, List<GalenTestInfo> testInfos) {
this.test = test;
this.listener = listener;
this.eventHandler = eventHandler;
this.testInfos = testInfos;
}


private GalenTestInfo runTest() {
GalenTestInfo info = new GalenTestInfo(test.getName(), test);
TestReport report = new TestReport();

info.setStartedAt(new Date());
info.setReport(report);


TestSession session = TestSession.register(info);
session.setReport(report);
session.setListener(listener);

eventHandler.invokeBeforeTestEvents(info);

tellTestStarted(listener, test);
try {
test.execute(report, listener);
}
catch(Throwable ex) {
info.setException(ex);
report.error(ex);
ex.printStackTrace();
}
info.setEndedAt(new Date());

eventHandler.invokeAfterTestEvents(info);
tellTestFinished(listener, test);

TestSession.clear();

return info;
}

@Override
public void run() {

GalenTestInfo info = null;
boolean shouldRetry = true;
int tries = 1;
while (shouldRetry) {
info = runTest();
shouldRetry = checkIfShouldRetry(info.getTest(), tries);
tries++;
}

testInfos.add(info);
}

private boolean checkIfShouldRetry(GalenTest test, int tries) {
for (TestRetryEvent retryEvent : eventHandler.getTestRetryEvents()) {
if (retryEvent.shouldRetry(test, tries)) {
return true;
}
}
return false;
}

private void tellTestFinished(TestListener testListener, GalenTest test) {
try {
if (testListener != null) {
testListener.onTestFinished(test);
}
}
catch (Exception e) {
e.printStackTrace();
}
}

private void tellTestStarted(TestListener testListener, GalenTest test) {
try {
if (testListener != null) {
testListener.onTestStarted(test);
}
}
catch (Exception e) {
e.printStackTrace();
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import net.mindengine.galen.browser.WebDriverWrapper;
import net.mindengine.galen.runner.events.TestEvent;
import net.mindengine.galen.runner.events.TestFilterEvent;
import net.mindengine.galen.runner.events.TestRetryEvent;
import net.mindengine.galen.runner.events.TestSuiteEvent;
import net.mindengine.galen.tests.GalenTest;
import net.mindengine.galen.tests.TestSession;
Expand Down Expand Up @@ -69,6 +70,7 @@ private void importAllMajorClasses() {
TestEvent.class,
TestSuiteEvent.class,
TestFilterEvent.class,
TestRetryEvent.class,
Galen.class
});
}
Expand Down
10 changes: 10 additions & 0 deletions src/main/java/net/mindengine/galen/runner/EventHandler.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,15 @@
import net.mindengine.galen.reports.GalenTestInfo;
import net.mindengine.galen.runner.events.TestEvent;
import net.mindengine.galen.runner.events.TestFilterEvent;
import net.mindengine.galen.runner.events.TestRetryEvent;
import net.mindengine.galen.runner.events.TestSuiteEvent;

public class EventHandler {

private List<TestEvent> beforeTestEvents = new LinkedList<TestEvent>();
private List<TestEvent> afterTestEvents = new LinkedList<TestEvent>();
private List<TestFilterEvent> testFilterEvents = new LinkedList<TestFilterEvent>();
private List<TestRetryEvent> testRetryEvents = new LinkedList<TestRetryEvent>();

private List<TestSuiteEvent> beforeTestSuiteEvents = new LinkedList<TestSuiteEvent>();
private List<TestSuiteEvent> afterTestSuiteEvents = new LinkedList<TestSuiteEvent>();
Expand Down Expand Up @@ -105,4 +107,12 @@ public List<TestFilterEvent> getTestFilterEvents() {
public void setTestFilterEvents(List<TestFilterEvent> testFilterEvents) {
this.testFilterEvents = testFilterEvents;
}

public List<TestRetryEvent> getTestRetryEvents() {
return testRetryEvents;
}

public void setTestRetryEvents(List<TestRetryEvent> testRetryEvents) {
this.testRetryEvents = testRetryEvents;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import java.util.List;

import net.mindengine.galen.runner.events.TestFilterEvent;
import net.mindengine.galen.runner.events.TestRetryEvent;
import org.apache.commons.io.IOUtils;

import net.mindengine.galen.javascript.GalenJsExecutor;
Expand Down Expand Up @@ -98,4 +99,8 @@ public void addTestFilterEvent(TestFilterEvent event) {
eventHandler.getTestFilterEvents().add(event);
}

public void addTestRetryEvent(TestRetryEvent event) {
eventHandler.getTestRetryEvents().add(event);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
/*******************************************************************************
* Copyright 2015 Ivan Shubin http://mindengine.net
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
******************************************************************************/
package net.mindengine.galen.runner.events;

import net.mindengine.galen.tests.GalenTest;

public interface TestRetryEvent {
public boolean shouldRetry(GalenTest test, int retryCount);
}
17 changes: 0 additions & 17 deletions src/main/java/net/mindengine/galen/tests/TestSession.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,6 @@
package net.mindengine.galen.tests;

import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.locks.ReentrantLock;

Expand All @@ -28,7 +26,6 @@
public class TestSession {

private static final ThreadLocal<TestSession> _sessions = new ThreadLocal<TestSession>();
private static final List<TestSession> _sessionsList = new LinkedList<TestSession>();
private static final ReentrantLock lock = new ReentrantLock();

private GalenTestInfo testInfo;
Expand All @@ -46,7 +43,6 @@ public static TestSession register(GalenTestInfo info) {
try {
TestSession session = new TestSession(info);
_sessions.set(session);
_sessionsList.add(session);
return session;
}
catch (Exception ex) {
Expand Down Expand Up @@ -110,17 +106,4 @@ public GalenProperties getProperties() {
public void setProperties(GalenProperties properties) {
this.properties = properties;
}

public static List<TestSession> getAllSessions() {
lock.lock();
try {
return new LinkedList<TestSession>(_sessionsList);
}
catch (Exception ex) {
throw new RuntimeException(ex);
}
finally {
lock.unlock();
}
}
}
12 changes: 12 additions & 0 deletions src/main/resources/js/GalenCore.js
Original file line number Diff line number Diff line change
Expand Up @@ -352,6 +352,17 @@ function testFilter(callback) {
}));
}

function testRetry(callback) {
_galenCore.addTestRetryEvent(new TestRetryEvent({
callback: {
func: callback
},
shouldRetry: function (testName, retryCount) {
return this.callback.func(testName, retryCount);
}
}));
}

(function (exports) {
exports.test = test;
exports.forAll = forAll;
Expand All @@ -364,4 +375,5 @@ function testFilter(callback) {
exports.createTestDataProvider = createTestDataProvider;
exports.GalenCore = GalenCore;
exports.testFilter = testFilter;
exports.testRetry = testRetry;
})(this);
Loading

0 comments on commit 67d50e0

Please sign in to comment.