Skip to content

Commit

Permalink
Cleanup and fix MultipleTestRunner
Browse files Browse the repository at this point in the history
  • Loading branch information
unclebob committed Apr 4, 2009
1 parent d20ad09 commit 314a08c
Show file tree
Hide file tree
Showing 12 changed files with 102 additions and 92 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ As you can see, each item of a list is a string. But since a string can encode
So when you send a list of instructions, what you are really sending is a string. When you receive a list of responses, what you are really receiving is a string. So the high level protocol of Slim is just strings. It looks like this:

1 !-FitNesse-! invokes the Slim Server via a command line. One of the command line arguments is the port number of the socket to listen on. !-FitNesse-! opens that socket.
2 Slim Server responds with the string "Slim -- ''V<version>''\n", where ''<version>'' is the version number of the slim ''protocol''. If this protocol ever changes, ''that'' version number will change. This is the only string that is ever sent without the ''<length>'' encoding. It is terminated by the '''\n''' instead. Every other message that slim sends will be prefixed by a ''<length>'' in ''!style_red(bytes)'', followed by a colon. !style_red(NOTE:) Every other length in this document is in ''characters''. This one length is in bytes.
2 Slim Server responds with the string "Slim -- ''V<version>''\n", where ''<version>'' is the version number of the slim ''protocol''. If this protocol ever changes, ''that'' version number will change. This is the only string that is ever sent without the ''<length>'' encoding. It is terminated by the '''\n''' instead. Every other message that slim sends will be prefixed by a ''<length>'' in ''!style_red(bytes)'', followed by a colon. !style_red(NOTE:) Every other length in this document is in UTF-8 ''characters''. This one length is in bytes.
3 !-FitNesse-! sends a list of instructions encoded as a string of course.
4 Slim Server sends a list of responses similarly encoded.
5 3 and 4 repeat until !-FitNesse-! sends a ''bye'' directive. This is simply the string ''bye'' properly encoded with ''<length>''. e.g. "000003:bye".
Expand Down
3 changes: 3 additions & 0 deletions FitNesseRoot/FitNesse/content.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
|!c !2 Contents|
|!contents -g|

!path fitnesse.jar
!path classes




Expand Down
3 changes: 0 additions & 3 deletions FitNesseRoot/FitNesse/properties.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,8 @@
<properties>
<Files/>
<Help/>
<LastModified>20090228113822</LastModified>
<RecentChanges>true</RecentChanges>
<Search/>
<Suites/>
<WhereUsed/>
<saveId>1201555823432</saveId>
<ticketId>6937893733333785404</ticketId>
</properties>
6 changes: 3 additions & 3 deletions FitNesseRoot/FrontPage/content.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@
To add your first "page", click the [[Edit][FrontPage?edit]] button and add a [[!-WikiWord-!][FitNesse.WikiWord]] to the page.

| '''To Learn More...'''|
| [[A One-Minute Description][FitNesse.UserGuide.OneMinuteDescription]]|''What is [[FitNesse][FitNesse.FitNesse]]? Start here.''|
| [[A Two-Minute Example][FitNesse.UserGuide.TwoMinuteExample]]|''A brief example. Read this one next.''|
| [[A One-Minute Description][FitNesse.OneMinuteDescription]]|''What is [[FitNesse][FitNesse.FitNesse]]? Start here.''|
| [[A Two-Minute Example][FitNesse.TwoMinuteExample]]|''A brief example. Read this one next.''|
| [[User Guide][FitNesse.UserGuide]]|''Answer the rest of your questions here.''|
| [[Acceptance Tests][FitNesse.SuiteAcceptanceTests]]|''FitNesse's suite of Acceptance Tests''|

