* Transition listeners are not longer stored at the ScanningState enum - it is equivalent to static. Now StateMachine does that.

* More transition methods in StateMachine, they now throw exceptions if source state is unexpected.
* Feeders now use varagrs for initialize method
* RescanFeeder and RESTARTING state introduced to support rescanning
* More tests
* Warning: rescanning functionality is not yet complete - it doesn't update the correct items in the list, more work with ScanningResultList is needed


git-svn-id: https://ipscan.svn.sourceforge.net/svnroot/ipscan/trunk@140 375186e5-ef17-0410-b0b6-91563547dcda
This commit is contained in:
angryziber 2007-07-08 19:30:56 +00:00
parent 5b368cd445
commit 7e2d427cac
25 changed files with 421 additions and 123 deletions

View File

@ -160,7 +160,7 @@ public class ComponentRegistry {
container.registerComponentImplementation(OptionsDialog.class);
container.registerComponentImplementation(SelectFetchersDialog.class);
// various actions / listener
// various actions / listeners
container.registerComponentImplementation(StartStopScanningAction.class);
container.registerComponentImplementation(ColumnsActions.SortBy.class);
container.registerComponentImplementation(ColumnsActions.FetcherOptions.class);

View File

@ -29,11 +29,12 @@ public class ScannerThread extends Thread {
private GlobalConfig config;
public ScannerThread(Feeder feeder, Scanner scanner, StateMachine stateMachine, ScanningProgressCallback progressCallback, ScanningResultList scanningResults, GlobalConfig globalConfig) {
public ScannerThread(Feeder feeder, Scanner scanner, StateMachine stateMachine, ScanningProgressCallback progressCallback, ScanningResultList scanningResults, GlobalConfig globalConfig, ScanningResultsCallback resultsCallback) {
super("Scanner Thread");
this.config = globalConfig;
this.stateMachine = stateMachine;
this.progressCallback = progressCallback;
this.resultsCallback = resultsCallback;
// this thread is daemon because we want JVM to terminate it
// automatically if user closes the program (Main thread, that is)
@ -74,7 +75,7 @@ public class ScannerThread extends Thread {
int preparationNumber = resultsCallback.prepareForResults(address);
// notify listeners of the progress we are doing
progressCallback.updateProgress(address, runningThreads, feeder.getPercentageComplete());
progressCallback.updateProgress(address, runningThreads, feeder.percentageComplete());
// scan each IP in parallel, in a separate thread
new IPThread(address, preparationNumber).start();
@ -104,12 +105,7 @@ public class ScannerThread extends Thread {
// finally, the scanning is complete
stateMachine.complete();
}
// TODO: remove me and change to constructor injection
public void setResultsCallback(ScanningResultsCallback resultsCallback) {
this.resultsCallback = resultsCallback;
}
/**
* This thread gets executed for each scanned IP address to do the actual
* scanning.

View File

@ -8,6 +8,7 @@ package net.azib.ipscan.core;
import net.azib.ipscan.config.GlobalConfig;
import net.azib.ipscan.core.state.StateMachine;
import net.azib.ipscan.feeders.Feeder;
import net.azib.ipscan.gui.ScanningResultsConsumer;
/**
* ScannerThreadFactory.
@ -30,7 +31,7 @@ public class ScannerThreadFactory {
this.globalConfig = globalConfig;
}
public ScannerThread createScannerThread(Feeder feeder, ScanningProgressCallback progressCallback) {
return new ScannerThread(feeder, scanner, stateMachine, progressCallback, scanningResults, globalConfig);
public ScannerThread createScannerThread(Feeder feeder, ScanningProgressCallback progressCallback, ScanningResultsConsumer resultsConsumer) {
return new ScannerThread(feeder, scanner, stateMachine, progressCallback, scanningResults, globalConfig, resultsConsumer);
}
}

View File

@ -29,7 +29,8 @@ public class ScanningResultList implements Iterable<ScanningResult> {
private FetcherRegistry fetcherRegistry;
// selected fetchers are cached here, because the may be changed in the registry already
private List<Fetcher> selectedFetchers;
/** TODO: use a Map instead of List here and remove all index-based access */
private List<ScanningResult> resultList = new ArrayList<ScanningResult>(1024);
private ResultsComparator resultsComparator = new ResultsComparator();

View File

@ -6,8 +6,6 @@
package net.azib.ipscan.core.state;
import java.util.ArrayList;
import java.util.List;
/**
* ScanningState enum - all possible states.
@ -17,35 +15,24 @@ import java.util.List;
public enum ScanningState {
IDLE,
STARTING,
SCANNING,
STOPPING,
KILLING;
private List<StateTransitionListener> listeners = new ArrayList<StateTransitionListener>();
KILLING,
RESTARTING;
/**
* Transitions the state to the next one
* Transitions the state to the next one.
* Note: not all states have the default next state;
*/
public ScanningState next() {
ScanningState[] states = values();
return states[ordinal()+1 % states.length];
}
public void addTransitionListener(StateTransitionListener listener) {
listeners.add(listener);
}
public void clearListeners() {
listeners.clear();
}
/**
* Notifies all registered listeners of the transition to this state.
*/
public void notifyOnEntry() {
for (StateTransitionListener listener : listeners) {
listener.transitionTo(this);
ScanningState next() {
switch (this) {
case IDLE: return STARTING;
case STARTING: return SCANNING;
case SCANNING: return STOPPING;
case STOPPING: return KILLING;
case RESTARTING: return SCANNING;
default: return null;
}
}
}

View File

@ -3,25 +3,23 @@
* see http://www.azib.net/ for more information.
* Licensed under GPLv2.
*/
package net.azib.ipscan.core.state;
import java.util.logging.Logger;
import net.azib.ipscan.config.LoggerFactory;
import java.util.ArrayList;
import java.util.List;
/**
* StateMachine
* StateMachine implementation.
* It holds the current state and performs transitions with corresponding methods.
*
* @author Anton Keks
*/
public class StateMachine {
private static final Logger LOG = LoggerFactory.getLogger();
private ScanningState state = ScanningState.IDLE;
private List<StateTransitionListener> transitionListeners = new ArrayList<StateTransitionListener>();
/**
* @param state
* @return true if current state is as specified
@ -37,14 +35,25 @@ public class StateMachine {
return state;
}
/**
* Registers state transition listener.
* @param listener instance
*/
public void addTransitionListener(StateTransitionListener listener) {
transitionListeners.add(listener);
}
/**
* Transitions to the specified state, notifying all listeners.
* Note: this method is intentionally not public, use specific methods to make desired transitions.
* @param newState
*/
public void transitionTo(ScanningState newState) {
void transitionTo(ScanningState newState) {
if (state != newState) {
state = newState;
state.notifyOnEntry();
for (StateTransitionListener listener : transitionListeners) {
listener.transitionTo(state);
}
}
}
@ -67,7 +76,7 @@ public class StateMachine {
transitionTo(ScanningState.STOPPING);
}
else {
LOG.warning("Attempt to stop from " + state);
throw new IllegalStateException("Attempt to stop from " + state);
}
}
@ -79,7 +88,31 @@ public class StateMachine {
transitionTo(ScanningState.IDLE);
}
else {
LOG.warning("Attempt to complete from " + state);
throw new IllegalStateException("Attempt to complete from " + state);
}
}
/**
* Transitions to the RESTARTING state in order to rescan previously scanned results.
*/
public void rescan() {
if (state == ScanningState.IDLE) {
transitionTo(ScanningState.RESTARTING);
}
else {
throw new IllegalStateException("Attempt to rescan from " + state);
}
}
/**
* Starts the scanning process
*/
public void startScanning() {
if (state == ScanningState.STARTING || state == ScanningState.RESTARTING) {
transitionTo(ScanningState.SCANNING);
}
else {
throw new IllegalStateException("Attempt to go scanning from " + state);
}
}

View File

@ -31,7 +31,7 @@ public interface Feeder {
* @param params the meaning and the number of these Strings depend on the implementation.
* @return the number of consumed parameters
*/
public int initialize(String[] params);
public int initialize(String ... params);
/**
* @return true in case there are more IPs left for processing
@ -46,7 +46,7 @@ public interface Feeder {
/**
* @return value from 0 to 100, describing the amount of work already done
*/
public int getPercentageComplete();
public int percentageComplete();
/**
* @return information about feeder's current settings.

View File

@ -56,7 +56,7 @@ public class FileFeeder implements Feeder {
* @param params 1 parameter:
* params[0] fileName
*/
public int initialize(String[] params) {
public int initialize(String ... params) {
initialize(params[0]);
return 1;
}
@ -104,7 +104,7 @@ public class FileFeeder implements Feeder {
foundIPAddressesIterator = foundIPAddresses.iterator();
}
public int getPercentageComplete() {
public int percentageComplete() {
return Math.round((float)currentIndex * 100 / totalAddresses);
}

View File

@ -43,7 +43,7 @@ public class RandomFeeder implements Feeder {
* params[1] mask
* params[2] count
*/
public int initialize(String[] params) {
public int initialize(String ... params) {
try {
initialize(params[0], params[1], Integer.parseInt(params[2]));
return 3;
@ -77,7 +77,7 @@ public class RandomFeeder implements Feeder {
this.currentBytes = new byte[prototypeBytes.length];
}
public int getPercentageComplete() {
public int percentageComplete() {
return Math.round((float)currentNumber * 100 / addressCount);
}

View File

@ -43,7 +43,7 @@ public class RangeFeeder implements Feeder {
* params[0] - startIP
* params[1] - endIP
*/
public int initialize(String[] params) {
public int initialize(String ... params) {
initialize(params[0], params[1]);
return 2;
}
@ -96,7 +96,7 @@ public class RangeFeeder implements Feeder {
return prevIP;
}
public int getPercentageComplete() {
public int percentageComplete() {
return (int)Math.round(percentageComplete);
}

View File

@ -0,0 +1,78 @@
/**
* This file is a part of Angry IP Scanner source code,
* see http://www.azib.net/ for more information.
* Licensed under GPLv2.
*/
package net.azib.ipscan.feeders;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.List;
/**
* A Feeder for rescanning - takes a predefined list of IP addresses.
*
* @author anton
*/
public class RescanFeeder implements Feeder {
private List<InetAddress> addresses;
int current;
/**
* @see Feeder#getLabel()
*/
public String getLabel() {
// this feeder is not a regular one
return null;
}
/**
* Initializes the RescanFeeder with required parameters
* @see Feeder#initialize(String[])
* @param params an array of IP addresses as Strings
*/
public int initialize(String ... params) {
if (params.length == 0)
throw new IllegalArgumentException("no IP addresses specified");
try {
addresses = new ArrayList<InetAddress>(params.length);
for (String s : params) {
addresses.add(InetAddress.getByName(s));
}
}
catch (UnknownHostException e) {
throw new FeederException("malformedIP");
}
return params.length;
}
/**
* @see net.azib.ipscan.feeders.Feeder#hasNext()
*/
public boolean hasNext() {
return current < addresses.size();
}
/**
* @see net.azib.ipscan.feeders.Feeder#next()
*/
public InetAddress next() {
return addresses.get(current++);
}
public int percentageComplete() {
return current * 100 / addresses.size();
}
/**
* @see net.azib.ipscan.feeders.Feeder#getInfo()
*/
public String getInfo() {
// this is a non-standard feeder
return null;
}
}

View File

@ -25,7 +25,7 @@ public class SmartTextFeeder implements Feeder {
return null;
}
public int initialize(String[] params) {
public int initialize(String ... params) {
return 0;
}
@ -52,7 +52,7 @@ public class SmartTextFeeder implements Feeder {
return null;
}
public int getPercentageComplete() {
public int percentageComplete() {
return 0;
}

View File

@ -109,7 +109,7 @@ public class MainMenu {
private void createCommandsMenuItems(Menu menu) {
initMenuItem(menu, "menu.commands.details", null, null, initListener(CommandsActions.Details.class));
initMenuItem(menu, null, null, null, null);
initMenuItem(menu, "menu.commands.rescan", "Ctrl+R", new Integer(SWT.MOD1 | 'R'), null);
initMenuItem(menu, "menu.commands.rescan", "Ctrl+R", new Integer(SWT.MOD1 | 'R'), initListener(CommandsActions.Rescan.class));
initMenuItem(menu, "menu.commands.delete", "Del", null, initListener(CommandsActions.Delete.class));
initMenuItem(menu, null, null, null, null);
initMenuItem(menu, "menu.commands.copy", "Ctrl+C", new Integer(SWT.MOD1 | 'C'), initListener(CommandsActions.CopyIP.class));

View File

@ -116,7 +116,7 @@ public class ResultTable extends Table implements FetcherRegistryUpdateListener
final int index = scanningResults.add(address);
getDisplay().syncExec(new Runnable() {
public void run() {
ResultTable.this.setItemCount(index+1);
setItemCount(index+1);
}
});
return index;
@ -165,6 +165,16 @@ public class ResultTable extends Table implements FetcherRegistryUpdateListener
scanningResults.clear();
super.removeAll();
}
public void resetSelection() {
int columnCount = getColumnCount();
for (TableItem item : getSelection()) {
for (int i = 1; i < columnCount; i++) {
item.setText(i, "");
}
item.setImage(this.listImages[ScanningSubject.RESULT_TYPE_UNKNOWN]);
}
}
/**
* Initializes a new scan.
@ -185,6 +195,16 @@ public class ResultTable extends Table implements FetcherRegistryUpdateListener
return scanningResults;
}
/**
* @return the feeder info, which used in this scan
*/
public String getFeederInfo() {
return feederInfo;
}
/**
* This listener is used for displaying the real results in the table, on demand.
*/
class SetDataListener implements Listener {
public void handleEvent(Event event) {
@ -205,11 +225,4 @@ public class ResultTable extends Table implements FetcherRegistryUpdateListener
}
/**
* @return the feeder info, which used in this scan
*/
public String getFeederInfo() {
return feederInfo;
}
}

View File

@ -22,14 +22,14 @@ public class ScanningResultsConsumer implements ScanningResultsCallback {
this.resultTable = resultTable;
}
/**
/*
* @see net.azib.ipscan.core.ScanningResultsCallback#prepareForResults(InetAddress)
*/
public int prepareForResults(InetAddress address) {
return resultTable.addResultsRow(address);
}
/**
/*
* @see net.azib.ipscan.core.ScanningResultsCallback#consumeResults(int, ScanningResult)
*/
public void consumeResults(int preparationIndex, ScanningResult results) {

View File

@ -10,6 +10,7 @@ import java.util.Iterator;
import net.azib.ipscan.config.Config;
import net.azib.ipscan.config.Labels;
import net.azib.ipscan.config.OpenersConfig.Opener;
import net.azib.ipscan.core.state.StateMachine;
import net.azib.ipscan.fetchers.FetcherRegistry;
import net.azib.ipscan.gui.DetailsDialog;
import net.azib.ipscan.gui.EditOpenersDialog;
@ -56,7 +57,8 @@ public class CommandsActions {
}
public void handleEvent(Event event) {
// ignore other keys if this is a KeyDown event
// ignore other keys if this is a KeyDown event -
// the same listener is used for several events
if (event.type == SWT.KeyDown && event.keyCode != SWT.DEL)
return;
checkSelection(resultTable);
@ -66,6 +68,21 @@ public class CommandsActions {
}
}
public static class Rescan implements Listener {
private ResultTable resultTable;
private StateMachine stateMachine;
public Rescan(ResultTable resultTable, StateMachine stateMachine) {
this.resultTable = resultTable;
this.stateMachine = stateMachine;
}
public void handleEvent(Event event) {
checkSelection(resultTable);
stateMachine.rescan();
}
}
public static class CopyIP implements Listener {
private ResultTable resultTable;

View File

@ -35,19 +35,44 @@ public class StartStopScanningAction implements SelectionListener, ScanningProgr
private ScannerThreadFactory scannerThreadFactory;
private ScannerThread scannerThread;
ScanningResultsConsumer resultsConsumer;
private StatusBar statusBar;
private ResultTable resultTable;
private FeederGUIRegistry feederRegistry;
private Button button;
private Image[] buttonImages = new Image[ScanningState.values().length];
private String[] buttonTexts = new String[ScanningState.values().length];
Image[] buttonImages = new Image[ScanningState.values().length];
String[] buttonTexts = new String[ScanningState.values().length];
private Display display;
private StateMachine stateMachine;
/**
* Creates internal stuff independent from all other external dependencies
*/
StartStopScanningAction() {
// pre-load button images
buttonImages[ScanningState.IDLE.ordinal()] = new Image(null, Labels.getInstance().getImageAsStream("button.start.img"));
buttonImages[ScanningState.SCANNING.ordinal()] = new Image(null, Labels.getInstance().getImageAsStream("button.stop.img"));
buttonImages[ScanningState.STARTING.ordinal()] = buttonImages[ScanningState.SCANNING.ordinal()];
buttonImages[ScanningState.RESTARTING.ordinal()] = buttonImages[ScanningState.SCANNING.ordinal()];
buttonImages[ScanningState.STOPPING.ordinal()] = new Image(null, Labels.getInstance().getImageAsStream("button.kill.img"));
buttonImages[ScanningState.KILLING.ordinal()] = buttonImages[ScanningState.STOPPING.ordinal()];
// pre-load button texts
buttonTexts[ScanningState.IDLE.ordinal()] = Labels.getLabel("button.start");
buttonTexts[ScanningState.SCANNING.ordinal()] = Labels.getLabel("button.stop");
buttonTexts[ScanningState.STARTING.ordinal()] = buttonTexts[ScanningState.SCANNING.ordinal()];
buttonTexts[ScanningState.RESTARTING.ordinal()] = buttonTexts[ScanningState.SCANNING.ordinal()];
buttonTexts[ScanningState.STOPPING.ordinal()] = Labels.getLabel("button.kill");
buttonTexts[ScanningState.KILLING.ordinal()] = Labels.getLabel("button.kill");
}
public StartStopScanningAction(ScannerThreadFactory scannerThreadFactory, StateMachine stateMachine, ResultTable resultTable, StatusBar statusBar, FeederGUIRegistry feederRegistry, Button startStopButton) {
this();
this.scannerThreadFactory = scannerThreadFactory;
this.resultTable = resultTable;
this.statusBar = statusBar;
@ -55,23 +80,10 @@ public class StartStopScanningAction implements SelectionListener, ScanningProgr
this.button = startStopButton;
this.display = button.getDisplay();
this.stateMachine = stateMachine;
this.resultsConsumer = new ScanningResultsConsumer(resultTable);
// pre-load button images
buttonImages[ScanningState.IDLE.ordinal()] = new Image(null, Labels.getInstance().getImageAsStream("button.start.img"));
buttonImages[ScanningState.SCANNING.ordinal()] = new Image(null, Labels.getInstance().getImageAsStream("button.stop.img"));
buttonImages[ScanningState.STOPPING.ordinal()] = new Image(null, Labels.getInstance().getImageAsStream("button.kill.img"));
buttonImages[ScanningState.KILLING.ordinal()] = buttonImages[ScanningState.STOPPING.ordinal()];
// pre-load button texts
buttonTexts[ScanningState.IDLE.ordinal()] = Labels.getLabel("button.start");
buttonTexts[ScanningState.SCANNING.ordinal()] = Labels.getLabel("button.stop");
buttonTexts[ScanningState.STOPPING.ordinal()] = Labels.getLabel("button.kill");
buttonTexts[ScanningState.KILLING.ordinal()] = Labels.getLabel("button.kill");
// add listeners to all state changes
for (ScanningState state : ScanningState.values()) {
state.addTransitionListener(this);
}
stateMachine.addTransitionListener(this);
// set the defaultimage
ScanningState state = stateMachine.getState();
@ -79,10 +91,16 @@ public class StartStopScanningAction implements SelectionListener, ScanningProgr
button.setText(buttonTexts[state.ordinal()]);
}
/**
* Called when scanning button is clicked
*/
public void widgetDefaultSelected(SelectionEvent e) {
widgetSelected(e);
}
/**
* Called when scanning button is clicked
*/
public void widgetSelected(SelectionEvent e) {
stateMachine.transitionToNext();
}
@ -101,13 +119,19 @@ public class StartStopScanningAction implements SelectionListener, ScanningProgr
statusBar.setStatusText(null);
statusBar.setProgress(0);
break;
case SCANNING:
case STARTING:
// start the scan!
resultTable.initNewScan(feederRegistry.current().getInfo());
ScanningResultsConsumer resultsConsumer = new ScanningResultsConsumer(resultTable);
scannerThread = scannerThreadFactory.createScannerThread(feederRegistry.current().getFeeder(), StartStopScanningAction.this);
// TODO: fix this: this is needed here to avoid cylic dependencies...
scannerThread.setResultsCallback(resultsConsumer);
scannerThread = scannerThreadFactory.createScannerThread(feederRegistry.current().getFeeder(), StartStopScanningAction.this, resultsConsumer);
stateMachine.startScanning();
break;
case RESTARTING:
// restart the scanning - rescan
resultTable.resetSelection();
scannerThread = scannerThreadFactory.createScannerThread(feederRegistry.createRescanFeeder(resultTable.getSelection()), StartStopScanningAction.this, resultsConsumer);
stateMachine.startScanning();
break;
case SCANNING:
scannerThread.start();
break;
case STOPPING:

View File

@ -11,9 +11,12 @@ import java.util.List;
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.TableItem;
import net.azib.ipscan.config.Config;
import net.azib.ipscan.feeders.Feeder;
import net.azib.ipscan.feeders.FeederException;
import net.azib.ipscan.feeders.RescanFeeder;
/**
* FeederGUIRegistry
@ -72,4 +75,18 @@ public class FeederGUIRegistry implements Iterable<AbstractFeederGUI> {
// if not found
throw new FeederException("No such feeder found: " + feederName);
}
/**
* @param items selected table items to derive IP addresses from
* @return initialized instance of RescanFeeder
*/
public Feeder createRescanFeeder(TableItem[] items) {
Feeder feeder = new RescanFeeder();
String[] addresses = new String[items.length];
for (int i = 0; i < items.length; i++) {
addresses[i] = items[i].getText();
}
feeder.initialize(addresses);
return feeder;
}
}

View File

@ -0,0 +1,29 @@
/**
* This file is a part of Angry IP Scanner source code,
* see http://www.azib.net/ for more information.
* Licensed under GPLv2.
*/
package net.azib.ipscan.core.state;
import static org.junit.Assert.*;
import org.junit.Test;
/**
* ScanningStateTest
*
* @author Anton Keks
*/
public class ScanningStateTest {
@Test
public void testNext() throws Exception {
assertEquals(ScanningState.STARTING, ScanningState.IDLE.next());
assertEquals(ScanningState.SCANNING, ScanningState.STARTING.next());
assertEquals(ScanningState.SCANNING, ScanningState.RESTARTING.next());
assertEquals(ScanningState.STOPPING, ScanningState.SCANNING.next());
assertEquals(ScanningState.KILLING, ScanningState.STOPPING.next());
assertNull(ScanningState.KILLING.next());
}
}

View File

@ -33,34 +33,41 @@ public class StateMachineTest {
}
@Test
public void transitionTo() throws Exception {
final boolean[] called = {false};
ScanningState.IDLE.addTransitionListener(new StateTransitionListener() {
public void transitionToSameState() throws Exception {
stateMachine.addTransitionListener(new StateTransitionListener() {
public void transitionTo(ScanningState state) {
fail("no transition if changing to the same state");
}
});
ScanningState.STOPPING.addTransitionListener(new StateTransitionListener() {
assertEquals(ScanningState.IDLE, stateMachine.getState());
stateMachine.transitionTo(ScanningState.IDLE);
assertEquals(ScanningState.IDLE, stateMachine.getState());
}
@Test
public void transitionToAnotherState() throws Exception {
final ScanningState[] calledWithParameter = {null};
stateMachine.addTransitionListener(new StateTransitionListener() {
public void transitionTo(ScanningState state) {
called[0] = true;
calledWithParameter[0] = state;
}
});
assertEquals(ScanningState.IDLE, stateMachine.getState());
stateMachine.transitionTo(ScanningState.IDLE);
assertEquals(ScanningState.IDLE, stateMachine.getState());
stateMachine.transitionTo(ScanningState.STOPPING);
assertEquals(ScanningState.STOPPING, stateMachine.getState());
assertTrue(called[0]);
ScanningState.IDLE.clearListeners();
ScanningState.STOPPING.clearListeners();
assertEquals(ScanningState.STOPPING, calledWithParameter[0]);
stateMachine.transitionTo(ScanningState.STARTING);
assertEquals(ScanningState.STARTING, stateMachine.getState());
assertEquals(ScanningState.STARTING, calledWithParameter[0]);
}
@Test
public void transitionToNext() throws Exception {
assertEquals(ScanningState.IDLE, stateMachine.getState());
stateMachine.transitionToNext();
assertEquals(ScanningState.STARTING, stateMachine.getState());
stateMachine.transitionToNext();
assertEquals(ScanningState.SCANNING, stateMachine.getState());
stateMachine.transitionToNext();
assertEquals(ScanningState.STOPPING, stateMachine.getState());
@ -87,4 +94,22 @@ public class StateMachineTest {
stateMachine.complete();
assertEquals(ScanningState.IDLE, stateMachine.getState());
}
@Test
public void rescan() throws Exception {
stateMachine.transitionTo(ScanningState.IDLE);
stateMachine.rescan();
assertEquals(ScanningState.RESTARTING, stateMachine.getState());
}
@Test
public void startScanning() throws Exception {
stateMachine.transitionTo(ScanningState.STARTING);
stateMachine.startScanning();
assertEquals(ScanningState.SCANNING, stateMachine.getState());
stateMachine.transitionTo(ScanningState.RESTARTING);
stateMachine.startScanning();
assertEquals(ScanningState.SCANNING, stateMachine.getState());
}
}

View File

@ -89,19 +89,19 @@ public class FileFeederTest {
StringReader reader = new StringReader("1.2.3.4, 2.3.4.5, mega cool 0.0.0.0");
FileFeeder fileFeeder = new FileFeeder();
fileFeeder.initialize(reader);
assertEquals(0, fileFeeder.getPercentageComplete());
assertEquals(0, fileFeeder.percentageComplete());
fileFeeder.next();
assertEquals(33, fileFeeder.getPercentageComplete());
assertEquals(33, fileFeeder.percentageComplete());
fileFeeder.next();
assertEquals(67, fileFeeder.getPercentageComplete());
assertEquals(67, fileFeeder.percentageComplete());
fileFeeder.next();
assertEquals(100, fileFeeder.getPercentageComplete());
assertEquals(100, fileFeeder.percentageComplete());
reader = new StringReader("255.255.255.255");
fileFeeder.initialize(reader);
assertEquals(0, fileFeeder.getPercentageComplete());
assertEquals(0, fileFeeder.percentageComplete());
fileFeeder.next();
assertEquals(100, fileFeeder.getPercentageComplete());
assertEquals(100, fileFeeder.percentageComplete());
}
@Test

View File

@ -119,18 +119,18 @@ public class RandomFeederTest {
public void testGetPercentageComplete() throws Exception {
RandomFeeder randomFeeder = new RandomFeeder();
randomFeeder.initialize("100.11.12.13", "100.11.12.15", 3);
assertEquals(0, randomFeeder.getPercentageComplete());
assertEquals(0, randomFeeder.percentageComplete());
randomFeeder.next();
assertEquals(33, randomFeeder.getPercentageComplete());
assertEquals(33, randomFeeder.percentageComplete());
randomFeeder.next();
assertEquals(67, randomFeeder.getPercentageComplete());
assertEquals(67, randomFeeder.percentageComplete());
randomFeeder.next();
assertEquals(100, randomFeeder.getPercentageComplete());
assertEquals(100, randomFeeder.percentageComplete());
randomFeeder.initialize("255.255.255.255", "255.255.255.255", 1);
assertEquals(0, randomFeeder.getPercentageComplete());
assertEquals(0, randomFeeder.percentageComplete());
randomFeeder.next();
assertEquals(100, randomFeeder.getPercentageComplete());
assertEquals(100, randomFeeder.percentageComplete());
}
@Test

View File

@ -74,18 +74,18 @@ public class RangeFeederTest {
public void testGetPercentageComplete() throws Exception {
RangeFeeder rangeFeeder = new RangeFeeder();
rangeFeeder.initialize("100.11.12.13", "100.11.12.15");
assertEquals(0, rangeFeeder.getPercentageComplete());
assertEquals(0, rangeFeeder.percentageComplete());
rangeFeeder.next();
assertEquals(33, rangeFeeder.getPercentageComplete());
assertEquals(33, rangeFeeder.percentageComplete());
rangeFeeder.next();
assertEquals(67, rangeFeeder.getPercentageComplete());
assertEquals(67, rangeFeeder.percentageComplete());
rangeFeeder.next();
assertEquals(100, rangeFeeder.getPercentageComplete());
assertEquals(100, rangeFeeder.percentageComplete());
rangeFeeder.initialize("255.255.255.255", "255.255.255.255");
assertEquals(0, rangeFeeder.getPercentageComplete());
assertEquals(0, rangeFeeder.percentageComplete());
rangeFeeder.next();
assertEquals(100, rangeFeeder.getPercentageComplete());
assertEquals(100, rangeFeeder.percentageComplete());
}
@Test

View File

@ -0,0 +1,47 @@
/**
* This file is a part of Angry IP Scanner source code,
* see http://www.azib.net/ for more information.
* Licensed under GPLv2.
*/
package net.azib.ipscan.feeders;
import static org.junit.Assert.*;
import org.junit.Test;
/**
* RescanFeederTest
*
* @author Anton Keks
*/
public class RescanFeederTest {
private Feeder feeder = new RescanFeeder();
@Test(expected=IllegalArgumentException.class)
public void testEmpty() throws Exception {
feeder.initialize();
}
@Test
public void name() throws Exception {
assertEquals(3, feeder.initialize("127.0.0.15", "127.0.1.35", "127.0.2.2"));
assertTrue(feeder.hasNext());
assertEquals(0, feeder.percentageComplete());
assertEquals("127.0.0.15", feeder.next().getHostAddress());
assertTrue(feeder.hasNext());
assertEquals(33, feeder.percentageComplete());
assertEquals("127.0.1.35", feeder.next().getHostAddress());
assertTrue(feeder.hasNext());
assertEquals(66, feeder.percentageComplete());
assertEquals("127.0.2.2", feeder.next().getHostAddress());
assertFalse(feeder.hasNext());
assertEquals(100, feeder.percentageComplete());
}
}

View File

@ -0,0 +1,30 @@
/**
* This file is a part of Angry IP Scanner source code,
* see http://www.azib.net/ for more information.
* Licensed under GPLv2.
*/
package net.azib.ipscan.gui.actions;
import static org.junit.Assert.assertNotNull;
import net.azib.ipscan.core.state.ScanningState;
import org.junit.Test;
/**
* StartStopScanningActionTest
*
* @author Anton Keks
*/
public class StartStopScanningActionTest {
@Test
public void testAllImagesAreDefined() throws Exception {
StartStopScanningAction action = new StartStopScanningAction();
for (ScanningState state : ScanningState.values()) {
assertNotNull(action.buttonImages[state.ordinal()]);
assertNotNull(action.buttonTexts[state.ordinal()]);
}
}
}