Toggle navigation
Toggle navigation
This project
Loading...
Sign in
홍길동
/
onos
Go to a project
Toggle navigation
Toggle navigation pinning
Projects
Groups
Snippets
Help
Project
Activity
Repository
Pipelines
Graphs
Issues
0
Merge Requests
0
Wiki
Snippets
Network
Create a new issue
Builds
Commits
Issue Boards
Authored by
pankaj
2014-10-02 16:05:44 -0700
Browse Files
Options
Browse Files
Download
Plain Diff
Commit
185a0035bc4e5912ee310c22d41f04302e2567b5
185a0035
2 parents
8d0fa214
f3d0616b
Merge branch 'master' of
ssh://gerrit.onlab.us:29418/onos-next
Show whitespace changes
Inline
Side-by-side
Showing
23 changed files
with
1348 additions
and
0 deletions
core/api/src/main/java/org/onlab/onos/net/intent/BatchOperation.java
core/api/src/main/java/org/onlab/onos/net/intent/BatchOperationEntry.java
core/api/src/main/java/org/onlab/onos/net/intent/BatchOperationTarget.java
core/api/src/main/java/org/onlab/onos/net/intent/IdGenerator.java
core/api/src/test/java/org/onlab/onos/net/intent/ConnectivityIntentTest.java
core/api/src/test/java/org/onlab/onos/net/intent/FakeIntentManager.java
core/api/src/test/java/org/onlab/onos/net/intent/ImmutableClassChecker.java
core/api/src/test/java/org/onlab/onos/net/intent/IntentExceptionTest.java
core/api/src/test/java/org/onlab/onos/net/intent/IntentIdGenerator.java
core/api/src/test/java/org/onlab/onos/net/intent/IntentIdTest.java
core/api/src/test/java/org/onlab/onos/net/intent/IntentServiceTest.java
core/api/src/test/java/org/onlab/onos/net/intent/IntentTest.java
core/api/src/test/java/org/onlab/onos/net/intent/MultiPointToSinglePointIntentTest.java
core/api/src/test/java/org/onlab/onos/net/intent/PathIntentTest.java
core/api/src/test/java/org/onlab/onos/net/intent/PointToPointIntentTest.java
core/api/src/test/java/org/onlab/onos/net/intent/SinglePointToMultiPointIntentTest.java
core/api/src/test/java/org/onlab/onos/net/intent/TestInstallableIntent.java
core/api/src/test/java/org/onlab/onos/net/intent/TestIntent.java
core/api/src/test/java/org/onlab/onos/net/intent/TestSubclassInstallableIntent.java
core/api/src/test/java/org/onlab/onos/net/intent/TestSubclassIntent.java
core/api/src/test/java/org/onlab/onos/net/intent/TestTools.java
core/api/src/test/java/org/onlab/onos/net/intent/TestableIntentService.java
pom.xml
core/api/src/main/java/org/onlab/onos/net/intent/BatchOperation.java
View file @
185a003
package
org
.
onlab
.
onos
.
net
.
intent
;
//TODO is this the right package?
import
static
com
.
google
.
common
.
base
.
Preconditions
.
checkNotNull
;
...
...
core/api/src/main/java/org/onlab/onos/net/intent/BatchOperationEntry.java
View file @
185a003
package
org
.
onlab
.
onos
.
net
.
intent
;
//TODO is this the right package?
import
java.util.Objects
;
...
...
core/api/src/main/java/org/onlab/onos/net/intent/BatchOperationTarget.java
View file @
185a003
package
org
.
onlab
.
onos
.
net
.
intent
;
//TODO is this the right package?
/**
* An interface of the class which is assigned to BatchOperation.
...
...
core/api/src/main/java/org/onlab/onos/net/intent/IdGenerator.java
0 → 100644
View file @
185a003
package
org
.
onlab
.
onos
.
net
.
intent
;
//TODO is this the right package?
/**
* A generalized interface for ID generation
*
* {@link #getNewId()} generates a globally unique ID instance on
* each invocation.
*
* @param <T> the type of ID
*/
// TODO: do we need to define a base marker interface for ID,
// then changed the type parameter to <T extends BaseId> something
// like that?
public
interface
IdGenerator
<
T
>
{
/**
* Returns a globally unique ID instance.
*
* @return globally unique ID instance
*/
T
getNewId
();
}
core/api/src/test/java/org/onlab/onos/net/intent/ConnectivityIntentTest.java
0 → 100644
View file @
185a003
package
org
.
onlab
.
onos
.
net
.
intent
;
import
java.util.Set
;
import
org.onlab.onos.net.ConnectPoint
;
import
org.onlab.onos.net.DeviceId
;
import
org.onlab.onos.net.PortNumber
;
import
org.onlab.onos.net.flow.DefaultTrafficSelector
;
import
org.onlab.onos.net.flow.DefaultTrafficTreatment
;
import
org.onlab.onos.net.flow.TrafficSelector
;
import
org.onlab.onos.net.flow.TrafficTreatment
;
/**
* Base facilities to test various connectivity tests.
*/
public
abstract
class
ConnectivityIntentTest
extends
IntentTest
{
public
static
final
IntentId
IID
=
new
IntentId
(
123
);
public
static
final
TrafficSelector
MATCH
=
(
new
DefaultTrafficSelector
.
Builder
()).
build
();
public
static
final
TrafficTreatment
NOP
=
(
new
DefaultTrafficTreatment
.
Builder
()).
build
();
public
static
final
ConnectPoint
P1
=
new
ConnectPoint
(
DeviceId
.
deviceId
(
"111"
),
PortNumber
.
portNumber
(
0x1
));
public
static
final
ConnectPoint
P2
=
new
ConnectPoint
(
DeviceId
.
deviceId
(
"222"
),
PortNumber
.
portNumber
(
0x2
));
public
static
final
ConnectPoint
P3
=
new
ConnectPoint
(
DeviceId
.
deviceId
(
"333"
),
PortNumber
.
portNumber
(
0x3
));
public
static
final
Set
<
ConnectPoint
>
PS1
=
itemSet
(
new
ConnectPoint
[]{
P1
,
P3
});
public
static
final
Set
<
ConnectPoint
>
PS2
=
itemSet
(
new
ConnectPoint
[]{
P2
,
P3
});
}
core/api/src/test/java/org/onlab/onos/net/intent/FakeIntentManager.java
0 → 100644
View file @
185a003
package
org
.
onlab
.
onos
.
net
.
intent
;
import
java.util.ArrayList
;
import
java.util.Collections
;
import
java.util.HashMap
;
import
java.util.HashSet
;
import
java.util.List
;
import
java.util.Map
;
import
java.util.Set
;
import
java.util.concurrent.ExecutorService
;
import
java.util.concurrent.Executors
;
/**
* Fake implementation of the intent service to assist in developing tests
* of the interface contract.
*/
public
class
FakeIntentManager
implements
TestableIntentService
{
private
final
Map
<
IntentId
,
Intent
>
intents
=
new
HashMap
<>();
private
final
Map
<
IntentId
,
IntentState
>
intentStates
=
new
HashMap
<>();
private
final
Map
<
IntentId
,
List
<
InstallableIntent
>>
installables
=
new
HashMap
<>();
private
final
Set
<
IntentEventListener
>
listeners
=
new
HashSet
<>();
private
final
Map
<
Class
<?
extends
Intent
>,
IntentCompiler
<?
extends
Intent
>>
compilers
=
new
HashMap
<>();
private
final
Map
<
Class
<?
extends
InstallableIntent
>,
IntentInstaller
<?
extends
InstallableIntent
>>
installers
=
new
HashMap
<>();
private
final
ExecutorService
executor
=
Executors
.
newSingleThreadExecutor
();
private
final
List
<
IntentException
>
exceptions
=
new
ArrayList
<>();
@Override
public
List
<
IntentException
>
getExceptions
()
{
return
exceptions
;
}
// Provides an out-of-thread simulation of intent submit life-cycle
private
void
executeSubmit
(
final
Intent
intent
)
{
registerSubclassCompilerIfNeeded
(
intent
);
executor
.
execute
(
new
Runnable
()
{
@Override
public
void
run
()
{
try
{
List
<
InstallableIntent
>
installable
=
compileIntent
(
intent
);
installIntents
(
intent
,
installable
);
}
catch
(
IntentException
e
)
{
exceptions
.
add
(
e
);
}
}
});
}
// Provides an out-of-thread simulation of intent withdraw life-cycle
private
void
executeWithdraw
(
final
Intent
intent
)
{
executor
.
execute
(
new
Runnable
()
{
@Override
public
void
run
()
{
try
{
List
<
InstallableIntent
>
installable
=
getInstallable
(
intent
.
getId
());
uninstallIntents
(
intent
,
installable
);
}
catch
(
IntentException
e
)
{
exceptions
.
add
(
e
);
}
}
});
}
private
<
T
extends
Intent
>
IntentCompiler
<
T
>
getCompiler
(
T
intent
)
{
@SuppressWarnings
(
"unchecked"
)
IntentCompiler
<
T
>
compiler
=
(
IntentCompiler
<
T
>)
compilers
.
get
(
intent
.
getClass
());
if
(
compiler
==
null
)
{
throw
new
IntentException
(
"no compiler for class "
+
intent
.
getClass
());
}
return
compiler
;
}
private
<
T
extends
InstallableIntent
>
IntentInstaller
<
T
>
getInstaller
(
T
intent
)
{
@SuppressWarnings
(
"unchecked"
)
IntentInstaller
<
T
>
installer
=
(
IntentInstaller
<
T
>)
installers
.
get
(
intent
.
getClass
());
if
(
installer
==
null
)
{
throw
new
IntentException
(
"no installer for class "
+
intent
.
getClass
());
}
return
installer
;
}
private
<
T
extends
Intent
>
List
<
InstallableIntent
>
compileIntent
(
T
intent
)
{
try
{
// For the fake, we compile using a single level pass
List
<
InstallableIntent
>
installable
=
new
ArrayList
<>();
for
(
Intent
compiled
:
getCompiler
(
intent
).
compile
(
intent
))
{
installable
.
add
((
InstallableIntent
)
compiled
);
}
setState
(
intent
,
IntentState
.
COMPILED
);
return
installable
;
}
catch
(
IntentException
e
)
{
setState
(
intent
,
IntentState
.
FAILED
);
throw
e
;
}
}
private
void
installIntents
(
Intent
intent
,
List
<
InstallableIntent
>
installable
)
{
try
{
for
(
InstallableIntent
ii
:
installable
)
{
registerSubclassInstallerIfNeeded
(
ii
);
getInstaller
(
ii
).
install
(
ii
);
}
setState
(
intent
,
IntentState
.
INSTALLED
);
putInstallable
(
intent
.
getId
(),
installable
);
}
catch
(
IntentException
e
)
{
setState
(
intent
,
IntentState
.
FAILED
);
throw
e
;
}
}
private
void
uninstallIntents
(
Intent
intent
,
List
<
InstallableIntent
>
installable
)
{
try
{
for
(
InstallableIntent
ii
:
installable
)
{
getInstaller
(
ii
).
uninstall
(
ii
);
}
setState
(
intent
,
IntentState
.
WITHDRAWN
);
removeInstallable
(
intent
.
getId
());
}
catch
(
IntentException
e
)
{
setState
(
intent
,
IntentState
.
FAILED
);
throw
e
;
}
}
// Sets the internal state for the given intent and dispatches an event
private
void
setState
(
Intent
intent
,
IntentState
state
)
{
IntentState
previous
=
intentStates
.
get
(
intent
.
getId
());
intentStates
.
put
(
intent
.
getId
(),
state
);
dispatch
(
new
IntentEvent
(
intent
,
state
,
previous
,
System
.
currentTimeMillis
()));
}
private
void
putInstallable
(
IntentId
id
,
List
<
InstallableIntent
>
installable
)
{
installables
.
put
(
id
,
installable
);
}
private
void
removeInstallable
(
IntentId
id
)
{
installables
.
remove
(
id
);
}
private
List
<
InstallableIntent
>
getInstallable
(
IntentId
id
)
{
List
<
InstallableIntent
>
installable
=
installables
.
get
(
id
);
if
(
installable
!=
null
)
{
return
installable
;
}
else
{
return
Collections
.
emptyList
();
}
}
@Override
public
void
submit
(
Intent
intent
)
{
intents
.
put
(
intent
.
getId
(),
intent
);
setState
(
intent
,
IntentState
.
SUBMITTED
);
executeSubmit
(
intent
);
}
@Override
public
void
withdraw
(
Intent
intent
)
{
intents
.
remove
(
intent
.
getId
());
setState
(
intent
,
IntentState
.
WITHDRAWING
);
executeWithdraw
(
intent
);
}
@Override
public
void
execute
(
IntentOperations
operations
)
{
// TODO: implement later
}
@Override
public
Set
<
Intent
>
getIntents
()
{
return
Collections
.
unmodifiableSet
(
new
HashSet
<>(
intents
.
values
()));
}
@Override
public
Intent
getIntent
(
IntentId
id
)
{
return
intents
.
get
(
id
);
}
@Override
public
IntentState
getIntentState
(
IntentId
id
)
{
return
intentStates
.
get
(
id
);
}
@Override
public
void
addListener
(
IntentEventListener
listener
)
{
listeners
.
add
(
listener
);
}
@Override
public
void
removeListener
(
IntentEventListener
listener
)
{
listeners
.
remove
(
listener
);
}
private
void
dispatch
(
IntentEvent
event
)
{
for
(
IntentEventListener
listener
:
listeners
)
{
listener
.
event
(
event
);
}
}
@Override
public
<
T
extends
Intent
>
void
registerCompiler
(
Class
<
T
>
cls
,
IntentCompiler
<
T
>
compiler
)
{
compilers
.
put
(
cls
,
compiler
);
}
@Override
public
<
T
extends
Intent
>
void
unregisterCompiler
(
Class
<
T
>
cls
)
{
compilers
.
remove
(
cls
);
}
@Override
public
Map
<
Class
<?
extends
Intent
>,
IntentCompiler
<?
extends
Intent
>>
getCompilers
()
{
return
Collections
.
unmodifiableMap
(
compilers
);
}
@Override
public
<
T
extends
InstallableIntent
>
void
registerInstaller
(
Class
<
T
>
cls
,
IntentInstaller
<
T
>
installer
)
{
installers
.
put
(
cls
,
installer
);
}
@Override
public
<
T
extends
InstallableIntent
>
void
unregisterInstaller
(
Class
<
T
>
cls
)
{
installers
.
remove
(
cls
);
}
@Override
public
Map
<
Class
<?
extends
InstallableIntent
>,
IntentInstaller
<?
extends
InstallableIntent
>>
getInstallers
()
{
return
Collections
.
unmodifiableMap
(
installers
);
}
private
void
registerSubclassCompilerIfNeeded
(
Intent
intent
)
{
if
(!
compilers
.
containsKey
(
intent
.
getClass
()))
{
Class
<?>
cls
=
intent
.
getClass
();
while
(
cls
!=
Object
.
class
)
{
// As long as we're within the Intent class descendants
if
(
Intent
.
class
.
isAssignableFrom
(
cls
))
{
IntentCompiler
<?>
compiler
=
compilers
.
get
(
cls
);
if
(
compiler
!=
null
)
{
compilers
.
put
(
intent
.
getClass
(),
compiler
);
return
;
}
}
cls
=
cls
.
getSuperclass
();
}
}
}
private
void
registerSubclassInstallerIfNeeded
(
InstallableIntent
intent
)
{
if
(!
installers
.
containsKey
(
intent
.
getClass
()))
{
Class
<?>
cls
=
intent
.
getClass
();
while
(
cls
!=
Object
.
class
)
{
// As long as we're within the InstallableIntent class descendants
if
(
InstallableIntent
.
class
.
isAssignableFrom
(
cls
))
{
IntentInstaller
<?>
installer
=
installers
.
get
(
cls
);
if
(
installer
!=
null
)
{
installers
.
put
(
intent
.
getClass
(),
installer
);
return
;
}
}
cls
=
cls
.
getSuperclass
();
}
}
}
}
core/api/src/test/java/org/onlab/onos/net/intent/ImmutableClassChecker.java
0 → 100644
View file @
185a003
package
org
.
onlab
.
onos
.
net
.
intent
;
//TODO is this the right package?
import
org.hamcrest.Description
;
import
org.hamcrest.StringDescription
;
import
java.lang.reflect.Field
;
import
java.lang.reflect.Method
;
import
java.lang.reflect.Modifier
;
/**
* Hamcrest style class for verifying that a class follows the
* accepted rules for immutable classes.
*
* The rules that are enforced for immutable classes:
* - the class must be declared final
* - all data members of the class must be declared private and final
* - the class must not define any setter methods
*/
public
class
ImmutableClassChecker
{
private
String
failureReason
=
""
;
/**
* Method to determine if a given class is a properly specified
* immutable class.
*
* @param clazz the class to check
* @return true if the given class is a properly specified immutable class.
*/
private
boolean
isImmutableClass
(
Class
<?>
clazz
)
{
// class must be declared final
if
(!
Modifier
.
isFinal
(
clazz
.
getModifiers
()))
{
failureReason
=
"a class that is not final"
;
return
false
;
}
// class must have only final and private data members
for
(
final
Field
field
:
clazz
.
getDeclaredFields
())
{
if
(
field
.
getName
().
startsWith
(
"__cobertura"
))
{
// cobertura sticks these fields into classes - ignore them
continue
;
}
if
(!
Modifier
.
isFinal
(
field
.
getModifiers
()))
{
failureReason
=
"a field named '"
+
field
.
getName
()
+
"' that is not final"
;
return
false
;
}
if
(!
Modifier
.
isPrivate
(
field
.
getModifiers
()))
{
//
// NOTE: We relax the recommended rules for defining immutable
// objects and allow "static final" fields that are not
// private. The "final" check was already done above so we
// don't repeat it here.
//
if
(!
Modifier
.
isStatic
(
field
.
getModifiers
()))
{
failureReason
=
"a field named '"
+
field
.
getName
()
+
"' that is not private and is not static"
;
return
false
;
}
}
}
// class must not define any setters
for
(
final
Method
method
:
clazz
.
getMethods
())
{
if
(
method
.
getDeclaringClass
().
equals
(
clazz
))
{
if
(
method
.
getName
().
startsWith
(
"set"
))
{
failureReason
=
"a class with a setter named '"
+
method
.
getName
()
+
"'"
;
return
false
;
}
}
}
return
true
;
}
/**
* Describe why an error was reported. Uses Hamcrest style Description
* interfaces.
*
* @param description the Description object to use for reporting the
* mismatch
*/
public
void
describeMismatch
(
Description
description
)
{
description
.
appendText
(
failureReason
);
}
/**
* Describe the source object that caused an error, using a Hamcrest
* Matcher style interface. In this case, it always returns
* that we are looking for a properly defined utility class.
*
* @param description the Description object to use to report the "to"
* object
*/
public
void
describeTo
(
Description
description
)
{
description
.
appendText
(
"a properly defined immutable class"
);
}
/**
* Assert that the given class adheres to the utility class rules.
*
* @param clazz the class to check
*
* @throws java.lang.AssertionError if the class is not a valid
* utility class
*/
public
static
void
assertThatClassIsImmutable
(
Class
<?>
clazz
)
{
final
ImmutableClassChecker
checker
=
new
ImmutableClassChecker
();
if
(!
checker
.
isImmutableClass
(
clazz
))
{
final
Description
toDescription
=
new
StringDescription
();
final
Description
mismatchDescription
=
new
StringDescription
();
checker
.
describeTo
(
toDescription
);
checker
.
describeMismatch
(
mismatchDescription
);
final
String
reason
=
"\n"
+
"Expected: is \""
+
toDescription
.
toString
()
+
"\"\n"
+
" but : was \""
+
mismatchDescription
.
toString
()
+
"\""
;
throw
new
AssertionError
(
reason
);
}
}
}
core/api/src/test/java/org/onlab/onos/net/intent/IntentExceptionTest.java
0 → 100644
View file @
185a003
package
org
.
onlab
.
onos
.
net
.
intent
;
import
org.junit.Test
;
import
static
org
.
junit
.
Assert
.
assertEquals
;
/**
* Test of the intent exception.
*/
public
class
IntentExceptionTest
{
@Test
public
void
basics
()
{
validate
(
new
IntentException
(),
null
,
null
);
validate
(
new
IntentException
(
"foo"
),
"foo"
,
null
);
Throwable
cause
=
new
NullPointerException
(
"bar"
);
validate
(
new
IntentException
(
"foo"
,
cause
),
"foo"
,
cause
);
}
/**
* Validates that the specified exception has the correct message and cause.
*
* @param e exception to test
* @param message expected message
* @param cause expected cause
*/
protected
void
validate
(
RuntimeException
e
,
String
message
,
Throwable
cause
)
{
assertEquals
(
"incorrect message"
,
message
,
e
.
getMessage
());
assertEquals
(
"incorrect cause"
,
cause
,
e
.
getCause
());
}
}
core/api/src/test/java/org/onlab/onos/net/intent/IntentIdGenerator.java
0 → 100644
View file @
185a003
package
org
.
onlab
.
onos
.
net
.
intent
;
/**
* This interface is for generator of IntentId. It is defined only for
* testing purpose to keep type safety on mock creation.
*
* <p>
* {@link #getNewId()} generates a globally unique {@link IntentId} instance
* on each invocation. Application developers should not generate IntentId
* by themselves. Instead use an implementation of this interface.
* </p>
*/
public
interface
IntentIdGenerator
extends
IdGenerator
<
IntentId
>
{
}
core/api/src/test/java/org/onlab/onos/net/intent/IntentIdTest.java
0 → 100644
View file @
185a003
package
org
.
onlab
.
onos
.
net
.
intent
;
import
org.junit.Test
;
import
static
org
.
hamcrest
.
Matchers
.
is
;
import
static
org
.
hamcrest
.
Matchers
.
not
;
import
static
org
.
junit
.
Assert
.
assertEquals
;
import
static
org
.
junit
.
Assert
.
assertThat
;
/**
* This class tests the immutability, equality, and non-equality of
* {@link IntentId}.
*/
public
class
IntentIdTest
{
/**
* Tests the immutability of {@link IntentId}.
*/
@Test
public
void
intentIdFollowsGuidelineForImmutableObject
()
{
ImmutableClassChecker
.
assertThatClassIsImmutable
(
IntentId
.
class
);
}
/**
* Tests equality of {@link IntentId}.
*/
@Test
public
void
testEquality
()
{
IntentId
id1
=
new
IntentId
(
1L
);
IntentId
id2
=
new
IntentId
(
1L
);
assertThat
(
id1
,
is
(
id2
));
}
/**
* Tests non-equality of {@link IntentId}.
*/
@Test
public
void
testNonEquality
()
{
IntentId
id1
=
new
IntentId
(
1L
);
IntentId
id2
=
new
IntentId
(
2L
);
assertThat
(
id1
,
is
(
not
(
id2
)));
}
@Test
public
void
valueOf
()
{
IntentId
id
=
new
IntentId
(
12345
);
assertEquals
(
"incorrect valueOf"
,
id
,
IntentId
.
valueOf
(
"12345"
));
}
@Test
public
void
valueOfHex
()
{
IntentId
id
=
new
IntentId
(
0xdeadbeef
L
);
assertEquals
(
"incorrect valueOf"
,
id
,
IntentId
.
valueOf
(
id
.
toString
()));
}
}
core/api/src/test/java/org/onlab/onos/net/intent/IntentServiceTest.java
0 → 100644
View file @
185a003
package
org
.
onlab
.
onos
.
net
.
intent
;
import
org.junit.After
;
import
org.junit.Before
;
import
org.junit.Test
;
import
java.util.ArrayList
;
import
java.util.Arrays
;
import
java.util.Collections
;
import
java.util.Iterator
;
import
java.util.List
;
import
static
org
.
onlab
.
onos
.
net
.
intent
.
IntentState
.*;
import
static
org
.
junit
.
Assert
.*;
// TODO: consider make it categorized as integration test when it become
// slow test or fragile test
/**
* Suite of tests for the intent service contract.
*/
public
class
IntentServiceTest
{
public
static
final
IntentId
IID
=
new
IntentId
(
123
);
public
static
final
IntentId
INSTALLABLE_IID
=
new
IntentId
(
234
);
protected
static
final
int
GRACE_MS
=
500
;
// millis
protected
TestableIntentService
service
;
protected
TestListener
listener
=
new
TestListener
();
@Before
public
void
setUp
()
{
service
=
createIntentService
();
service
.
addListener
(
listener
);
}
@After
public
void
tearDown
()
{
service
.
removeListener
(
listener
);
}
/**
* Creates a service instance appropriately instrumented for testing.
*
* @return testable intent service
*/
protected
TestableIntentService
createIntentService
()
{
return
new
FakeIntentManager
();
}
@Test
public
void
basics
()
{
// Make sure there are no intents
assertEquals
(
"incorrect intent count"
,
0
,
service
.
getIntents
().
size
());
// Register a compiler and an installer both setup for success.
service
.
registerCompiler
(
TestIntent
.
class
,
new
TestCompiler
(
new
TestInstallableIntent
(
INSTALLABLE_IID
)));
service
.
registerInstaller
(
TestInstallableIntent
.
class
,
new
TestInstaller
(
false
));
final
Intent
intent
=
new
TestIntent
(
IID
);
service
.
submit
(
intent
);
// Allow a small window of time until the intent is in the expected state
TestTools
.
assertAfter
(
GRACE_MS
,
new
Runnable
()
{
@Override
public
void
run
()
{
assertEquals
(
"incorrect intent state"
,
INSTALLED
,
service
.
getIntentState
(
intent
.
getId
()));
}
});
// Make sure that all expected events have been emitted
validateEvents
(
intent
,
SUBMITTED
,
COMPILED
,
INSTALLED
);
// Make sure there is just one intent (and is ours)
assertEquals
(
"incorrect intent count"
,
1
,
service
.
getIntents
().
size
());
assertEquals
(
"incorrect intent"
,
intent
,
service
.
getIntent
(
intent
.
getId
()));
// Reset the listener events
listener
.
events
.
clear
();
// Now withdraw the intent
service
.
withdraw
(
intent
);
// Allow a small window of time until the event is in the expected state
TestTools
.
assertAfter
(
GRACE_MS
,
new
Runnable
()
{
@Override
public
void
run
()
{
assertEquals
(
"incorrect intent state"
,
WITHDRAWN
,
service
.
getIntentState
(
intent
.
getId
()));
}
});
// Make sure that all expected events have been emitted
validateEvents
(
intent
,
WITHDRAWING
,
WITHDRAWN
);
// TODO: discuss what is the fate of intents after they have been withdrawn
// Make sure that the intent is no longer in the system
// assertEquals("incorrect intent count", 0, service.getIntents().size());
// assertNull("intent should not be found", service.getIntent(intent.getId()));
// assertNull("intent state should not be found", service.getIntentState(intent.getId()));
}
@Test
public
void
failedCompilation
()
{
// Register a compiler programmed for success
service
.
registerCompiler
(
TestIntent
.
class
,
new
TestCompiler
(
true
));
// Submit an intent
final
Intent
intent
=
new
TestIntent
(
IID
);
service
.
submit
(
intent
);
// Allow a small window of time until the intent is in the expected state
TestTools
.
assertAfter
(
GRACE_MS
,
new
Runnable
()
{
@Override
public
void
run
()
{
assertEquals
(
"incorrect intent state"
,
FAILED
,
service
.
getIntentState
(
intent
.
getId
()));
}
});
// Make sure that all expected events have been emitted
validateEvents
(
intent
,
SUBMITTED
,
FAILED
);
}
@Test
public
void
failedInstallation
()
{
// Register a compiler programmed for success and installer for failure
service
.
registerCompiler
(
TestIntent
.
class
,
new
TestCompiler
(
new
TestInstallableIntent
(
INSTALLABLE_IID
)));
service
.
registerInstaller
(
TestInstallableIntent
.
class
,
new
TestInstaller
(
true
));
// Submit an intent
final
Intent
intent
=
new
TestIntent
(
IID
);
service
.
submit
(
intent
);
// Allow a small window of time until the intent is in the expected state
TestTools
.
assertAfter
(
GRACE_MS
,
new
Runnable
()
{
@Override
public
void
run
()
{
assertEquals
(
"incorrect intent state"
,
FAILED
,
service
.
getIntentState
(
intent
.
getId
()));
}
});
// Make sure that all expected events have been emitted
validateEvents
(
intent
,
SUBMITTED
,
COMPILED
,
FAILED
);
}
/**
* Validates that the test event listener has received the following events
* for the specified intent. Events received for other intents will not be
* considered.
*
* @param intent intent subject
* @param states list of states for which events are expected
*/
protected
void
validateEvents
(
Intent
intent
,
IntentState
...
states
)
{
Iterator
<
IntentEvent
>
events
=
listener
.
events
.
iterator
();
for
(
IntentState
state
:
states
)
{
IntentEvent
event
=
events
.
hasNext
()
?
events
.
next
()
:
null
;
if
(
event
==
null
)
{
fail
(
"expected event not found: "
+
state
);
}
else
if
(
intent
.
equals
(
event
.
getIntent
()))
{
assertEquals
(
"incorrect state"
,
state
,
event
.
getState
());
}
}
// Remainder of events should not apply to this intent; make sure.
while
(
events
.
hasNext
())
{
assertFalse
(
"unexpected event for intent"
,
intent
.
equals
(
events
.
next
().
getIntent
()));
}
}
@Test
public
void
compilerBasics
()
{
// Make sure there are no compilers
assertEquals
(
"incorrect compiler count"
,
0
,
service
.
getCompilers
().
size
());
// Add a compiler and make sure that it appears in the map
IntentCompiler
<
TestIntent
>
compiler
=
new
TestCompiler
(
false
);
service
.
registerCompiler
(
TestIntent
.
class
,
compiler
);
assertEquals
(
"incorrect compiler"
,
compiler
,
service
.
getCompilers
().
get
(
TestIntent
.
class
));
// Remove the same and make sure that it no longer appears in the map
service
.
unregisterCompiler
(
TestIntent
.
class
);
assertNull
(
"compiler should not be registered"
,
service
.
getCompilers
().
get
(
TestIntent
.
class
));
}
@Test
public
void
installerBasics
()
{
// Make sure there are no installers
assertEquals
(
"incorrect installer count"
,
0
,
service
.
getInstallers
().
size
());
// Add an installer and make sure that it appears in the map
IntentInstaller
<
TestInstallableIntent
>
installer
=
new
TestInstaller
(
false
);
service
.
registerInstaller
(
TestInstallableIntent
.
class
,
installer
);
assertEquals
(
"incorrect installer"
,
installer
,
service
.
getInstallers
().
get
(
TestInstallableIntent
.
class
));
// Remove the same and make sure that it no longer appears in the map
service
.
unregisterInstaller
(
TestInstallableIntent
.
class
);
assertNull
(
"installer should not be registered"
,
service
.
getInstallers
().
get
(
TestInstallableIntent
.
class
));
}
@Test
public
void
implicitRegistration
()
{
// Add a compiler and make sure that it appears in the map
IntentCompiler
<
TestIntent
>
compiler
=
new
TestCompiler
(
new
TestSubclassInstallableIntent
(
INSTALLABLE_IID
));
service
.
registerCompiler
(
TestIntent
.
class
,
compiler
);
assertEquals
(
"incorrect compiler"
,
compiler
,
service
.
getCompilers
().
get
(
TestIntent
.
class
));
// Add a installer and make sure that it appears in the map
IntentInstaller
<
TestInstallableIntent
>
installer
=
new
TestInstaller
(
false
);
service
.
registerInstaller
(
TestInstallableIntent
.
class
,
installer
);
assertEquals
(
"incorrect installer"
,
installer
,
service
.
getInstallers
().
get
(
TestInstallableIntent
.
class
));
// Submit an intent which is a subclass of the one we registered
final
Intent
intent
=
new
TestSubclassIntent
(
IID
);
service
.
submit
(
intent
);
// Allow some time for the intent to be compiled and installed
TestTools
.
assertAfter
(
GRACE_MS
,
new
Runnable
()
{
@Override
public
void
run
()
{
assertEquals
(
"incorrect intent state"
,
INSTALLED
,
service
.
getIntentState
(
intent
.
getId
()));
}
});
// Make sure that now we have an implicit registration of the compiler
// under the intent subclass
assertEquals
(
"incorrect compiler"
,
compiler
,
service
.
getCompilers
().
get
(
TestSubclassIntent
.
class
));
// Make sure that now we have an implicit registration of the installer
// under the intent subclass
assertEquals
(
"incorrect installer"
,
installer
,
service
.
getInstallers
().
get
(
TestSubclassInstallableIntent
.
class
));
// TODO: discuss whether or if implicit registration should require implicit unregistration
// perhaps unregister by compiler or installer itself, rather than by class would be better
}
// Fixture to track emitted intent events
protected
class
TestListener
implements
IntentEventListener
{
final
List
<
IntentEvent
>
events
=
new
ArrayList
<>();
@Override
public
void
event
(
IntentEvent
event
)
{
events
.
add
(
event
);
}
}
// Controllable compiler
private
class
TestCompiler
implements
IntentCompiler
<
TestIntent
>
{
private
final
boolean
fail
;
private
final
List
<
Intent
>
result
;
TestCompiler
(
boolean
fail
)
{
this
.
fail
=
fail
;
this
.
result
=
Collections
.
emptyList
();
}
TestCompiler
(
Intent
...
result
)
{
this
.
fail
=
false
;
this
.
result
=
Arrays
.
asList
(
result
);
}
@Override
public
List
<
Intent
>
compile
(
TestIntent
intent
)
{
if
(
fail
)
{
throw
new
IntentException
(
"compile failed by design"
);
}
List
<
Intent
>
compiled
=
new
ArrayList
<>(
result
);
return
compiled
;
}
}
// Controllable installer
private
class
TestInstaller
implements
IntentInstaller
<
TestInstallableIntent
>
{
private
final
boolean
fail
;
TestInstaller
(
boolean
fail
)
{
this
.
fail
=
fail
;
}
@Override
public
void
install
(
TestInstallableIntent
intent
)
{
if
(
fail
)
{
throw
new
IntentException
(
"install failed by design"
);
}
}
@Override
public
void
uninstall
(
TestInstallableIntent
intent
)
{
if
(
fail
)
{
throw
new
IntentException
(
"remove failed by design"
);
}
}
}
}
core/api/src/test/java/org/onlab/onos/net/intent/IntentTest.java
0 → 100644
View file @
185a003
package
org
.
onlab
.
onos
.
net
.
intent
;
import
static
org
.
junit
.
Assert
.
assertEquals
;
import
static
org
.
junit
.
Assert
.
assertFalse
;
import
static
org
.
junit
.
Assert
.
assertTrue
;
import
java.util.Arrays
;
import
java.util.HashSet
;
import
java.util.Set
;
import
org.junit.Test
;
/**
* Base facilities to test various intent tests.
*/
public
abstract
class
IntentTest
{
/**
* Produces a set of items from the supplied items.
*
* @param items items to be placed in set
* @param <T> item type
* @return set of items
*/
protected
static
<
T
>
Set
<
T
>
itemSet
(
T
[]
items
)
{
return
new
HashSet
<>(
Arrays
.
asList
(
items
));
}
@Test
public
void
equalsAndHashCode
()
{
Intent
one
=
createOne
();
Intent
like
=
createOne
();
Intent
another
=
createAnother
();
assertTrue
(
"should be equal"
,
one
.
equals
(
like
));
assertEquals
(
"incorrect hashCode"
,
one
.
hashCode
(),
like
.
hashCode
());
assertFalse
(
"should not be equal"
,
one
.
equals
(
another
));
assertFalse
(
"should not be equal"
,
one
.
equals
(
null
));
assertFalse
(
"should not be equal"
,
one
.
equals
(
"foo"
));
}
@Test
public
void
testToString
()
{
Intent
one
=
createOne
();
Intent
like
=
createOne
();
assertEquals
(
"incorrect toString"
,
one
.
toString
(),
like
.
toString
());
}
/**
* Creates a new intent, but always a like intent, i.e. all instances will
* be equal, but should not be the same.
*
* @return intent
*/
protected
abstract
Intent
createOne
();
/**
* Creates another intent, not equals to the one created by
* {@link #createOne()} and with a different hash code.
*
* @return another intent
*/
protected
abstract
Intent
createAnother
();
}
core/api/src/test/java/org/onlab/onos/net/intent/MultiPointToSinglePointIntentTest.java
0 → 100644
View file @
185a003
package
org
.
onlab
.
onos
.
net
.
intent
;
import
org.junit.Test
;
import
static
org
.
junit
.
Assert
.
assertEquals
;
/**
* Suite of tests of the multi-to-single point intent descriptor.
*/
public
class
MultiPointToSinglePointIntentTest
extends
ConnectivityIntentTest
{
@Test
public
void
basics
()
{
MultiPointToSinglePointIntent
intent
=
createOne
();
assertEquals
(
"incorrect id"
,
IID
,
intent
.
getId
());
assertEquals
(
"incorrect match"
,
MATCH
,
intent
.
getTrafficSelector
());
assertEquals
(
"incorrect ingress"
,
PS1
,
intent
.
getIngressPorts
());
assertEquals
(
"incorrect egress"
,
P2
,
intent
.
getEgressPort
());
}
@Override
protected
MultiPointToSinglePointIntent
createOne
()
{
return
new
MultiPointToSinglePointIntent
(
IID
,
MATCH
,
NOP
,
PS1
,
P2
);
}
@Override
protected
MultiPointToSinglePointIntent
createAnother
()
{
return
new
MultiPointToSinglePointIntent
(
IID
,
MATCH
,
NOP
,
PS2
,
P1
);
}
}
core/api/src/test/java/org/onlab/onos/net/intent/PathIntentTest.java
0 → 100644
View file @
185a003
package
org
.
onlab
.
onos
.
net
.
intent
;
import
static
org
.
junit
.
Assert
.
assertEquals
;
import
org.junit.Test
;
import
org.onlab.onos.net.NetTestTools
;
import
org.onlab.onos.net.Path
;
public
class
PathIntentTest
extends
ConnectivityIntentTest
{
// 111:11 --> 222:22
private
static
final
Path
PATH1
=
NetTestTools
.
createPath
(
"111"
,
"222"
);
// 111:11 --> 333:33
private
static
final
Path
PATH2
=
NetTestTools
.
createPath
(
"222"
,
"333"
);
@Test
public
void
basics
()
{
PathIntent
intent
=
createOne
();
assertEquals
(
"incorrect id"
,
IID
,
intent
.
getId
());
assertEquals
(
"incorrect match"
,
MATCH
,
intent
.
getTrafficSelector
());
assertEquals
(
"incorrect action"
,
NOP
,
intent
.
getTrafficTreatment
());
assertEquals
(
"incorrect ingress"
,
P1
,
intent
.
getIngressPort
());
assertEquals
(
"incorrect egress"
,
P2
,
intent
.
getEgressPort
());
assertEquals
(
"incorrect path"
,
PATH1
,
intent
.
getPath
());
}
@Override
protected
PathIntent
createOne
()
{
return
new
PathIntent
(
IID
,
MATCH
,
NOP
,
P1
,
P2
,
PATH1
);
}
@Override
protected
PathIntent
createAnother
()
{
return
new
PathIntent
(
IID
,
MATCH
,
NOP
,
P1
,
P3
,
PATH2
);
}
}
core/api/src/test/java/org/onlab/onos/net/intent/PointToPointIntentTest.java
0 → 100644
View file @
185a003
package
org
.
onlab
.
onos
.
net
.
intent
;
import
org.junit.Test
;
import
static
org
.
junit
.
Assert
.
assertEquals
;
/**
* Suite of tests of the point-to-point intent descriptor.
*/
public
class
PointToPointIntentTest
extends
ConnectivityIntentTest
{
@Test
public
void
basics
()
{
PointToPointIntent
intent
=
createOne
();
assertEquals
(
"incorrect id"
,
IID
,
intent
.
getId
());
assertEquals
(
"incorrect match"
,
MATCH
,
intent
.
getTrafficSelector
());
assertEquals
(
"incorrect ingress"
,
P1
,
intent
.
getIngressPort
());
assertEquals
(
"incorrect egress"
,
P2
,
intent
.
getEgressPort
());
}
@Override
protected
PointToPointIntent
createOne
()
{
return
new
PointToPointIntent
(
IID
,
MATCH
,
NOP
,
P1
,
P2
);
}
@Override
protected
PointToPointIntent
createAnother
()
{
return
new
PointToPointIntent
(
IID
,
MATCH
,
NOP
,
P2
,
P1
);
}
}
core/api/src/test/java/org/onlab/onos/net/intent/SinglePointToMultiPointIntentTest.java
0 → 100644
View file @
185a003
package
org
.
onlab
.
onos
.
net
.
intent
;
import
org.junit.Test
;
import
static
org
.
junit
.
Assert
.
assertEquals
;
/**
* Suite of tests of the single-to-multi point intent descriptor.
*/
public
class
SinglePointToMultiPointIntentTest
extends
ConnectivityIntentTest
{
@Test
public
void
basics
()
{
SinglePointToMultiPointIntent
intent
=
createOne
();
assertEquals
(
"incorrect id"
,
IID
,
intent
.
getId
());
assertEquals
(
"incorrect match"
,
MATCH
,
intent
.
getTrafficSelector
());
assertEquals
(
"incorrect ingress"
,
P1
,
intent
.
getIngressPort
());
assertEquals
(
"incorrect egress"
,
PS2
,
intent
.
getEgressPorts
());
}
@Override
protected
SinglePointToMultiPointIntent
createOne
()
{
return
new
SinglePointToMultiPointIntent
(
IID
,
MATCH
,
NOP
,
P1
,
PS2
);
}
@Override
protected
SinglePointToMultiPointIntent
createAnother
()
{
return
new
SinglePointToMultiPointIntent
(
IID
,
MATCH
,
NOP
,
P2
,
PS1
);
}
}
core/api/src/test/java/org/onlab/onos/net/intent/TestInstallableIntent.java
0 → 100644
View file @
185a003
package
org
.
onlab
.
onos
.
net
.
intent
;
//TODO is this the right package?
/**
* An installable intent used in the unit test.
*
* FIXME: we don't want to expose this class publicly, but the current Kryo
* serialization mechanism does not allow this class to be private and placed
* on testing directory.
*/
public
class
TestInstallableIntent
extends
AbstractIntent
implements
InstallableIntent
{
/**
* Constructs an instance with the specified intent ID.
*
* @param id intent ID
*/
public
TestInstallableIntent
(
IntentId
id
)
{
super
(
id
);
}
/**
* Constructor for serializer.
*/
protected
TestInstallableIntent
()
{
super
();
}
}
core/api/src/test/java/org/onlab/onos/net/intent/TestIntent.java
0 → 100644
View file @
185a003
package
org
.
onlab
.
onos
.
net
.
intent
;
//TODO is this the right package?
/**
* An intent used in the unit test.
*
* FIXME: we don't want to expose this class publicly, but the current Kryo
* serialization mechanism does not allow this class to be private and placed
* on testing directory.
*/
public
class
TestIntent
extends
AbstractIntent
{
/**
* Constructs an instance with the specified intent ID.
*
* @param id intent ID
*/
public
TestIntent
(
IntentId
id
)
{
super
(
id
);
}
/**
* Constructor for serializer.
*/
protected
TestIntent
()
{
super
();
}
}
core/api/src/test/java/org/onlab/onos/net/intent/TestSubclassInstallableIntent.java
0 → 100644
View file @
185a003
package
org
.
onlab
.
onos
.
net
.
intent
;
//TODO is this the right package?
/**
* An intent used in the unit test.
*
* FIXME: we don't want to expose this class publicly, but the current Kryo
* serialization mechanism does not allow this class to be private and placed
* on testing directory.
*/
public
class
TestSubclassInstallableIntent
extends
TestInstallableIntent
implements
InstallableIntent
{
/**
* Constructs an instance with the specified intent ID.
*
* @param id intent ID
*/
public
TestSubclassInstallableIntent
(
IntentId
id
)
{
super
(
id
);
}
/**
* Constructor for serializer.
*/
protected
TestSubclassInstallableIntent
()
{
super
();
}
}
core/api/src/test/java/org/onlab/onos/net/intent/TestSubclassIntent.java
0 → 100644
View file @
185a003
package
org
.
onlab
.
onos
.
net
.
intent
;
//TODO is this the right package?
/**
* An intent used in the unit test.
*
* FIXME: we don't want to expose this class publicly, but the current Kryo
* serialization mechanism does not allow this class to be private and placed
* on testing directory.
*/
public
class
TestSubclassIntent
extends
TestIntent
{
/**
* Constructs an instance with the specified intent ID.
*
* @param id intent ID
*/
public
TestSubclassIntent
(
IntentId
id
)
{
super
(
id
);
}
/**
* Constructor for serializer.
*/
protected
TestSubclassIntent
()
{
super
();
}
}
core/api/src/test/java/org/onlab/onos/net/intent/TestTools.java
0 → 100644
View file @
185a003
package
org
.
onlab
.
onos
.
net
.
intent
;
import
static
org
.
junit
.
Assert
.
fail
;
/**
* Set of test tools.
*/
public
final
class
TestTools
{
// Disallow construction
private
TestTools
()
{
}
/**
* Utility method to pause the current thread for the specified number of
* milliseconds.
*
* @param ms number of milliseconds to pause
*/
public
static
void
delay
(
int
ms
)
{
try
{
Thread
.
sleep
(
ms
);
}
catch
(
InterruptedException
e
)
{
fail
(
"unexpected interrupt"
);
}
}
/**
* Periodically runs the given runnable, which should contain a series of
* test assertions until all the assertions succeed, in which case it will
* return, or until the the time expires, in which case it will throw the
* first failed assertion error.
*
* @param start start time, in millis since start of epoch from which the
* duration will be measured
* @param delay initial delay (in milliseconds) before the first assertion
* attempt
* @param step delay (in milliseconds) between successive assertion
* attempts
* @param duration number of milliseconds beyond the given start time,
* after which the failed assertions will be propagated and allowed
* to fail the test
* @param assertions runnable housing the test assertions
*/
public
static
void
assertAfter
(
long
start
,
int
delay
,
int
step
,
int
duration
,
Runnable
assertions
)
{
delay
(
delay
);
while
(
true
)
{
try
{
assertions
.
run
();
break
;
}
catch
(
AssertionError
e
)
{
if
(
System
.
currentTimeMillis
()
-
start
>
duration
)
{
throw
e
;
}
}
delay
(
step
);
}
}
/**
* Periodically runs the given runnable, which should contain a series of
* test assertions until all the assertions succeed, in which case it will
* return, or until the the time expires, in which case it will throw the
* first failed assertion error.
* <p>
* The start of the period is the current time.
*
* @param delay initial delay (in milliseconds) before the first assertion
* attempt
* @param step delay (in milliseconds) between successive assertion
* attempts
* @param duration number of milliseconds beyond the current time time,
* after which the failed assertions will be propagated and allowed
* to fail the test
* @param assertions runnable housing the test assertions
*/
public
static
void
assertAfter
(
int
delay
,
int
step
,
int
duration
,
Runnable
assertions
)
{
assertAfter
(
System
.
currentTimeMillis
(),
delay
,
step
,
duration
,
assertions
);
}
/**
* Periodically runs the given runnable, which should contain a series of
* test assertions until all the assertions succeed, in which case it will
* return, or until the the time expires, in which case it will throw the
* first failed assertion error.
* <p>
* The start of the period is the current time and the first assertion
* attempt is delayed by the value of {@code step} parameter.
*
* @param step delay (in milliseconds) between successive assertion
* attempts
* @param duration number of milliseconds beyond the current time time,
* after which the failed assertions will be propagated and allowed
* to fail the test
* @param assertions runnable housing the test assertions
*/
public
static
void
assertAfter
(
int
step
,
int
duration
,
Runnable
assertions
)
{
assertAfter
(
step
,
step
,
duration
,
assertions
);
}
/**
* Periodically runs the given runnable, which should contain a series of
* test assertions until all the assertions succeed, in which case it will
* return, or until the the time expires, in which case it will throw the
* first failed assertion error.
* <p>
* The start of the period is the current time and each successive
* assertion attempt is delayed by at least 10 milliseconds unless the
* {@code duration} is less than that, in which case the one and only
* assertion is made after that delay.
*
* @param duration number of milliseconds beyond the current time,
* after which the failed assertions will be propagated and allowed
* to fail the test
* @param assertions runnable housing the test assertions
*/
public
static
void
assertAfter
(
int
duration
,
Runnable
assertions
)
{
int
step
=
Math
.
min
(
duration
,
Math
.
max
(
10
,
duration
/
10
));
assertAfter
(
step
,
duration
,
assertions
);
}
}
core/api/src/test/java/org/onlab/onos/net/intent/TestableIntentService.java
0 → 100644
View file @
185a003
package
org
.
onlab
.
onos
.
net
.
intent
;
import
java.util.List
;
/**
* Abstraction of an extensible intent service enabled for unit tests.
*/
public
interface
TestableIntentService
extends
IntentService
,
IntentExtensionService
{
List
<
IntentException
>
getExceptions
();
}
pom.xml
View file @
185a003
...
...
@@ -48,6 +48,19 @@
</dependency>
<dependency>
<groupId>
org.hamcrest
</groupId>
<artifactId>
hamcrest-core
</artifactId>
<version>
1.3
</version>
<scope>
test
</scope>
</dependency>
<dependency>
<groupId>
org.hamcrest
</groupId>
<artifactId>
hamcrest-library
</artifactId>
<version>
1.3
</version>
<scope>
test
</scope>
</dependency>
<dependency>
<groupId>
org.slf4j
</groupId>
<artifactId>
slf4j-api
</artifactId>
<version>
1.7.6
</version>
...
...
@@ -244,6 +257,14 @@
<artifactId>
junit
</artifactId>
</dependency>
<dependency>
<groupId>
org.hamcrest
</groupId>
<artifactId>
hamcrest-core
</artifactId>
</dependency>
<dependency>
<groupId>
org.hamcrest
</groupId>
<artifactId>
hamcrest-library
</artifactId>
</dependency>
<dependency>
<groupId>
org.slf4j
</groupId>
<artifactId>
slf4j-jdk14
</artifactId>
</dependency>
...
...
@@ -320,6 +341,35 @@
</plugin>
<!-- TODO: add findbugs plugin for static code analysis; for explicit invocation only -->
<!--This plugin's configuration is used to store Eclipse m2e settings only. It has no influence on the Maven build itself.-->
<plugin>
<groupId>
org.eclipse.m2e
</groupId>
<artifactId>
lifecycle-mapping
</artifactId>
<version>
1.0.0
</version>
<configuration>
<lifecycleMappingMetadata>
<pluginExecutions>
<pluginExecution>
<pluginExecutionFilter>
<groupId>
org.jacoco
</groupId>
<artifactId>
jacoco-maven-plugin
</artifactId>
<versionRange>
[0.7.1.201405082137,)
</versionRange>
<goals>
<goal>
prepare-agent
</goal>
</goals>
</pluginExecutionFilter>
<action>
<ignore></ignore>
</action>
</pluginExecution>
</pluginExecutions>
</lifecycleMappingMetadata>
</configuration>
</plugin>
</plugins>
</pluginManagement>
...
...
Please
register
or
login
to post a comment