!note Release v20090403
!note Release v20090404
16 changes: 8 additions & 8 deletions FitNesseRoot/RecentChanges/content.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,11 @@
|FitNesse.UserGuide.SliM.SlimProtocol||06:49:33 Fri, Apr 03, 2009|
|JunkParent||09:38:28 Sat, Apr 04, 2009|
|JunkParent.RubyTests.JunkTests||09:30:35 Sat, Apr 04, 2009|
|JunkParent.RubyTests.DummyPage||09:14:25 Sat, Apr 04, 2009|
|FitNesse.UserGuide.SliM.SlimProtocol||09:11:29 Sat, Apr 04, 2009|
|JunkParent.RubyTests.DummyPage.MultiByteCharsRubySlim||08:55:36 Sat, Apr 04, 2009|
|FitNesse||04:53:40 Sat, Apr 04, 2009|
|||04:53:02 Sat, Apr 04, 2009|
|JunkParent.RubyTests.MultiByteCharsRubySlim||07:34:50 Fri, Apr 03, 2009|
|FrontPage||06:44:20 Fri, Apr 03, 2009|
|FitNesse.SuiteAcceptanceTests.SuiteSlimTests.MultiByteCharsInSlim||06:34:54 Fri, Apr 03, 2009|
|JunkParent.MultiByteCharsInSlim||05:57:47 Fri, Apr 03, 2009|
Expand Down Expand Up @@ -91,10 +98,3 @@
|FitNesse.SliM.DecisionTable||09:11:34 Tue, Mar 17, 2009|
|FitNesse.SliM.SlimProtocol.PortManagement||13:34:02 Mon, Mar 16, 2009|
|FitNesse.SliM.SlimProtocol||13:30:40 Mon, Mar 16, 2009|
|FitNesse.QuickReferenceGuide||13:27:12 Mon, Mar 16, 2009|
|FitNesse.TodaysDate||15:08:21 Sun, Mar 15, 2009|
|FitNesse.MarkupLanguageReference||14:50:06 Sun, Mar 15, 2009|
|FitNesse.FitNesseWontStart||14:11:12 Sun, Mar 15, 2009|
|FitNesse.TestSuites||18:10:12 Thu, Mar 12, 2009|
|FitNesse.SuiteAcceptanceTests.SuiteWidgetTests.SimpleWidgets||17:30:14 Thu, Mar 12, 2009|
|FitNesse.SuiteAcceptanceTests.SuiteSlimTests||13:07:10 Thu, Mar 12, 2009|
3 changes: 1 addition & 2 deletions FitNesseRoot/content.txt
Original file line number Diff line number Diff line change
@@ -1,2 +1 @@
!path classes
!path fitnesse.jar

2 changes: 1 addition & 1 deletion FitNesseRoot/properties
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,6 @@ PropertiesToXmlUpdate=applied
FilesAttributeUpdate=applied
SymLinkPropertyFormatUpdate=applied
VirtualWikiDeprecationUpdate=applied
WhereUsedAttributeUpdate=applied
RecentChangesAttributeUpdate=applied
WhereUsedAttributeUpdate=applied
=======
2 changes: 0 additions & 2 deletions FitNesseRoot/properties.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,10 @@
<properties>
<Edit>true</Edit>
<Files>true</Files>
<LastModified>20090228113821</LastModified>
<Properties>true</Properties>
<RecentChanges>true</RecentChanges>
<Refactor>true</Refactor>
<Search>true</Search>
<Versions>true</Versions>
<WhereUsed>true</WhereUsed>
<ticketId>3338770679626498962</ticketId>
</properties>
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
<description> The fully integrated standalone wiki, and acceptance
testing framework. </description>
<url>http://fitnesse.org</url>
<version>20090403</version>
<version>20090404</version>
<licenses>
<license>
<name>GNU Public License, Version 2.0</name>
Expand Down
2 changes: 1 addition & 1 deletion src/fitnesse/FitNesseVersion.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,6 @@

public class FitNesseVersion {
public String toString() {
return "v20090403";
return "v20090404";
}
}
149 changes: 81 additions & 68 deletions src/fitnesse/responders/run/MultipleTestsRunner.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,23 +2,17 @@
// Released under the terms of the CPL Common Public License version 1.0.
package fitnesse.responders.run;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;

import fitnesse.FitNesseContext;
import fitnesse.components.ClassPathBuilder;
import fitnesse.html.SetupTeardownIncluder;
import fitnesse.responders.run.TestSystem.Descriptor;
import fitnesse.wiki.PageData;
import fitnesse.wiki.WikiPage;

public class MultipleTestsRunner implements TestSystemListener, Stoppable{

import java.util.*;

public class MultipleTestsRunner implements TestSystemListener, Stoppable {

private final ResultsListener resultsListener;
private final FitNesseContext fitNesseContext;
private final WikiPage page;
Expand All @@ -27,13 +21,16 @@ public class MultipleTestsRunner implements TestSystemListener, Stoppable{

private LinkedList<WikiPage> processingQueue = new LinkedList<WikiPage>();
private WikiPage currentTest = null;

private TestSystemGroup testSystemGroup = null;
private TestSystem currentTestSystem = null;
private boolean isStopped = false;
private String stopId = null;

public MultipleTestsRunner(final List<WikiPage> testPagesToRun,
private class PagesByTestSystem extends HashMap<TestSystem.Descriptor, LinkedList<WikiPage>> {
}

public MultipleTestsRunner(final List<WikiPage> testPagesToRun,
final FitNesseContext fitNesseContext,
final WikiPage page,
final ResultsListener resultsListener) {
Expand All @@ -42,33 +39,29 @@ public MultipleTestsRunner(final List<WikiPage> testPagesToRun,
this.page = page;
this.fitNesseContext = fitNesseContext;
}

/**
* Fast test must be called before you run execute test pages
* @param isFastTest
*/

public void setFastTest(boolean isFastTest) {
this.isFastTest = isFastTest;
}

public void executeTestPages() {
try {
internalExecuteTestPages();
}
catch (Exception exception) {
exceptionOccurred(exception);
}
}
}

private void internalExecuteTestPages() throws Exception {
synchronized (this) {
testSystemGroup = new TestSystemGroup(fitNesseContext, page, this);
stopId = fitNesseContext.runningTestingTracker.addStartedProcess(this);
}
testSystemGroup.setFastTest(isFastTest);

resultsListener.setExecutionLogAndTrackingId(stopId, testSystemGroup.getExecutionLog());
Map<TestSystem.Descriptor, LinkedList<WikiPage>> pagesByTestSystem = makeMapOfPagesByTestSystem();
PagesByTestSystem pagesByTestSystem = makeMapOfPagesByTestSystem();
announceTotalTestsToRun(pagesByTestSystem);
for (TestSystem.Descriptor descriptor : pagesByTestSystem.keySet()) {
executePagesInTestSystem(descriptor, pagesByTestSystem);
Expand All @@ -77,10 +70,10 @@ private void internalExecuteTestPages() throws Exception {
}

private void executePagesInTestSystem(TestSystem.Descriptor descriptor,
Map<TestSystem.Descriptor, LinkedList<WikiPage>> pagesByTestSystem) throws Exception {
List<WikiPage> pagesInTestSystem = pagesByTestSystem.get(descriptor);
PagesByTestSystem pagesByTestSystem) throws Exception {
List<WikiPage> pagesInTestSystem = pagesByTestSystem.get(descriptor);

startTestSystemAndExecutePages(descriptor, pagesInTestSystem);
startTestSystemAndExecutePages(descriptor, pagesInTestSystem);
}

private void startTestSystemAndExecutePages(TestSystem.Descriptor descriptor, List<WikiPage> testSystemPages) throws Exception {
Expand All @@ -99,7 +92,7 @@ private void startTestSystemAndExecutePages(TestSystem.Descriptor descriptor, Li
} else {
throw new Exception("Test system not started");
}

synchronized (this) {
if (!isStopped) {
testSystem.bye();
Expand All @@ -117,61 +110,81 @@ private void executeTestSystemPages(List<WikiPage> pagesInTestSystem, TestSystem
testSystem.runTestsAndGenerateHtml(pageData);
}
}

private void waitForTestSystemToSendResults() throws InterruptedException {
while ((processingQueue.size() > 0) && isNotStopped())
Thread.sleep(50);
}

Map<TestSystem.Descriptor, LinkedList<WikiPage>> makeMapOfPagesByTestSystem() throws Exception {
Map<TestSystem.Descriptor, LinkedList<WikiPage>> map = new HashMap<TestSystem.Descriptor, LinkedList<WikiPage>>();

Map<WikiPage, TestSystem.Descriptor> pageToSystemMap = new HashMap<WikiPage, TestSystem.Descriptor>(testPagesToRun.size());


PagesByTestSystem makeMapOfPagesByTestSystem() throws Exception {
return addSuiteSetUpAndTearDownToAllTestSystems(mapWithAllPagesButSuiteSetUpAndTearDown());
}

private PagesByTestSystem mapWithAllPagesButSuiteSetUpAndTearDown() throws Exception {
PagesByTestSystem pagesByTestSystem = new PagesByTestSystem();

for (WikiPage testPage : testPagesToRun) {
TestSystem.Descriptor descriptor = TestSystem.getDescriptor(testPage.getData());
pageToSystemMap.put(testPage, descriptor);
getPagesForTestSystem(map, descriptor);
if (!SuiteContentsFinder.isSuiteSetupOrTearDown(testPage)) {
addPageToListWithinMap(pagesByTestSystem, testPage);
}
}
return pagesByTestSystem;
}

for (WikiPage testPage : testPagesToRun) {
if (SuiteContentsFinder.isSuiteSetupOrTearDown(testPage)) {
// add to all test systems
for (TestSystem.Descriptor descriptor : map.keySet()) {
List<WikiPage> pagesForTestSystem = getPagesForTestSystem(map, descriptor);
pagesForTestSystem.add(testPage);
}
private void addPageToListWithinMap(PagesByTestSystem pagesByTestSystem, WikiPage testPage) throws Exception {
Descriptor descriptor = TestSystem.getDescriptor(testPage.getData());
getOrMakeListWithinMap(pagesByTestSystem, descriptor).add(testPage);
}

private LinkedList<WikiPage> getOrMakeListWithinMap(PagesByTestSystem pagesByTestSystem, Descriptor descriptor) {
LinkedList<WikiPage> pagesForTestSystem;
if (!pagesByTestSystem.containsKey(descriptor)) {
pagesForTestSystem = new LinkedList<WikiPage>();
pagesByTestSystem.put(descriptor, pagesForTestSystem);
} else {
pagesForTestSystem = pagesByTestSystem.get(descriptor);
}
return pagesForTestSystem;
}

private PagesByTestSystem addSuiteSetUpAndTearDownToAllTestSystems(PagesByTestSystem pagesByTestSystem) throws Exception {
WikiPage firstPage = testPagesToRun.get(0);
WikiPage lastPage = testPagesToRun.get(testPagesToRun.size() - 1);

prependSuiteSetupToAllPageLists(pagesByTestSystem, firstPage);
appendSuiteTearDownToAllPageLists(pagesByTestSystem, lastPage);

return pagesByTestSystem;
}

private void appendSuiteTearDownToAllPageLists(PagesByTestSystem pagesByTestSystem, WikiPage page) throws Exception {
if (SuiteContentsFinder.SUITE_TEARDOWN_NAME.equals(page.getName())) {
for (Descriptor descriptor : pagesByTestSystem.keySet()) {
List<WikiPage> pagesForTestSystem = pagesByTestSystem.get(descriptor);
pagesForTestSystem.add(page);
}
else {
// add only to the system for running the page
List<WikiPage> pagesForTestSystem = getPagesForTestSystem(map, pageToSystemMap.get(testPage));
pagesForTestSystem.add(testPage);
}
}

private void prependSuiteSetupToAllPageLists(PagesByTestSystem pagesByTestSystem, WikiPage page) throws Exception {
if ((SuiteContentsFinder.SUITE_SETUP_NAME.equals(page.getName()))) {
for (Descriptor descriptor : pagesByTestSystem.keySet()) {
List<WikiPage> pagesForTestSystem = pagesByTestSystem.get(descriptor);
pagesForTestSystem.add(0, page);
}
}
return map;
}
private void announceTotalTestsToRun(Map<Descriptor, LinkedList<WikiPage>> pagesByTestSystem) {

private void announceTotalTestsToRun(PagesByTestSystem pagesByTestSystem) {
int tests = 0;
for (LinkedList<WikiPage> listOfPagesToRun : pagesByTestSystem.values()) {
tests += listOfPagesToRun.size();
}
resultsListener.announceNumberTestsToRun(tests);
}

private List<WikiPage> getPagesForTestSystem(Map<TestSystem.Descriptor, LinkedList<WikiPage>> map, TestSystem.Descriptor descriptor) {
LinkedList<WikiPage> listInMap;
if (map.containsKey(descriptor))
listInMap = map.get(descriptor);
else {
listInMap = new LinkedList<WikiPage>();
map.put(descriptor, listInMap);
}
return listInMap;
}

public String buildClassPath() throws Exception {

final ClassPathBuilder classPathBuilder = new ClassPathBuilder();
final String pathSeparator = classPathBuilder.getPathSeparator(page);
List<String> classPathElements = new ArrayList<String>();
Expand All @@ -180,12 +193,12 @@ public String buildClassPath() throws Exception {
for (WikiPage testPage : testPagesToRun) {
addClassPathElements(testPage, classPathElements, visitedPages);
}

return classPathBuilder.createClassPathString(classPathElements, pathSeparator);
}

private void addClassPathElements(WikiPage page, List<String> classPathElements, Set<WikiPage> visitedPages)
throws Exception {
throws Exception {
List<String> pathElements = new ClassPathBuilder().getInheritedPathElements(page, visitedPages);
classPathElements.addAll(pathElements);
}
Expand All @@ -202,7 +215,7 @@ public void acceptOutputFirst(String output) throws Exception {

public void acceptResultsLast(TestSummary testSummary) throws Exception {
WikiPage testPage = processingQueue.removeFirst();

resultsListener.processTestResults(testPage, testSummary);
}

Expand All @@ -217,11 +230,11 @@ public synchronized void exceptionOccurred(Throwable e) {
}
}
}

private synchronized boolean isNotStopped() {
return !isStopped;
}

public void stop() throws Exception {
boolean wasNotStopped = isNotStopped();
synchronized (this) {
Expand All @@ -230,7 +243,7 @@ public void stop() throws Exception {
fitNesseContext.runningTestingTracker.removeEndedProcess(stopId);
}
}

if (wasNotStopped) {
testSystemGroup.kill();
}
Expand Down
Loading

0 comments on commit 314a08c

Please sign in to comment.