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
Thomas Vachuska
2014-10-16 12:17:51 -0700
Browse Files
Options
Browse Files
Download
Plain Diff
Commit
eada07157569332bd53ad94088c9c87ef54df2fe
eada0715
2 parents
140d5854
20d8e514
Merge remote-tracking branch 'origin/master'
Show whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
1947 additions
and
0 deletions
apps/sdnip/pom.xml
apps/sdnip/src/test/java/org/onlab/onos/sdnip/bgp/AsPathTest.java
apps/sdnip/src/test/java/org/onlab/onos/sdnip/bgp/BgpRouteEntryTest.java
apps/sdnip/src/test/java/org/onlab/onos/sdnip/bgp/BgpSessionManagerTest.java
apps/sdnip/src/test/java/org/onlab/onos/sdnip/bgp/PathSegmentTest.java
apps/sdnip/src/test/java/org/onlab/onos/sdnip/bgp/TestBgpPeerChannelHandler.java
apps/sdnip/src/test/java/org/onlab/onos/sdnip/bgp/TestBgpPeerFrameDecoder.java
utils/misc/src/main/java/org/onlab/util/TestUtils.java
utils/misc/src/test/java/org/onlab/util/TestUtilsTest.java
apps/sdnip/pom.xml
View file @
eada071
...
...
@@ -42,6 +42,16 @@
<artifactId>
onlab-thirdparty
</artifactId>
</dependency>
<dependency>
<groupId>
org.onlab.onos
</groupId>
<artifactId>
onlab-misc
</artifactId>
</dependency>
<dependency>
<groupId>
org.easymock
</groupId>
<artifactId>
easymock
</artifactId>
<scope>
test
</scope>
</dependency>
</dependencies>
</project>
...
...
apps/sdnip/src/test/java/org/onlab/onos/sdnip/bgp/AsPathTest.java
0 → 100644
View file @
eada071
package
org
.
onlab
.
onos
.
sdnip
.
bgp
;
import
static
org
.
hamcrest
.
Matchers
.
is
;
import
static
org
.
hamcrest
.
Matchers
.
not
;
import
static
org
.
junit
.
Assert
.
assertThat
;
import
java.util.ArrayList
;
import
org.junit.Test
;
/**
* Unit tests for the BgpRouteEntry.AsPath class.
*/
public
class
AsPathTest
{
/**
* Generates an AS Path.
*
* @return a generated AS Path
*/
private
BgpRouteEntry
.
AsPath
generateAsPath
()
{
ArrayList
<
BgpRouteEntry
.
PathSegment
>
pathSegments
=
new
ArrayList
<>();
byte
pathSegmentType1
=
(
byte
)
BgpConstants
.
Update
.
AsPath
.
AS_SEQUENCE
;
ArrayList
<
Long
>
segmentAsNumbers1
=
new
ArrayList
<>();
segmentAsNumbers1
.
add
((
long
)
1
);
segmentAsNumbers1
.
add
((
long
)
2
);
segmentAsNumbers1
.
add
((
long
)
3
);
BgpRouteEntry
.
PathSegment
pathSegment1
=
new
BgpRouteEntry
.
PathSegment
(
pathSegmentType1
,
segmentAsNumbers1
);
pathSegments
.
add
(
pathSegment1
);
//
byte
pathSegmentType2
=
(
byte
)
BgpConstants
.
Update
.
AsPath
.
AS_SET
;
ArrayList
<
Long
>
segmentAsNumbers2
=
new
ArrayList
<>();
segmentAsNumbers2
.
add
((
long
)
4
);
segmentAsNumbers2
.
add
((
long
)
5
);
segmentAsNumbers2
.
add
((
long
)
6
);
BgpRouteEntry
.
PathSegment
pathSegment2
=
new
BgpRouteEntry
.
PathSegment
(
pathSegmentType2
,
segmentAsNumbers2
);
pathSegments
.
add
(
pathSegment2
);
//
BgpRouteEntry
.
AsPath
asPath
=
new
BgpRouteEntry
.
AsPath
(
pathSegments
);
return
asPath
;
}
/**
* Tests valid class constructor.
*/
@Test
public
void
testConstructor
()
{
BgpRouteEntry
.
AsPath
asPath
=
generateAsPath
();
String
expectedString
=
"AsPath{pathSegments="
+
"[PathSegment{type=2, segmentAsNumbers=[1, 2, 3]}, "
+
"PathSegment{type=1, segmentAsNumbers=[4, 5, 6]}]}"
;
assertThat
(
asPath
.
toString
(),
is
(
expectedString
));
}
/**
* Tests invalid class constructor for null Path Segments.
*/
@Test
(
expected
=
NullPointerException
.
class
)
public
void
testInvalidConstructorNullPathSegments
()
{
ArrayList
<
BgpRouteEntry
.
PathSegment
>
pathSegments
=
null
;
new
BgpRouteEntry
.
AsPath
(
pathSegments
);
}
/**
* Tests getting the fields of an AS Path.
*/
@Test
public
void
testGetFields
()
{
// Create the fields to compare against
ArrayList
<
BgpRouteEntry
.
PathSegment
>
pathSegments
=
new
ArrayList
<>();
byte
pathSegmentType1
=
(
byte
)
BgpConstants
.
Update
.
AsPath
.
AS_SEQUENCE
;
ArrayList
<
Long
>
segmentAsNumbers1
=
new
ArrayList
<>();
segmentAsNumbers1
.
add
((
long
)
1
);
segmentAsNumbers1
.
add
((
long
)
2
);
segmentAsNumbers1
.
add
((
long
)
3
);
BgpRouteEntry
.
PathSegment
pathSegment1
=
new
BgpRouteEntry
.
PathSegment
(
pathSegmentType1
,
segmentAsNumbers1
);
pathSegments
.
add
(
pathSegment1
);
//
byte
pathSegmentType2
=
(
byte
)
BgpConstants
.
Update
.
AsPath
.
AS_SET
;
ArrayList
<
Long
>
segmentAsNumbers2
=
new
ArrayList
<>();
segmentAsNumbers2
.
add
((
long
)
4
);
segmentAsNumbers2
.
add
((
long
)
5
);
segmentAsNumbers2
.
add
((
long
)
6
);
BgpRouteEntry
.
PathSegment
pathSegment2
=
new
BgpRouteEntry
.
PathSegment
(
pathSegmentType2
,
segmentAsNumbers2
);
pathSegments
.
add
(
pathSegment2
);
// Generate the entry to test
BgpRouteEntry
.
AsPath
asPath
=
generateAsPath
();
assertThat
(
asPath
.
getPathSegments
(),
is
(
pathSegments
));
}
/**
* Tests getting the AS Path Length.
*/
@Test
public
void
testGetAsPathLength
()
{
BgpRouteEntry
.
AsPath
asPath
=
generateAsPath
();
assertThat
(
asPath
.
getAsPathLength
(),
is
(
4
));
// Create an empty AS Path
ArrayList
<
BgpRouteEntry
.
PathSegment
>
pathSegments
=
new
ArrayList
<>();
asPath
=
new
BgpRouteEntry
.
AsPath
(
pathSegments
);
assertThat
(
asPath
.
getAsPathLength
(),
is
(
0
));
}
/**
* Tests equality of {@link BgpRouteEntry.AsPath}.
*/
@Test
public
void
testEquality
()
{
BgpRouteEntry
.
AsPath
asPath1
=
generateAsPath
();
BgpRouteEntry
.
AsPath
asPath2
=
generateAsPath
();
assertThat
(
asPath1
,
is
(
asPath2
));
}
/**
* Tests non-equality of {@link BgpRouteEntry.AsPath}.
*/
@Test
public
void
testNonEquality
()
{
BgpRouteEntry
.
AsPath
asPath1
=
generateAsPath
();
// Setup AS Path 2
ArrayList
<
BgpRouteEntry
.
PathSegment
>
pathSegments
=
new
ArrayList
<>();
byte
pathSegmentType1
=
(
byte
)
BgpConstants
.
Update
.
AsPath
.
AS_SEQUENCE
;
ArrayList
<
Long
>
segmentAsNumbers1
=
new
ArrayList
<>();
segmentAsNumbers1
.
add
((
long
)
1
);
segmentAsNumbers1
.
add
((
long
)
2
);
segmentAsNumbers1
.
add
((
long
)
3
);
BgpRouteEntry
.
PathSegment
pathSegment1
=
new
BgpRouteEntry
.
PathSegment
(
pathSegmentType1
,
segmentAsNumbers1
);
pathSegments
.
add
(
pathSegment1
);
//
byte
pathSegmentType2
=
(
byte
)
BgpConstants
.
Update
.
AsPath
.
AS_SET
;
ArrayList
<
Long
>
segmentAsNumbers2
=
new
ArrayList
<>();
segmentAsNumbers2
.
add
((
long
)
4
);
segmentAsNumbers2
.
add
((
long
)
55
);
// Different
segmentAsNumbers2
.
add
((
long
)
6
);
BgpRouteEntry
.
PathSegment
pathSegment2
=
new
BgpRouteEntry
.
PathSegment
(
pathSegmentType2
,
segmentAsNumbers2
);
pathSegments
.
add
(
pathSegment2
);
//
BgpRouteEntry
.
AsPath
asPath2
=
new
BgpRouteEntry
.
AsPath
(
pathSegments
);
assertThat
(
asPath1
,
is
(
not
(
asPath2
)));
}
/**
* Tests object string representation.
*/
@Test
public
void
testToString
()
{
BgpRouteEntry
.
AsPath
asPath
=
generateAsPath
();
String
expectedString
=
"AsPath{pathSegments="
+
"[PathSegment{type=2, segmentAsNumbers=[1, 2, 3]}, "
+
"PathSegment{type=1, segmentAsNumbers=[4, 5, 6]}]}"
;
assertThat
(
asPath
.
toString
(),
is
(
expectedString
));
}
}
apps/sdnip/src/test/java/org/onlab/onos/sdnip/bgp/BgpRouteEntryTest.java
0 → 100644
View file @
eada071
package
org
.
onlab
.
onos
.
sdnip
.
bgp
;
import
static
org
.
easymock
.
EasyMock
.
createMock
;
import
static
org
.
easymock
.
EasyMock
.
expect
;
import
static
org
.
easymock
.
EasyMock
.
replay
;
import
static
org
.
hamcrest
.
Matchers
.
is
;
import
static
org
.
hamcrest
.
Matchers
.
not
;
import
static
org
.
junit
.
Assert
.
assertThat
;
import
java.util.ArrayList
;
import
org.junit.Before
;
import
org.junit.Test
;
import
org.onlab.packet.IpAddress
;
import
org.onlab.packet.IpPrefix
;
/**
* Unit tests for the BgpRouteEntry class.
*/
public
class
BgpRouteEntryTest
{
private
BgpSession
bgpSession
;
private
static
final
IpAddress
BGP_SESSION_BGP_ID
=
IpAddress
.
valueOf
(
"10.0.0.1"
);
private
static
final
IpAddress
BGP_SESSION_IP_ADDRESS
=
IpAddress
.
valueOf
(
"20.0.0.1"
);
private
BgpSession
bgpSession2
;
private
static
final
IpAddress
BGP_SESSION_BGP_ID2
=
IpAddress
.
valueOf
(
"10.0.0.2"
);
private
static
final
IpAddress
BGP_SESSION_IP_ADDRESS2
=
IpAddress
.
valueOf
(
"20.0.0.1"
);
private
BgpSession
bgpSession3
;
private
static
final
IpAddress
BGP_SESSION_BGP_ID3
=
IpAddress
.
valueOf
(
"10.0.0.1"
);
private
static
final
IpAddress
BGP_SESSION_IP_ADDRESS3
=
IpAddress
.
valueOf
(
"20.0.0.2"
);
@Before
public
void
setUp
()
throws
Exception
{
// Mock objects for testing
bgpSession
=
createMock
(
BgpSession
.
class
);
bgpSession2
=
createMock
(
BgpSession
.
class
);
bgpSession3
=
createMock
(
BgpSession
.
class
);
// Setup the BGP Sessions
expect
(
bgpSession
.
getRemoteBgpId
())
.
andReturn
(
BGP_SESSION_BGP_ID
).
anyTimes
();
expect
(
bgpSession
.
getRemoteIp4Address
())
.
andReturn
(
BGP_SESSION_IP_ADDRESS
).
anyTimes
();
//
expect
(
bgpSession2
.
getRemoteBgpId
())
.
andReturn
(
BGP_SESSION_BGP_ID2
).
anyTimes
();
expect
(
bgpSession2
.
getRemoteIp4Address
())
.
andReturn
(
BGP_SESSION_IP_ADDRESS2
).
anyTimes
();
//
expect
(
bgpSession3
.
getRemoteBgpId
())
.
andReturn
(
BGP_SESSION_BGP_ID3
).
anyTimes
();
expect
(
bgpSession3
.
getRemoteIp4Address
())
.
andReturn
(
BGP_SESSION_IP_ADDRESS3
).
anyTimes
();
replay
(
bgpSession
);
replay
(
bgpSession2
);
replay
(
bgpSession3
);
}
/**
* Generates a BGP Route Entry.
*
* @return a generated BGP Route Entry
*/
private
BgpRouteEntry
generateBgpRouteEntry
()
{
IpPrefix
prefix
=
IpPrefix
.
valueOf
(
"1.2.3.0/24"
);
IpAddress
nextHop
=
IpAddress
.
valueOf
(
"5.6.7.8"
);
byte
origin
=
BgpConstants
.
Update
.
Origin
.
IGP
;
// Setup the AS Path
ArrayList
<
BgpRouteEntry
.
PathSegment
>
pathSegments
=
new
ArrayList
<>();
byte
pathSegmentType1
=
(
byte
)
BgpConstants
.
Update
.
AsPath
.
AS_SEQUENCE
;
ArrayList
<
Long
>
segmentAsNumbers1
=
new
ArrayList
<>();
segmentAsNumbers1
.
add
((
long
)
1
);
segmentAsNumbers1
.
add
((
long
)
2
);
segmentAsNumbers1
.
add
((
long
)
3
);
BgpRouteEntry
.
PathSegment
pathSegment1
=
new
BgpRouteEntry
.
PathSegment
(
pathSegmentType1
,
segmentAsNumbers1
);
pathSegments
.
add
(
pathSegment1
);
//
byte
pathSegmentType2
=
(
byte
)
BgpConstants
.
Update
.
AsPath
.
AS_SET
;
ArrayList
<
Long
>
segmentAsNumbers2
=
new
ArrayList
<>();
segmentAsNumbers2
.
add
((
long
)
4
);
segmentAsNumbers2
.
add
((
long
)
5
);
segmentAsNumbers2
.
add
((
long
)
6
);
BgpRouteEntry
.
PathSegment
pathSegment2
=
new
BgpRouteEntry
.
PathSegment
(
pathSegmentType2
,
segmentAsNumbers2
);
pathSegments
.
add
(
pathSegment2
);
//
BgpRouteEntry
.
AsPath
asPath
=
new
BgpRouteEntry
.
AsPath
(
pathSegments
);
//
long
localPref
=
100
;
long
multiExitDisc
=
20
;
BgpRouteEntry
bgpRouteEntry
=
new
BgpRouteEntry
(
bgpSession
,
prefix
,
nextHop
,
origin
,
asPath
,
localPref
);
bgpRouteEntry
.
setMultiExitDisc
(
multiExitDisc
);
return
bgpRouteEntry
;
}
/**
* Tests valid class constructor.
*/
@Test
public
void
testConstructor
()
{
BgpRouteEntry
bgpRouteEntry
=
generateBgpRouteEntry
();
String
expectedString
=
"BgpRouteEntry{prefix=1.2.3.0/24, nextHop=5.6.7.8, "
+
"bgpId=10.0.0.1, origin=0, asPath=AsPath{pathSegments="
+
"[PathSegment{type=2, segmentAsNumbers=[1, 2, 3]}, "
+
"PathSegment{type=1, segmentAsNumbers=[4, 5, 6]}]}, "
+
"localPref=100, multiExitDisc=20}"
;
assertThat
(
bgpRouteEntry
.
toString
(),
is
(
expectedString
));
}
/**
* Tests invalid class constructor for null BGP Session.
*/
@Test
(
expected
=
NullPointerException
.
class
)
public
void
testInvalidConstructorNullBgpSession
()
{
BgpSession
bgpSessionNull
=
null
;
IpPrefix
prefix
=
IpPrefix
.
valueOf
(
"1.2.3.0/24"
);
IpAddress
nextHop
=
IpAddress
.
valueOf
(
"5.6.7.8"
);
byte
origin
=
BgpConstants
.
Update
.
Origin
.
IGP
;
// Setup the AS Path
ArrayList
<
BgpRouteEntry
.
PathSegment
>
pathSegments
=
new
ArrayList
<>();
BgpRouteEntry
.
AsPath
asPath
=
new
BgpRouteEntry
.
AsPath
(
pathSegments
);
//
long
localPref
=
100
;
new
BgpRouteEntry
(
bgpSessionNull
,
prefix
,
nextHop
,
origin
,
asPath
,
localPref
);
}
/**
* Tests invalid class constructor for null AS Path.
*/
@Test
(
expected
=
NullPointerException
.
class
)
public
void
testInvalidConstructorNullAsPath
()
{
IpPrefix
prefix
=
IpPrefix
.
valueOf
(
"1.2.3.0/24"
);
IpAddress
nextHop
=
IpAddress
.
valueOf
(
"5.6.7.8"
);
byte
origin
=
BgpConstants
.
Update
.
Origin
.
IGP
;
BgpRouteEntry
.
AsPath
asPath
=
null
;
long
localPref
=
100
;
new
BgpRouteEntry
(
bgpSession
,
prefix
,
nextHop
,
origin
,
asPath
,
localPref
);
}
/**
* Tests getting the fields of a BGP route entry.
*/
@Test
public
void
testGetFields
()
{
// Create the fields to compare against
IpPrefix
prefix
=
IpPrefix
.
valueOf
(
"1.2.3.0/24"
);
IpAddress
nextHop
=
IpAddress
.
valueOf
(
"5.6.7.8"
);
byte
origin
=
BgpConstants
.
Update
.
Origin
.
IGP
;
// Setup the AS Path
ArrayList
<
BgpRouteEntry
.
PathSegment
>
pathSegments
=
new
ArrayList
<>();
byte
pathSegmentType1
=
(
byte
)
BgpConstants
.
Update
.
AsPath
.
AS_SEQUENCE
;
ArrayList
<
Long
>
segmentAsNumbers1
=
new
ArrayList
<>();
segmentAsNumbers1
.
add
((
long
)
1
);
segmentAsNumbers1
.
add
((
long
)
2
);
segmentAsNumbers1
.
add
((
long
)
3
);
BgpRouteEntry
.
PathSegment
pathSegment1
=
new
BgpRouteEntry
.
PathSegment
(
pathSegmentType1
,
segmentAsNumbers1
);
pathSegments
.
add
(
pathSegment1
);
//
byte
pathSegmentType2
=
(
byte
)
BgpConstants
.
Update
.
AsPath
.
AS_SET
;
ArrayList
<
Long
>
segmentAsNumbers2
=
new
ArrayList
<>();
segmentAsNumbers2
.
add
((
long
)
4
);
segmentAsNumbers2
.
add
((
long
)
5
);
segmentAsNumbers2
.
add
((
long
)
6
);
BgpRouteEntry
.
PathSegment
pathSegment2
=
new
BgpRouteEntry
.
PathSegment
(
pathSegmentType2
,
segmentAsNumbers2
);
pathSegments
.
add
(
pathSegment2
);
//
BgpRouteEntry
.
AsPath
asPath
=
new
BgpRouteEntry
.
AsPath
(
pathSegments
);
//
long
localPref
=
100
;
long
multiExitDisc
=
20
;
// Generate the entry to test
BgpRouteEntry
bgpRouteEntry
=
generateBgpRouteEntry
();
assertThat
(
bgpRouteEntry
.
prefix
(),
is
(
prefix
));
assertThat
(
bgpRouteEntry
.
nextHop
(),
is
(
nextHop
));
assertThat
(
bgpRouteEntry
.
getBgpSession
(),
is
(
bgpSession
));
assertThat
(
bgpRouteEntry
.
getOrigin
(),
is
(
origin
));
assertThat
(
bgpRouteEntry
.
getAsPath
(),
is
(
asPath
));
assertThat
(
bgpRouteEntry
.
getLocalPref
(),
is
(
localPref
));
assertThat
(
bgpRouteEntry
.
getMultiExitDisc
(),
is
(
multiExitDisc
));
}
/**
* Tests whether a BGP route entry is a local route.
*/
@Test
public
void
testIsLocalRoute
()
{
//
// Test non-local route
//
BgpRouteEntry
bgpRouteEntry
=
generateBgpRouteEntry
();
assertThat
(
bgpRouteEntry
.
isLocalRoute
(),
is
(
false
));
//
// Test local route with AS Path that begins with AS_SET
//
IpPrefix
prefix
=
IpPrefix
.
valueOf
(
"1.2.3.0/24"
);
IpAddress
nextHop
=
IpAddress
.
valueOf
(
"5.6.7.8"
);
byte
origin
=
BgpConstants
.
Update
.
Origin
.
IGP
;
// Setup the AS Path
ArrayList
<
BgpRouteEntry
.
PathSegment
>
pathSegments
=
new
ArrayList
<>();
byte
pathSegmentType1
=
(
byte
)
BgpConstants
.
Update
.
AsPath
.
AS_SET
;
ArrayList
<
Long
>
segmentAsNumbers1
=
new
ArrayList
<>();
segmentAsNumbers1
.
add
((
long
)
1
);
segmentAsNumbers1
.
add
((
long
)
2
);
segmentAsNumbers1
.
add
((
long
)
3
);
BgpRouteEntry
.
PathSegment
pathSegment1
=
new
BgpRouteEntry
.
PathSegment
(
pathSegmentType1
,
segmentAsNumbers1
);
pathSegments
.
add
(
pathSegment1
);
//
byte
pathSegmentType2
=
(
byte
)
BgpConstants
.
Update
.
AsPath
.
AS_SEQUENCE
;
ArrayList
<
Long
>
segmentAsNumbers2
=
new
ArrayList
<>();
segmentAsNumbers2
.
add
((
long
)
4
);
segmentAsNumbers2
.
add
((
long
)
5
);
segmentAsNumbers2
.
add
((
long
)
6
);
BgpRouteEntry
.
PathSegment
pathSegment2
=
new
BgpRouteEntry
.
PathSegment
(
pathSegmentType2
,
segmentAsNumbers2
);
pathSegments
.
add
(
pathSegment2
);
//
BgpRouteEntry
.
AsPath
asPath
=
new
BgpRouteEntry
.
AsPath
(
pathSegments
);
//
long
localPref
=
100
;
long
multiExitDisc
=
20
;
//
bgpRouteEntry
=
new
BgpRouteEntry
(
bgpSession
,
prefix
,
nextHop
,
origin
,
asPath
,
localPref
);
bgpRouteEntry
.
setMultiExitDisc
(
multiExitDisc
);
assertThat
(
bgpRouteEntry
.
isLocalRoute
(),
is
(
true
));
//
// Test local route with empty AS Path
//
pathSegments
=
new
ArrayList
<>();
asPath
=
new
BgpRouteEntry
.
AsPath
(
pathSegments
);
bgpRouteEntry
=
new
BgpRouteEntry
(
bgpSession
,
prefix
,
nextHop
,
origin
,
asPath
,
localPref
);
bgpRouteEntry
.
setMultiExitDisc
(
multiExitDisc
);
assertThat
(
bgpRouteEntry
.
isLocalRoute
(),
is
(
true
));
}
/**
* Tests getting the BGP Neighbor AS number for a route.
*/
@Test
public
void
testGetNeighborAs
()
{
//
// Get neighbor AS for non-local route
//
BgpRouteEntry
bgpRouteEntry
=
generateBgpRouteEntry
();
assertThat
(
bgpRouteEntry
.
getNeighborAs
(),
is
((
long
)
1
));
//
// Get neighbor AS for a local route
//
IpPrefix
prefix
=
IpPrefix
.
valueOf
(
"1.2.3.0/24"
);
IpAddress
nextHop
=
IpAddress
.
valueOf
(
"5.6.7.8"
);
byte
origin
=
BgpConstants
.
Update
.
Origin
.
IGP
;
// Setup the AS Path
ArrayList
<
BgpRouteEntry
.
PathSegment
>
pathSegments
=
new
ArrayList
<>();
BgpRouteEntry
.
AsPath
asPath
=
new
BgpRouteEntry
.
AsPath
(
pathSegments
);
//
long
localPref
=
100
;
long
multiExitDisc
=
20
;
//
bgpRouteEntry
=
new
BgpRouteEntry
(
bgpSession
,
prefix
,
nextHop
,
origin
,
asPath
,
localPref
);
bgpRouteEntry
.
setMultiExitDisc
(
multiExitDisc
);
assertThat
(
bgpRouteEntry
.
getNeighborAs
(),
is
(
BgpConstants
.
BGP_AS_0
));
}
/**
* Tests whether a BGP route entry has AS Path loop.
*/
@Test
public
void
testHasAsPathLoop
()
{
BgpRouteEntry
bgpRouteEntry
=
generateBgpRouteEntry
();
// Test for loops: test each AS number in the interval [1, 6]
for
(
int
i
=
1
;
i
<=
6
;
i
++)
{
assertThat
(
bgpRouteEntry
.
hasAsPathLoop
(
i
),
is
(
true
));
}
// Test for non-loops
assertThat
(
bgpRouteEntry
.
hasAsPathLoop
(
500
),
is
(
false
));
}
/**
* Tests the BGP Decision Process comparison of BGP routes.
*/
@Test
public
void
testBgpDecisionProcessComparison
()
{
BgpRouteEntry
bgpRouteEntry1
=
generateBgpRouteEntry
();
BgpRouteEntry
bgpRouteEntry2
=
generateBgpRouteEntry
();
//
// Compare two routes that are same
//
assertThat
(
bgpRouteEntry1
.
isBetterThan
(
bgpRouteEntry2
),
is
(
true
));
assertThat
(
bgpRouteEntry2
.
isBetterThan
(
bgpRouteEntry1
),
is
(
true
));
//
// Compare two routes with different LOCAL_PREF
//
IpPrefix
prefix
=
IpPrefix
.
valueOf
(
"1.2.3.0/24"
);
IpAddress
nextHop
=
IpAddress
.
valueOf
(
"5.6.7.8"
);
byte
origin
=
BgpConstants
.
Update
.
Origin
.
IGP
;
// Setup the AS Path
ArrayList
<
BgpRouteEntry
.
PathSegment
>
pathSegments
=
new
ArrayList
<>();
byte
pathSegmentType1
=
(
byte
)
BgpConstants
.
Update
.
AsPath
.
AS_SEQUENCE
;
ArrayList
<
Long
>
segmentAsNumbers1
=
new
ArrayList
<>();
segmentAsNumbers1
.
add
((
long
)
1
);
segmentAsNumbers1
.
add
((
long
)
2
);
segmentAsNumbers1
.
add
((
long
)
3
);
BgpRouteEntry
.
PathSegment
pathSegment1
=
new
BgpRouteEntry
.
PathSegment
(
pathSegmentType1
,
segmentAsNumbers1
);
pathSegments
.
add
(
pathSegment1
);
//
byte
pathSegmentType2
=
(
byte
)
BgpConstants
.
Update
.
AsPath
.
AS_SET
;
ArrayList
<
Long
>
segmentAsNumbers2
=
new
ArrayList
<>();
segmentAsNumbers2
.
add
((
long
)
4
);
segmentAsNumbers2
.
add
((
long
)
5
);
segmentAsNumbers2
.
add
((
long
)
6
);
BgpRouteEntry
.
PathSegment
pathSegment2
=
new
BgpRouteEntry
.
PathSegment
(
pathSegmentType2
,
segmentAsNumbers2
);
pathSegments
.
add
(
pathSegment2
);
//
BgpRouteEntry
.
AsPath
asPath
=
new
BgpRouteEntry
.
AsPath
(
pathSegments
);
//
long
localPref
=
50
;
// Different
long
multiExitDisc
=
20
;
bgpRouteEntry2
=
new
BgpRouteEntry
(
bgpSession
,
prefix
,
nextHop
,
origin
,
asPath
,
localPref
);
bgpRouteEntry2
.
setMultiExitDisc
(
multiExitDisc
);
//
assertThat
(
bgpRouteEntry1
.
isBetterThan
(
bgpRouteEntry2
),
is
(
true
));
assertThat
(
bgpRouteEntry2
.
isBetterThan
(
bgpRouteEntry1
),
is
(
false
));
localPref
=
bgpRouteEntry1
.
getLocalPref
();
// Restore
//
// Compare two routes with different AS_PATH length
//
ArrayList
<
BgpRouteEntry
.
PathSegment
>
pathSegments2
=
new
ArrayList
<>();
pathSegments2
.
add
(
pathSegment1
);
// Different AS Path
BgpRouteEntry
.
AsPath
asPath2
=
new
BgpRouteEntry
.
AsPath
(
pathSegments2
);
bgpRouteEntry2
=
new
BgpRouteEntry
(
bgpSession
,
prefix
,
nextHop
,
origin
,
asPath2
,
localPref
);
bgpRouteEntry2
.
setMultiExitDisc
(
multiExitDisc
);
//
assertThat
(
bgpRouteEntry1
.
isBetterThan
(
bgpRouteEntry2
),
is
(
false
));
assertThat
(
bgpRouteEntry2
.
isBetterThan
(
bgpRouteEntry1
),
is
(
true
));
//
// Compare two routes with different ORIGIN
//
origin
=
BgpConstants
.
Update
.
Origin
.
EGP
;
// Different
bgpRouteEntry2
=
new
BgpRouteEntry
(
bgpSession
,
prefix
,
nextHop
,
origin
,
asPath
,
localPref
);
bgpRouteEntry2
.
setMultiExitDisc
(
multiExitDisc
);
//
assertThat
(
bgpRouteEntry1
.
isBetterThan
(
bgpRouteEntry2
),
is
(
true
));
assertThat
(
bgpRouteEntry2
.
isBetterThan
(
bgpRouteEntry1
),
is
(
false
));
origin
=
bgpRouteEntry1
.
getOrigin
();
// Restore
//
// Compare two routes with different MULTI_EXIT_DISC
//
multiExitDisc
=
10
;
// Different
bgpRouteEntry2
=
new
BgpRouteEntry
(
bgpSession
,
prefix
,
nextHop
,
origin
,
asPath
,
localPref
);
bgpRouteEntry2
.
setMultiExitDisc
(
multiExitDisc
);
//
assertThat
(
bgpRouteEntry1
.
isBetterThan
(
bgpRouteEntry2
),
is
(
true
));
assertThat
(
bgpRouteEntry2
.
isBetterThan
(
bgpRouteEntry1
),
is
(
false
));
multiExitDisc
=
bgpRouteEntry1
.
getMultiExitDisc
();
// Restore
//
// Compare two routes with different BGP ID
//
bgpRouteEntry2
=
new
BgpRouteEntry
(
bgpSession2
,
prefix
,
nextHop
,
origin
,
asPath
,
localPref
);
bgpRouteEntry2
.
setMultiExitDisc
(
multiExitDisc
);
//
assertThat
(
bgpRouteEntry1
.
isBetterThan
(
bgpRouteEntry2
),
is
(
true
));
assertThat
(
bgpRouteEntry2
.
isBetterThan
(
bgpRouteEntry1
),
is
(
false
));
//
// Compare two routes with different BGP address
//
bgpRouteEntry2
=
new
BgpRouteEntry
(
bgpSession3
,
prefix
,
nextHop
,
origin
,
asPath
,
localPref
);
bgpRouteEntry2
.
setMultiExitDisc
(
multiExitDisc
);
//
assertThat
(
bgpRouteEntry1
.
isBetterThan
(
bgpRouteEntry2
),
is
(
true
));
assertThat
(
bgpRouteEntry2
.
isBetterThan
(
bgpRouteEntry1
),
is
(
false
));
}
/**
* Tests equality of {@link BgpRouteEntry}.
*/
@Test
public
void
testEquality
()
{
BgpRouteEntry
bgpRouteEntry1
=
generateBgpRouteEntry
();
BgpRouteEntry
bgpRouteEntry2
=
generateBgpRouteEntry
();
assertThat
(
bgpRouteEntry1
,
is
(
bgpRouteEntry2
));
}
/**
* Tests non-equality of {@link BgpRouteEntry}.
*/
@Test
public
void
testNonEquality
()
{
BgpRouteEntry
bgpRouteEntry1
=
generateBgpRouteEntry
();
// Setup BGP Route 2
IpPrefix
prefix
=
IpPrefix
.
valueOf
(
"1.2.3.0/24"
);
IpAddress
nextHop
=
IpAddress
.
valueOf
(
"5.6.7.8"
);
byte
origin
=
BgpConstants
.
Update
.
Origin
.
IGP
;
// Setup the AS Path
ArrayList
<
BgpRouteEntry
.
PathSegment
>
pathSegments
=
new
ArrayList
<>();
byte
pathSegmentType1
=
(
byte
)
BgpConstants
.
Update
.
AsPath
.
AS_SEQUENCE
;
ArrayList
<
Long
>
segmentAsNumbers1
=
new
ArrayList
<>();
segmentAsNumbers1
.
add
((
long
)
1
);
segmentAsNumbers1
.
add
((
long
)
2
);
segmentAsNumbers1
.
add
((
long
)
3
);
BgpRouteEntry
.
PathSegment
pathSegment1
=
new
BgpRouteEntry
.
PathSegment
(
pathSegmentType1
,
segmentAsNumbers1
);
pathSegments
.
add
(
pathSegment1
);
//
byte
pathSegmentType2
=
(
byte
)
BgpConstants
.
Update
.
AsPath
.
AS_SET
;
ArrayList
<
Long
>
segmentAsNumbers2
=
new
ArrayList
<>();
segmentAsNumbers2
.
add
((
long
)
4
);
segmentAsNumbers2
.
add
((
long
)
5
);
segmentAsNumbers2
.
add
((
long
)
6
);
BgpRouteEntry
.
PathSegment
pathSegment2
=
new
BgpRouteEntry
.
PathSegment
(
pathSegmentType2
,
segmentAsNumbers2
);
pathSegments
.
add
(
pathSegment2
);
//
BgpRouteEntry
.
AsPath
asPath
=
new
BgpRouteEntry
.
AsPath
(
pathSegments
);
//
long
localPref
=
500
;
// Different
long
multiExitDisc
=
20
;
BgpRouteEntry
bgpRouteEntry2
=
new
BgpRouteEntry
(
bgpSession
,
prefix
,
nextHop
,
origin
,
asPath
,
localPref
);
bgpRouteEntry2
.
setMultiExitDisc
(
multiExitDisc
);
assertThat
(
bgpRouteEntry1
,
is
(
not
(
bgpRouteEntry2
)));
}
/**
* Tests object string representation.
*/
@Test
public
void
testToString
()
{
BgpRouteEntry
bgpRouteEntry
=
generateBgpRouteEntry
();
String
expectedString
=
"BgpRouteEntry{prefix=1.2.3.0/24, nextHop=5.6.7.8, "
+
"bgpId=10.0.0.1, origin=0, asPath=AsPath{pathSegments="
+
"[PathSegment{type=2, segmentAsNumbers=[1, 2, 3]}, "
+
"PathSegment{type=1, segmentAsNumbers=[4, 5, 6]}]}, "
+
"localPref=100, multiExitDisc=20}"
;
assertThat
(
bgpRouteEntry
.
toString
(),
is
(
expectedString
));
}
}
apps/sdnip/src/test/java/org/onlab/onos/sdnip/bgp/BgpSessionManagerTest.java
0 → 100644
View file @
eada071
package
org
.
onlab
.
onos
.
sdnip
.
bgp
;
import
static
org
.
hamcrest
.
Matchers
.
hasItem
;
import
static
org
.
hamcrest
.
Matchers
.
hasSize
;
import
static
org
.
hamcrest
.
Matchers
.
is
;
import
static
org
.
hamcrest
.
Matchers
.
notNullValue
;
import
static
org
.
junit
.
Assert
.
assertThat
;
import
java.net.InetAddress
;
import
java.net.InetSocketAddress
;
import
java.net.SocketAddress
;
import
java.util.ArrayList
;
import
java.util.Collection
;
import
java.util.LinkedList
;
import
java.util.concurrent.Executors
;
import
java.util.concurrent.TimeUnit
;
import
org.jboss.netty.bootstrap.ClientBootstrap
;
import
org.jboss.netty.buffer.ChannelBuffer
;
import
org.jboss.netty.channel.Channel
;
import
org.jboss.netty.channel.ChannelFactory
;
import
org.jboss.netty.channel.ChannelPipeline
;
import
org.jboss.netty.channel.ChannelPipelineFactory
;
import
org.jboss.netty.channel.Channels
;
import
org.jboss.netty.channel.socket.nio.NioClientSocketChannelFactory
;
import
org.junit.After
;
import
org.junit.Before
;
import
org.junit.Test
;
import
org.onlab.onos.sdnip.RouteListener
;
import
org.onlab.onos.sdnip.RouteUpdate
;
import
org.onlab.packet.IpAddress
;
import
org.onlab.packet.IpPrefix
;
import
org.onlab.util.TestUtils
;
import
org.onlab.util.TestUtils.TestUtilsException
;
import
com.google.common.net.InetAddresses
;
/**
* Unit tests for the BgpSessionManager class.
*/
public
class
BgpSessionManagerTest
{
private
static
final
IpAddress
IP_LOOPBACK_ID
=
IpAddress
.
valueOf
(
"127.0.0.1"
);
private
static
final
IpAddress
BGP_PEER1_ID
=
IpAddress
.
valueOf
(
"10.0.0.1"
);
private
static
final
long
DEFAULT_LOCAL_PREF
=
10
;
private
static
final
long
DEFAULT_MULTI_EXIT_DISC
=
20
;
// The BGP Session Manager to test
private
BgpSessionManager
bgpSessionManager
;
// Remote Peer state
private
ClientBootstrap
peerBootstrap
;
private
TestBgpPeerChannelHandler
peerChannelHandler
=
new
TestBgpPeerChannelHandler
(
BGP_PEER1_ID
,
DEFAULT_LOCAL_PREF
);
private
TestBgpPeerFrameDecoder
peerFrameDecoder
=
new
TestBgpPeerFrameDecoder
();
// The socket that the Remote Peer should connect to
private
InetSocketAddress
connectToSocket
;
private
final
DummyRouteListener
dummyRouteListener
=
new
DummyRouteListener
();
/**
* Dummy implementation for the RouteListener interface.
*/
private
class
DummyRouteListener
implements
RouteListener
{
@Override
public
void
update
(
RouteUpdate
routeUpdate
)
{
// Nothing to do
}
}
@Before
public
void
setUp
()
throws
Exception
{
//
// Setup the BGP Session Manager to test, and start listening for BGP
// connections.
//
bgpSessionManager
=
new
BgpSessionManager
(
dummyRouteListener
);
// NOTE: We use port 0 to bind on any available port
bgpSessionManager
.
startUp
(
0
);
// Get the port number the BGP Session Manager is listening on
Channel
serverChannel
=
TestUtils
.
getField
(
bgpSessionManager
,
"serverChannel"
);
SocketAddress
socketAddress
=
serverChannel
.
getLocalAddress
();
InetSocketAddress
inetSocketAddress
=
(
InetSocketAddress
)
socketAddress
;
//
// Setup the BGP Peer, i.e., the "remote" BGP router that will
// initiate the BGP connection, send BGP UPDATE messages, etc.
//
ChannelFactory
channelFactory
=
new
NioClientSocketChannelFactory
(
Executors
.
newCachedThreadPool
(),
Executors
.
newCachedThreadPool
());
ChannelPipelineFactory
pipelineFactory
=
new
ChannelPipelineFactory
()
{
@Override
public
ChannelPipeline
getPipeline
()
throws
Exception
{
// Setup the transmitting pipeline
ChannelPipeline
pipeline
=
Channels
.
pipeline
();
pipeline
.
addLast
(
"TestBgpPeerFrameDecoder"
,
peerFrameDecoder
);
pipeline
.
addLast
(
"TestBgpPeerChannelHandler"
,
peerChannelHandler
);
return
pipeline
;
}
};
peerBootstrap
=
new
ClientBootstrap
(
channelFactory
);
peerBootstrap
.
setOption
(
"child.keepAlive"
,
true
);
peerBootstrap
.
setOption
(
"child.tcpNoDelay"
,
true
);
peerBootstrap
.
setPipelineFactory
(
pipelineFactory
);
InetAddress
connectToAddress
=
InetAddresses
.
forString
(
"127.0.0.1"
);
connectToSocket
=
new
InetSocketAddress
(
connectToAddress
,
inetSocketAddress
.
getPort
());
}
@After
public
void
tearDown
()
throws
Exception
{
bgpSessionManager
.
shutDown
();
bgpSessionManager
=
null
;
}
/**
* Gets BGP RIB-IN routes by waiting until they are received.
* <p/>
* NOTE: We keep checking once a second the number of received routes,
* up to 5 seconds.
*
* @param bgpSession the BGP session that is expected to receive the
* routes
* @param expectedRoutes the expected number of routes
* @return the BGP RIB-IN routes as received within the expected
* time interval
*/
private
Collection
<
BgpRouteEntry
>
waitForBgpRibIn
(
BgpSession
bgpSession
,
long
expectedRoutes
)
throws
InterruptedException
{
Collection
<
BgpRouteEntry
>
bgpRibIn
=
bgpSession
.
getBgpRibIn
();
final
int
maxChecks
=
5
;
// Max wait of 5 seconds
for
(
int
i
=
0
;
i
<
maxChecks
;
i
++)
{
if
(
bgpRibIn
.
size
()
==
expectedRoutes
)
{
break
;
}
Thread
.
sleep
(
1000
);
bgpRibIn
=
bgpSession
.
getBgpRibIn
();
}
return
bgpRibIn
;
}
/**
* Gets BGP merged routes by waiting until they are received.
* <p/>
* NOTE: We keep checking once a second the number of received routes,
* up to 5 seconds.
*
* @param expectedRoutes the expected number of routes
* @return the BGP Session Manager routes as received within the expected
* time interval
*/
private
Collection
<
BgpRouteEntry
>
waitForBgpRoutes
(
long
expectedRoutes
)
throws
InterruptedException
{
Collection
<
BgpRouteEntry
>
bgpRoutes
=
bgpSessionManager
.
getBgpRoutes
();
final
int
maxChecks
=
5
;
// Max wait of 5 seconds
for
(
int
i
=
0
;
i
<
maxChecks
;
i
++)
{
if
(
bgpRoutes
.
size
()
==
expectedRoutes
)
{
break
;
}
Thread
.
sleep
(
1000
);
bgpRoutes
=
bgpSessionManager
.
getBgpRoutes
();
}
return
bgpRoutes
;
}
/**
* Tests that the BGP OPEN messages have been exchanged, followed by
* KEEPALIVE.
* <p>
* The BGP Peer opens the sessions and transmits OPEN Message, eventually
* followed by KEEPALIVE. The tested BGP listener should respond by
* OPEN Message, followed by KEEPALIVE.
*
* @throws TestUtilsException TestUtils error
*/
@Test
public
void
testExchangedBgpOpenMessages
()
throws
InterruptedException
,
TestUtilsException
{
// Initiate the connection
peerBootstrap
.
connect
(
connectToSocket
);
// Wait until the OPEN message is received
peerFrameDecoder
.
receivedOpenMessageLatch
.
await
(
2000
,
TimeUnit
.
MILLISECONDS
);
// Wait until the KEEPALIVE message is received
peerFrameDecoder
.
receivedKeepaliveMessageLatch
.
await
(
2000
,
TimeUnit
.
MILLISECONDS
);
//
// Test the fields from the BGP OPEN message:
// BGP version, AS number, BGP ID
//
assertThat
(
peerFrameDecoder
.
remoteBgpVersion
,
is
(
BgpConstants
.
BGP_VERSION
));
assertThat
(
peerFrameDecoder
.
remoteAs
,
is
(
TestBgpPeerChannelHandler
.
PEER_AS
));
assertThat
(
peerFrameDecoder
.
remoteBgpIdentifier
,
is
(
IP_LOOPBACK_ID
));
//
// Test that a BgpSession instance has been created
//
assertThat
(
bgpSessionManager
.
getMyBgpId
(),
is
(
IP_LOOPBACK_ID
));
assertThat
(
bgpSessionManager
.
getBgpSessions
(),
hasSize
(
1
));
BgpSession
bgpSession
=
bgpSessionManager
.
getBgpSessions
().
iterator
().
next
();
assertThat
(
bgpSession
,
notNullValue
());
long
sessionAs
=
TestUtils
.
getField
(
bgpSession
,
"localAs"
);
assertThat
(
sessionAs
,
is
(
TestBgpPeerChannelHandler
.
PEER_AS
));
}
/**
* Tests that the BGP UPDATE messages have been received and processed.
*/
@Test
public
void
testProcessedBgpUpdateMessages
()
throws
InterruptedException
{
BgpSession
bgpSession
;
IpAddress
nextHopRouter
;
BgpRouteEntry
bgpRouteEntry
;
ChannelBuffer
message
;
Collection
<
BgpRouteEntry
>
bgpRibIn
;
Collection
<
BgpRouteEntry
>
bgpRoutes
;
// Initiate the connection
peerBootstrap
.
connect
(
connectToSocket
);
// Wait until the OPEN message is received
peerFrameDecoder
.
receivedOpenMessageLatch
.
await
(
2000
,
TimeUnit
.
MILLISECONDS
);
// Wait until the KEEPALIVE message is received
peerFrameDecoder
.
receivedKeepaliveMessageLatch
.
await
(
2000
,
TimeUnit
.
MILLISECONDS
);
// Get the BGP Session handler
bgpSession
=
bgpSessionManager
.
getBgpSessions
().
iterator
().
next
();
// Prepare routes to add/delete
nextHopRouter
=
IpAddress
.
valueOf
(
"10.20.30.40"
);
Collection
<
IpPrefix
>
addedRoutes
=
new
LinkedList
<>();
Collection
<
IpPrefix
>
withdrawnRoutes
=
new
LinkedList
<>();
addedRoutes
.
add
(
IpPrefix
.
valueOf
(
"0.0.0.0/0"
));
addedRoutes
.
add
(
IpPrefix
.
valueOf
(
"20.0.0.0/8"
));
addedRoutes
.
add
(
IpPrefix
.
valueOf
(
"30.0.0.0/16"
));
addedRoutes
.
add
(
IpPrefix
.
valueOf
(
"40.0.0.0/24"
));
addedRoutes
.
add
(
IpPrefix
.
valueOf
(
"50.0.0.0/32"
));
withdrawnRoutes
.
add
(
IpPrefix
.
valueOf
(
"60.0.0.0/8"
));
withdrawnRoutes
.
add
(
IpPrefix
.
valueOf
(
"70.0.0.0/16"
));
withdrawnRoutes
.
add
(
IpPrefix
.
valueOf
(
"80.0.0.0/24"
));
withdrawnRoutes
.
add
(
IpPrefix
.
valueOf
(
"90.0.0.0/32"
));
// Write the routes
message
=
peerChannelHandler
.
prepareBgpUpdate
(
nextHopRouter
,
addedRoutes
,
withdrawnRoutes
);
peerChannelHandler
.
savedCtx
.
getChannel
().
write
(
message
);
// Check that the routes have been received, processed and stored
bgpRibIn
=
waitForBgpRibIn
(
bgpSession
,
5
);
assertThat
(
bgpRibIn
,
hasSize
(
5
));
bgpRoutes
=
waitForBgpRoutes
(
5
);
assertThat
(
bgpRoutes
,
hasSize
(
5
));
// Setup the AS Path
ArrayList
<
BgpRouteEntry
.
PathSegment
>
pathSegments
=
new
ArrayList
<>();
byte
pathSegmentType1
=
(
byte
)
BgpConstants
.
Update
.
AsPath
.
AS_SEQUENCE
;
ArrayList
<
Long
>
segmentAsNumbers1
=
new
ArrayList
<>();
segmentAsNumbers1
.
add
((
long
)
65010
);
segmentAsNumbers1
.
add
((
long
)
65020
);
segmentAsNumbers1
.
add
((
long
)
65030
);
BgpRouteEntry
.
PathSegment
pathSegment1
=
new
BgpRouteEntry
.
PathSegment
(
pathSegmentType1
,
segmentAsNumbers1
);
pathSegments
.
add
(
pathSegment1
);
//
byte
pathSegmentType2
=
(
byte
)
BgpConstants
.
Update
.
AsPath
.
AS_SET
;
ArrayList
<
Long
>
segmentAsNumbers2
=
new
ArrayList
<>();
segmentAsNumbers2
.
add
((
long
)
65041
);
segmentAsNumbers2
.
add
((
long
)
65042
);
segmentAsNumbers2
.
add
((
long
)
65043
);
BgpRouteEntry
.
PathSegment
pathSegment2
=
new
BgpRouteEntry
.
PathSegment
(
pathSegmentType2
,
segmentAsNumbers2
);
pathSegments
.
add
(
pathSegment2
);
//
BgpRouteEntry
.
AsPath
asPath
=
new
BgpRouteEntry
.
AsPath
(
pathSegments
);
//
bgpRouteEntry
=
new
BgpRouteEntry
(
bgpSession
,
IpPrefix
.
valueOf
(
"0.0.0.0/0"
),
nextHopRouter
,
(
byte
)
BgpConstants
.
Update
.
Origin
.
IGP
,
asPath
,
DEFAULT_LOCAL_PREF
);
bgpRouteEntry
.
setMultiExitDisc
(
DEFAULT_MULTI_EXIT_DISC
);
assertThat
(
bgpRibIn
,
hasItem
(
bgpRouteEntry
));
//
bgpRouteEntry
=
new
BgpRouteEntry
(
bgpSession
,
IpPrefix
.
valueOf
(
"20.0.0.0/8"
),
nextHopRouter
,
(
byte
)
BgpConstants
.
Update
.
Origin
.
IGP
,
asPath
,
DEFAULT_LOCAL_PREF
);
bgpRouteEntry
.
setMultiExitDisc
(
DEFAULT_MULTI_EXIT_DISC
);
assertThat
(
bgpRibIn
,
hasItem
(
bgpRouteEntry
));
//
bgpRouteEntry
=
new
BgpRouteEntry
(
bgpSession
,
IpPrefix
.
valueOf
(
"30.0.0.0/16"
),
nextHopRouter
,
(
byte
)
BgpConstants
.
Update
.
Origin
.
IGP
,
asPath
,
DEFAULT_LOCAL_PREF
);
bgpRouteEntry
.
setMultiExitDisc
(
DEFAULT_MULTI_EXIT_DISC
);
assertThat
(
bgpRibIn
,
hasItem
(
bgpRouteEntry
));
//
bgpRouteEntry
=
new
BgpRouteEntry
(
bgpSession
,
IpPrefix
.
valueOf
(
"40.0.0.0/24"
),
nextHopRouter
,
(
byte
)
BgpConstants
.
Update
.
Origin
.
IGP
,
asPath
,
DEFAULT_LOCAL_PREF
);
bgpRouteEntry
.
setMultiExitDisc
(
DEFAULT_MULTI_EXIT_DISC
);
assertThat
(
bgpRibIn
,
hasItem
(
bgpRouteEntry
));
//
bgpRouteEntry
=
new
BgpRouteEntry
(
bgpSession
,
IpPrefix
.
valueOf
(
"50.0.0.0/32"
),
nextHopRouter
,
(
byte
)
BgpConstants
.
Update
.
Origin
.
IGP
,
asPath
,
DEFAULT_LOCAL_PREF
);
bgpRouteEntry
.
setMultiExitDisc
(
DEFAULT_MULTI_EXIT_DISC
);
assertThat
(
bgpRibIn
,
hasItem
(
bgpRouteEntry
));
// Delete some routes
addedRoutes
=
new
LinkedList
<>();
withdrawnRoutes
=
new
LinkedList
<>();
withdrawnRoutes
.
add
(
IpPrefix
.
valueOf
(
"0.0.0.0/0"
));
withdrawnRoutes
.
add
(
IpPrefix
.
valueOf
(
"50.0.0.0/32"
));
// Write the routes
message
=
peerChannelHandler
.
prepareBgpUpdate
(
nextHopRouter
,
addedRoutes
,
withdrawnRoutes
);
peerChannelHandler
.
savedCtx
.
getChannel
().
write
(
message
);
// Check that the routes have been received, processed and stored
bgpRibIn
=
waitForBgpRibIn
(
bgpSession
,
3
);
assertThat
(
bgpRibIn
,
hasSize
(
3
));
bgpRoutes
=
waitForBgpRoutes
(
3
);
assertThat
(
bgpRoutes
,
hasSize
(
3
));
//
bgpRouteEntry
=
new
BgpRouteEntry
(
bgpSession
,
IpPrefix
.
valueOf
(
"20.0.0.0/8"
),
nextHopRouter
,
(
byte
)
BgpConstants
.
Update
.
Origin
.
IGP
,
asPath
,
DEFAULT_LOCAL_PREF
);
bgpRouteEntry
.
setMultiExitDisc
(
DEFAULT_MULTI_EXIT_DISC
);
assertThat
(
bgpRibIn
,
hasItem
(
bgpRouteEntry
));
//
bgpRouteEntry
=
new
BgpRouteEntry
(
bgpSession
,
IpPrefix
.
valueOf
(
"30.0.0.0/16"
),
nextHopRouter
,
(
byte
)
BgpConstants
.
Update
.
Origin
.
IGP
,
asPath
,
DEFAULT_LOCAL_PREF
);
bgpRouteEntry
.
setMultiExitDisc
(
DEFAULT_MULTI_EXIT_DISC
);
assertThat
(
bgpRibIn
,
hasItem
(
bgpRouteEntry
));
//
bgpRouteEntry
=
new
BgpRouteEntry
(
bgpSession
,
IpPrefix
.
valueOf
(
"40.0.0.0/24"
),
nextHopRouter
,
(
byte
)
BgpConstants
.
Update
.
Origin
.
IGP
,
asPath
,
DEFAULT_LOCAL_PREF
);
bgpRouteEntry
.
setMultiExitDisc
(
DEFAULT_MULTI_EXIT_DISC
);
assertThat
(
bgpRibIn
,
hasItem
(
bgpRouteEntry
));
// Close the channel and test there are no routes
peerChannelHandler
.
closeChannel
();
bgpRoutes
=
waitForBgpRoutes
(
0
);
assertThat
(
bgpRoutes
,
hasSize
(
0
));
}
}
apps/sdnip/src/test/java/org/onlab/onos/sdnip/bgp/PathSegmentTest.java
0 → 100644
View file @
eada071
package
org
.
onlab
.
onos
.
sdnip
.
bgp
;
import
static
org
.
hamcrest
.
Matchers
.
is
;
import
static
org
.
hamcrest
.
Matchers
.
not
;
import
static
org
.
junit
.
Assert
.
assertThat
;
import
java.util.ArrayList
;
import
org.junit.Test
;
/**
* Unit tests for the BgpRouteEntry.PathSegment class.
*/
public
class
PathSegmentTest
{
/**
* Generates a Path Segment.
*
* @return a generated PathSegment
*/
private
BgpRouteEntry
.
PathSegment
generatePathSegment
()
{
byte
pathSegmentType
=
(
byte
)
BgpConstants
.
Update
.
AsPath
.
AS_SEQUENCE
;
ArrayList
<
Long
>
segmentAsNumbers
=
new
ArrayList
<>();
segmentAsNumbers
.
add
((
long
)
1
);
segmentAsNumbers
.
add
((
long
)
2
);
segmentAsNumbers
.
add
((
long
)
3
);
BgpRouteEntry
.
PathSegment
pathSegment
=
new
BgpRouteEntry
.
PathSegment
(
pathSegmentType
,
segmentAsNumbers
);
return
pathSegment
;
}
/**
* Tests valid class constructor.
*/
@Test
public
void
testConstructor
()
{
BgpRouteEntry
.
PathSegment
pathSegment
=
generatePathSegment
();
String
expectedString
=
"PathSegment{type=2, segmentAsNumbers=[1, 2, 3]}"
;
assertThat
(
pathSegment
.
toString
(),
is
(
expectedString
));
}
/**
* Tests invalid class constructor for null Segment AS Numbers.
*/
@Test
(
expected
=
NullPointerException
.
class
)
public
void
testInvalidConstructorNullSegmentAsNumbers
()
{
byte
pathSegmentType
=
(
byte
)
BgpConstants
.
Update
.
AsPath
.
AS_SEQUENCE
;
ArrayList
<
Long
>
segmentAsNumbers
=
null
;
new
BgpRouteEntry
.
PathSegment
(
pathSegmentType
,
segmentAsNumbers
);
}
/**
* Tests getting the fields of a Path Segment.
*/
@Test
public
void
testGetFields
()
{
// Create the fields to compare against
byte
pathSegmentType
=
(
byte
)
BgpConstants
.
Update
.
AsPath
.
AS_SEQUENCE
;
ArrayList
<
Long
>
segmentAsNumbers
=
new
ArrayList
<>();
segmentAsNumbers
.
add
((
long
)
1
);
segmentAsNumbers
.
add
((
long
)
2
);
segmentAsNumbers
.
add
((
long
)
3
);
// Generate the entry to test
BgpRouteEntry
.
PathSegment
pathSegment
=
generatePathSegment
();
assertThat
(
pathSegment
.
getType
(),
is
(
pathSegmentType
));
assertThat
(
pathSegment
.
getSegmentAsNumbers
(),
is
(
segmentAsNumbers
));
}
/**
* Tests equality of {@link BgpRouteEntry.PathSegment}.
*/
@Test
public
void
testEquality
()
{
BgpRouteEntry
.
PathSegment
pathSegment1
=
generatePathSegment
();
BgpRouteEntry
.
PathSegment
pathSegment2
=
generatePathSegment
();
assertThat
(
pathSegment1
,
is
(
pathSegment2
));
}
/**
* Tests non-equality of {@link BgpRouteEntry.PathSegment}.
*/
@Test
public
void
testNonEquality
()
{
BgpRouteEntry
.
PathSegment
pathSegment1
=
generatePathSegment
();
// Setup Path Segment 2
byte
pathSegmentType
=
(
byte
)
BgpConstants
.
Update
.
AsPath
.
AS_SEQUENCE
;
ArrayList
<
Long
>
segmentAsNumbers
=
new
ArrayList
<>();
segmentAsNumbers
.
add
((
long
)
1
);
segmentAsNumbers
.
add
((
long
)
22
);
// Different
segmentAsNumbers
.
add
((
long
)
3
);
//
BgpRouteEntry
.
PathSegment
pathSegment2
=
new
BgpRouteEntry
.
PathSegment
(
pathSegmentType
,
segmentAsNumbers
);
assertThat
(
pathSegment1
,
is
(
not
(
pathSegment2
)));
}
/**
* Tests object string representation.
*/
@Test
public
void
testToString
()
{
BgpRouteEntry
.
PathSegment
pathSegment
=
generatePathSegment
();
String
expectedString
=
"PathSegment{type=2, segmentAsNumbers=[1, 2, 3]}"
;
assertThat
(
pathSegment
.
toString
(),
is
(
expectedString
));
}
}
apps/sdnip/src/test/java/org/onlab/onos/sdnip/bgp/TestBgpPeerChannelHandler.java
0 → 100644
View file @
eada071
package
org
.
onlab
.
onos
.
sdnip
.
bgp
;
import
java.util.Collection
;
import
org.jboss.netty.buffer.ChannelBuffer
;
import
org.jboss.netty.buffer.ChannelBuffers
;
import
org.jboss.netty.channel.ChannelHandlerContext
;
import
org.jboss.netty.channel.ChannelStateEvent
;
import
org.jboss.netty.channel.SimpleChannelHandler
;
import
org.onlab.packet.IpAddress
;
import
org.onlab.packet.IpPrefix
;
/**
* Class for handling the remote BGP Peer session.
*/
class
TestBgpPeerChannelHandler
extends
SimpleChannelHandler
{
static
final
long
PEER_AS
=
65001
;
static
final
int
PEER_HOLDTIME
=
120
;
// 120 seconds
final
IpAddress
bgpId
;
// The BGP ID
final
long
localPref
;
// Local preference for routes
final
long
multiExitDisc
=
20
;
// MED value
ChannelHandlerContext
savedCtx
;
/**
* Constructor for given BGP ID.
*
* @param bgpId the BGP ID to use
* @param localPref the local preference for the routes to use
*/
TestBgpPeerChannelHandler
(
IpAddress
bgpId
,
long
localPref
)
{
this
.
bgpId
=
bgpId
;
this
.
localPref
=
localPref
;
}
/**
* Closes the channel.
*/
void
closeChannel
()
{
savedCtx
.
getChannel
().
close
();
}
@Override
public
void
channelConnected
(
ChannelHandlerContext
ctx
,
ChannelStateEvent
channelEvent
)
{
this
.
savedCtx
=
ctx
;
// Prepare and transmit BGP OPEN message
ChannelBuffer
message
=
prepareBgpOpen
();
ctx
.
getChannel
().
write
(
message
);
// Prepare and transmit BGP KEEPALIVE message
message
=
prepareBgpKeepalive
();
ctx
.
getChannel
().
write
(
message
);
}
@Override
public
void
channelDisconnected
(
ChannelHandlerContext
ctx
,
ChannelStateEvent
channelEvent
)
{
// Nothing to do
}
/**
* Prepares BGP OPEN message.
*
* @return the message to transmit (BGP header included)
*/
ChannelBuffer
prepareBgpOpen
()
{
ChannelBuffer
message
=
ChannelBuffers
.
buffer
(
BgpConstants
.
BGP_MESSAGE_MAX_LENGTH
);
message
.
writeByte
(
BgpConstants
.
BGP_VERSION
);
message
.
writeShort
((
int
)
PEER_AS
);
message
.
writeShort
(
PEER_HOLDTIME
);
message
.
writeInt
(
bgpId
.
toInt
());
message
.
writeByte
(
0
);
// No Optional Parameters
return
prepareBgpMessage
(
BgpConstants
.
BGP_TYPE_OPEN
,
message
);
}
/**
* Prepares BGP UPDATE message.
*
* @param nextHopRouter the next-hop router address for the routes to add
* @param addedRoutes the routes to add
* @param withdrawnRoutes the routes to withdraw
* @return the message to transmit (BGP header included)
*/
ChannelBuffer
prepareBgpUpdate
(
IpAddress
nextHopRouter
,
Collection
<
IpPrefix
>
addedRoutes
,
Collection
<
IpPrefix
>
withdrawnRoutes
)
{
int
attrFlags
;
ChannelBuffer
message
=
ChannelBuffers
.
buffer
(
BgpConstants
.
BGP_MESSAGE_MAX_LENGTH
);
ChannelBuffer
pathAttributes
=
ChannelBuffers
.
buffer
(
BgpConstants
.
BGP_MESSAGE_MAX_LENGTH
);
// Encode the Withdrawn Routes
ChannelBuffer
encodedPrefixes
=
encodePackedPrefixes
(
withdrawnRoutes
);
message
.
writeShort
(
encodedPrefixes
.
readableBytes
());
message
.
writeBytes
(
encodedPrefixes
);
// Encode the Path Attributes
// ORIGIN: IGP
attrFlags
=
0x40
;
// Transitive flag
pathAttributes
.
writeByte
(
attrFlags
);
pathAttributes
.
writeByte
(
BgpConstants
.
Update
.
Origin
.
TYPE
);
pathAttributes
.
writeByte
(
1
);
// Data length
pathAttributes
.
writeByte
(
BgpConstants
.
Update
.
Origin
.
IGP
);
// AS_PATH: Two Path Segments of 3 ASes each
attrFlags
=
0x40
;
// Transitive flag
pathAttributes
.
writeByte
(
attrFlags
);
pathAttributes
.
writeByte
(
BgpConstants
.
Update
.
AsPath
.
TYPE
);
pathAttributes
.
writeByte
(
16
);
// Data length
byte
pathSegmentType1
=
(
byte
)
BgpConstants
.
Update
.
AsPath
.
AS_SEQUENCE
;
pathAttributes
.
writeByte
(
pathSegmentType1
);
pathAttributes
.
writeByte
(
3
);
// Three ASes
pathAttributes
.
writeShort
(
65010
);
// AS=65010
pathAttributes
.
writeShort
(
65020
);
// AS=65020
pathAttributes
.
writeShort
(
65030
);
// AS=65030
byte
pathSegmentType2
=
(
byte
)
BgpConstants
.
Update
.
AsPath
.
AS_SET
;
pathAttributes
.
writeByte
(
pathSegmentType2
);
pathAttributes
.
writeByte
(
3
);
// Three ASes
pathAttributes
.
writeShort
(
65041
);
// AS=65041
pathAttributes
.
writeShort
(
65042
);
// AS=65042
pathAttributes
.
writeShort
(
65043
);
// AS=65043
// NEXT_HOP: nextHopRouter
attrFlags
=
0x40
;
// Transitive flag
pathAttributes
.
writeByte
(
attrFlags
);
pathAttributes
.
writeByte
(
BgpConstants
.
Update
.
NextHop
.
TYPE
);
pathAttributes
.
writeByte
(
4
);
// Data length
pathAttributes
.
writeInt
(
nextHopRouter
.
toInt
());
// Next-hop router
// LOCAL_PREF: localPref
attrFlags
=
0x40
;
// Transitive flag
pathAttributes
.
writeByte
(
attrFlags
);
pathAttributes
.
writeByte
(
BgpConstants
.
Update
.
LocalPref
.
TYPE
);
pathAttributes
.
writeByte
(
4
);
// Data length
pathAttributes
.
writeInt
((
int
)
localPref
);
// Preference value
// MULTI_EXIT_DISC: multiExitDisc
attrFlags
=
0x80
;
// Optional
// Non-Transitive flag
pathAttributes
.
writeByte
(
attrFlags
);
pathAttributes
.
writeByte
(
BgpConstants
.
Update
.
MultiExitDisc
.
TYPE
);
pathAttributes
.
writeByte
(
4
);
// Data length
pathAttributes
.
writeInt
((
int
)
multiExitDisc
);
// Preference value
// The NLRI prefixes
encodedPrefixes
=
encodePackedPrefixes
(
addedRoutes
);
// Write the Path Attributes, beginning with its length
message
.
writeShort
(
pathAttributes
.
readableBytes
());
message
.
writeBytes
(
pathAttributes
);
message
.
writeBytes
(
encodedPrefixes
);
return
prepareBgpMessage
(
BgpConstants
.
BGP_TYPE_UPDATE
,
message
);
}
/**
* Encodes a collection of IPv4 network prefixes in a packed format.
* <p>
* The IPv4 prefixes are encoded in the form:
* <Length, Prefix> where Length is the length in bits of the IPv4 prefix,
* and Prefix is the IPv4 prefix (padded with trailing bits to the end
* of an octet).
*
* @param prefixes the prefixes to encode
* @return the buffer with the encoded prefixes
*/
private
ChannelBuffer
encodePackedPrefixes
(
Collection
<
IpPrefix
>
prefixes
)
{
ChannelBuffer
message
=
ChannelBuffers
.
buffer
(
BgpConstants
.
BGP_MESSAGE_MAX_LENGTH
);
// Write each of the prefixes
for
(
IpPrefix
prefix
:
prefixes
)
{
int
prefixBitlen
=
prefix
.
prefixLength
();
int
prefixBytelen
=
(
prefixBitlen
+
7
)
/
8
;
// Round-up
message
.
writeByte
(
prefixBitlen
);
IpAddress
address
=
prefix
.
toIpAddress
();
long
value
=
address
.
toInt
()
&
0xffffffff
L
;
for
(
int
i
=
0
;
i
<
IpAddress
.
INET_LEN
;
i
++)
{
if
(
prefixBytelen
--
==
0
)
{
break
;
}
long
nextByte
=
(
value
>>
((
IpAddress
.
INET_LEN
-
i
-
1
)
*
8
))
&
0xff
;
message
.
writeByte
((
int
)
nextByte
);
}
}
return
message
;
}
/**
* Prepares BGP KEEPALIVE message.
*
* @return the message to transmit (BGP header included)
*/
ChannelBuffer
prepareBgpKeepalive
()
{
ChannelBuffer
message
=
ChannelBuffers
.
buffer
(
BgpConstants
.
BGP_MESSAGE_MAX_LENGTH
);
return
prepareBgpMessage
(
BgpConstants
.
BGP_TYPE_KEEPALIVE
,
message
);
}
/**
* Prepares BGP NOTIFICATION message.
*
* @param errorCode the BGP NOTIFICATION Error Code
* @param errorSubcode the BGP NOTIFICATION Error Subcode if applicable,
* otherwise BgpConstants.Notifications.ERROR_SUBCODE_UNSPECIFIC
* @param payload the BGP NOTIFICATION Data if applicable, otherwise null
* @return the message to transmit (BGP header included)
*/
ChannelBuffer
prepareBgpNotification
(
int
errorCode
,
int
errorSubcode
,
ChannelBuffer
data
)
{
ChannelBuffer
message
=
ChannelBuffers
.
buffer
(
BgpConstants
.
BGP_MESSAGE_MAX_LENGTH
);
// Prepare the NOTIFICATION message payload
message
.
writeByte
(
errorCode
);
message
.
writeByte
(
errorSubcode
);
if
(
data
!=
null
)
{
message
.
writeBytes
(
data
);
}
return
prepareBgpMessage
(
BgpConstants
.
BGP_TYPE_NOTIFICATION
,
message
);
}
/**
* Prepares BGP message.
*
* @param type the BGP message type
* @param payload the message payload to transmit (BGP header excluded)
* @return the message to transmit (BGP header included)
*/
private
ChannelBuffer
prepareBgpMessage
(
int
type
,
ChannelBuffer
payload
)
{
ChannelBuffer
message
=
ChannelBuffers
.
buffer
(
BgpConstants
.
BGP_HEADER_LENGTH
+
payload
.
readableBytes
());
// Write the marker
for
(
int
i
=
0
;
i
<
BgpConstants
.
BGP_HEADER_MARKER_LENGTH
;
i
++)
{
message
.
writeByte
(
0xff
);
}
// Write the rest of the BGP header
message
.
writeShort
(
BgpConstants
.
BGP_HEADER_LENGTH
+
payload
.
readableBytes
());
message
.
writeByte
(
type
);
// Write the payload
message
.
writeBytes
(
payload
);
return
message
;
}
}
apps/sdnip/src/test/java/org/onlab/onos/sdnip/bgp/TestBgpPeerFrameDecoder.java
0 → 100644
View file @
eada071
package
org
.
onlab
.
onos
.
sdnip
.
bgp
;
import
java.util.concurrent.CountDownLatch
;
import
org.jboss.netty.buffer.ChannelBuffer
;
import
org.jboss.netty.channel.Channel
;
import
org.jboss.netty.channel.ChannelHandlerContext
;
import
org.jboss.netty.handler.codec.frame.FrameDecoder
;
import
org.onlab.packet.IpAddress
;
/**
* Class for handling the decoding of the BGP messages at the remote
* BGP peer session.
*/
class
TestBgpPeerFrameDecoder
extends
FrameDecoder
{
int
remoteBgpVersion
;
// 1 octet
long
remoteAs
;
// 2 octets
long
remoteHoldtime
;
// 2 octets
IpAddress
remoteBgpIdentifier
;
// 4 octets -> IPv4 address
final
CountDownLatch
receivedOpenMessageLatch
=
new
CountDownLatch
(
1
);
final
CountDownLatch
receivedKeepaliveMessageLatch
=
new
CountDownLatch
(
1
);
@Override
protected
Object
decode
(
ChannelHandlerContext
ctx
,
Channel
channel
,
ChannelBuffer
buf
)
throws
Exception
{
// Test for minimum length of the BGP message
if
(
buf
.
readableBytes
()
<
BgpConstants
.
BGP_HEADER_LENGTH
)
{
// No enough data received
return
null
;
}
//
// Mark the current buffer position in case we haven't received
// the whole message.
//
buf
.
markReaderIndex
();
//
// Read and check the BGP message Marker field: it must be all ones
//
byte
[]
marker
=
new
byte
[
BgpConstants
.
BGP_HEADER_MARKER_LENGTH
];
buf
.
readBytes
(
marker
);
for
(
int
i
=
0
;
i
<
marker
.
length
;
i
++)
{
if
(
marker
[
i
]
!=
(
byte
)
0xff
)
{
// ERROR: Connection Not Synchronized. Close the channel.
ctx
.
getChannel
().
close
();
return
null
;
}
}
//
// Read and check the BGP message Length field
//
int
length
=
buf
.
readUnsignedShort
();
if
((
length
<
BgpConstants
.
BGP_HEADER_LENGTH
)
||
(
length
>
BgpConstants
.
BGP_MESSAGE_MAX_LENGTH
))
{
// ERROR: Bad Message Length. Close the channel.
ctx
.
getChannel
().
close
();
return
null
;
}
//
// Test whether the rest of the message is received:
// So far we have read the Marker (16 octets) and the
// Length (2 octets) fields.
//
int
remainingMessageLen
=
length
-
BgpConstants
.
BGP_HEADER_MARKER_LENGTH
-
2
;
if
(
buf
.
readableBytes
()
<
remainingMessageLen
)
{
// No enough data received
buf
.
resetReaderIndex
();
return
null
;
}
//
// Read the BGP message Type field, and process based on that type
//
int
type
=
buf
.
readUnsignedByte
();
remainingMessageLen
--;
// Adjust after reading the type
ChannelBuffer
message
=
buf
.
readBytes
(
remainingMessageLen
);
//
// Process the remaining of the message based on the message type
//
switch
(
type
)
{
case
BgpConstants
.
BGP_TYPE_OPEN
:
processBgpOpen
(
ctx
,
message
);
break
;
case
BgpConstants
.
BGP_TYPE_UPDATE
:
// NOTE: Not used as part of the test, because ONOS does not
// originate UPDATE messages.
break
;
case
BgpConstants
.
BGP_TYPE_NOTIFICATION
:
// NOTE: Not used as part of the testing (yet)
break
;
case
BgpConstants
.
BGP_TYPE_KEEPALIVE
:
processBgpKeepalive
(
ctx
,
message
);
break
;
default
:
// ERROR: Bad Message Type. Close the channel.
ctx
.
getChannel
().
close
();
return
null
;
}
return
null
;
}
/**
* Processes BGP OPEN message.
*
* @param ctx the Channel Handler Context.
* @param message the message to process.
*/
private
void
processBgpOpen
(
ChannelHandlerContext
ctx
,
ChannelBuffer
message
)
{
int
minLength
=
BgpConstants
.
BGP_OPEN_MIN_LENGTH
-
BgpConstants
.
BGP_HEADER_LENGTH
;
if
(
message
.
readableBytes
()
<
minLength
)
{
// ERROR: Bad Message Length. Close the channel.
ctx
.
getChannel
().
close
();
return
;
}
//
// Parse the OPEN message
//
remoteBgpVersion
=
message
.
readUnsignedByte
();
remoteAs
=
message
.
readUnsignedShort
();
remoteHoldtime
=
message
.
readUnsignedShort
();
remoteBgpIdentifier
=
IpAddress
.
valueOf
((
int
)
message
.
readUnsignedInt
());
// Optional Parameters
int
optParamLen
=
message
.
readUnsignedByte
();
if
(
message
.
readableBytes
()
<
optParamLen
)
{
// ERROR: Bad Message Length. Close the channel.
ctx
.
getChannel
().
close
();
return
;
}
message
.
readBytes
(
optParamLen
);
// NOTE: data ignored
// BGP OPEN message successfully received
receivedOpenMessageLatch
.
countDown
();
}
/**
* Processes BGP KEEPALIVE message.
*
* @param ctx the Channel Handler Context.
* @param message the message to process.
*/
private
void
processBgpKeepalive
(
ChannelHandlerContext
ctx
,
ChannelBuffer
message
)
{
if
(
message
.
readableBytes
()
+
BgpConstants
.
BGP_HEADER_LENGTH
!=
BgpConstants
.
BGP_KEEPALIVE_EXPECTED_LENGTH
)
{
// ERROR: Bad Message Length. Close the channel.
ctx
.
getChannel
().
close
();
return
;
}
// BGP KEEPALIVE message successfully received
receivedKeepaliveMessageLatch
.
countDown
();
}
}
utils/misc/src/main/java/org/onlab/util/TestUtils.java
0 → 100644
View file @
eada071
package
org
.
onlab
.
util
;
import
java.lang.reflect.Constructor
;
import
java.lang.reflect.Field
;
import
java.lang.reflect.InvocationTargetException
;
import
java.lang.reflect.Method
;
/**
* Utilities for testing.
*/
public
final
class
TestUtils
{
/**
* Sets the field, bypassing scope restriction.
*
* @param subject Object where the field belongs
* @param fieldName name of the field to set
* @param value value to set to the field.
* @param <T> subject type
* @param <U> value type
* @throws TestUtilsException if there are reflection errors while setting
* the field
*/
public
static
<
T
,
U
>
void
setField
(
T
subject
,
String
fieldName
,
U
value
)
throws
TestUtilsException
{
@SuppressWarnings
(
"unchecked"
)
Class
<
T
>
clazz
=
(
Class
<
T
>)
subject
.
getClass
();
try
{
Field
field
=
clazz
.
getDeclaredField
(
fieldName
);
field
.
setAccessible
(
true
);
field
.
set
(
subject
,
value
);
}
catch
(
NoSuchFieldException
|
SecurityException
|
IllegalArgumentException
|
IllegalAccessException
e
)
{
throw
new
TestUtilsException
(
"setField failed"
,
e
);
}
}
/**
* Gets the field, bypassing scope restriction.
*
* @param subject Object where the field belongs
* @param fieldName name of the field to get
* @return value of the field.
* @param <T> subject type
* @param <U> field value type
* @throws TestUtilsException if there are reflection errors while getting
* the field
*/
public
static
<
T
,
U
>
U
getField
(
T
subject
,
String
fieldName
)
throws
TestUtilsException
{
try
{
@SuppressWarnings
(
"unchecked"
)
Class
<
T
>
clazz
=
(
Class
<
T
>)
subject
.
getClass
();
Field
field
=
clazz
.
getDeclaredField
(
fieldName
);
field
.
setAccessible
(
true
);
@SuppressWarnings
(
"unchecked"
)
U
result
=
(
U
)
field
.
get
(
subject
);
return
result
;
}
catch
(
NoSuchFieldException
|
SecurityException
|
IllegalArgumentException
|
IllegalAccessException
e
)
{
throw
new
TestUtilsException
(
"getField failed"
,
e
);
}
}
/**
* Calls the method, bypassing scope restriction.
*
* @param subject Object where the method belongs
* @param methodName name of the method to call
* @param paramTypes formal parameter type array
* @param args arguments
* @return return value or null if void
* @param <T> subject type
* @param <U> return value type
* @throws TestUtilsException if there are reflection errors while calling
* the method
*/
public
static
<
T
,
U
>
U
callMethod
(
T
subject
,
String
methodName
,
Class
<?>[]
paramTypes
,
Object
...
args
)
throws
TestUtilsException
{
try
{
@SuppressWarnings
(
"unchecked"
)
Class
<
T
>
clazz
=
(
Class
<
T
>)
subject
.
getClass
();
final
Method
method
;
if
(
paramTypes
==
null
||
paramTypes
.
length
==
0
)
{
method
=
clazz
.
getDeclaredMethod
(
methodName
);
}
else
{
method
=
clazz
.
getDeclaredMethod
(
methodName
,
paramTypes
);
}
method
.
setAccessible
(
true
);
@SuppressWarnings
(
"unchecked"
)
U
result
=
(
U
)
method
.
invoke
(
subject
,
args
);
return
result
;
}
catch
(
NoSuchMethodException
|
SecurityException
|
IllegalAccessException
|
IllegalArgumentException
|
InvocationTargetException
e
)
{
throw
new
TestUtilsException
(
"callMethod failed"
,
e
);
}
}
/**
* Calls the method, bypassing scope restriction.
*
* @param subject Object where the method belongs
* @param methodName name of the method to call
* @param paramType formal parameter type
* @param arg argument
* @return return value or null if void
* @param <T> subject type
* @param <U> return value type
* @throws TestUtilsException if there are reflection errors while calling
* the method
*/
public
static
<
T
,
U
>
U
callMethod
(
T
subject
,
String
methodName
,
Class
<?>
paramType
,
Object
arg
)
throws
TestUtilsException
{
return
callMethod
(
subject
,
methodName
,
new
Class
<?>[]{
paramType
},
arg
);
}
/**
* Triggers an allocation of an object of type <T> and forces a call to
* the private constructor.
*
* @param constructor Constructor to call
* @param <T> type of the object to create
* @return created object of type <T>
* @throws TestUtilsException if there are reflection errors while calling
* the constructor
*/
public
static
<
T
>
T
callConstructor
(
Constructor
<
T
>
constructor
)
throws
TestUtilsException
{
try
{
constructor
.
setAccessible
(
true
);
return
constructor
.
newInstance
();
}
catch
(
InstantiationException
|
IllegalAccessException
|
InvocationTargetException
error
)
{
throw
new
TestUtilsException
(
"callConstructor failed"
,
error
);
}
}
/**
* Avoid instantiation.
*/
private
TestUtils
()
{}
/**
* Exception that can be thrown if problems are encountered while executing
* the utility method. These are usually problems accessing fields/methods
* through reflection. The original exception can be found by examining the
* cause.
*/
public
static
class
TestUtilsException
extends
Exception
{
private
static
final
long
serialVersionUID
=
1L
;
/**
* Constructs a new exception with the specified detail message and
* cause.
*
* @param message the detail message
* @param cause the original cause of this exception
*/
public
TestUtilsException
(
String
message
,
Throwable
cause
)
{
super
(
message
,
cause
);
}
}
}
utils/misc/src/test/java/org/onlab/util/TestUtilsTest.java
0 → 100644
View file @
eada071
package
org
.
onlab
.
util
;
import
static
org
.
junit
.
Assert
.
assertArrayEquals
;
import
static
org
.
junit
.
Assert
.
assertEquals
;
import
static
org
.
junit
.
Assert
.
assertNull
;
import
org.junit.Before
;
import
org.junit.Test
;
import
org.onlab.util.TestUtils.TestUtilsException
;
/**
* Test and usage examples for TestUtils.
*/
public
class
TestUtilsTest
{
/**
* Test data.
*/
private
static
final
class
TestClass
{
@SuppressWarnings
(
"unused"
)
private
int
privateField
=
42
;
@SuppressWarnings
(
"unused"
)
protected
int
protectedField
=
2501
;
// CHECKSTYLE IGNORE THIS LINE
/**
* Protected method with multiple argument.
*
* @param x simply returns
* @param y not used
* @return x
*/
@SuppressWarnings
(
"unused"
)
private
int
privateMethod
(
Number
x
,
Long
y
)
{
return
x
.
intValue
();
}
/**
* Protected method with no argument.
*
* @return int
*/
@SuppressWarnings
(
"unused"
)
protected
int
protectedMethod
()
{
return
42
;
}
/**
* Method returning array.
*
* @param ary random array
* @return ary
*/
@SuppressWarnings
(
"unused"
)
private
int
[]
arrayReturnMethod
(
int
[]
ary
)
{
return
ary
;
}
/**
* Method without return value.
*
* @param s ignored
*/
@SuppressWarnings
(
"unused"
)
private
void
voidMethod
(
String
s
)
{
System
.
out
.
println
(
s
);
}
}
private
TestClass
test
;
/**
* Sets up the test fixture.
*/
@Before
public
void
setUp
()
{
test
=
new
TestClass
();
}
/**
* Example to access private field.
*
* @throws TestUtilsException TestUtils error
*/
@Test
public
void
testSetGetPrivateField
()
throws
TestUtilsException
{
assertEquals
(
42
,
TestUtils
.
getField
(
test
,
"privateField"
));
TestUtils
.
setField
(
test
,
"privateField"
,
0xDEAD
);
assertEquals
(
0xDEAD
,
TestUtils
.
getField
(
test
,
"privateField"
));
}
/**
* Example to access protected field.
*
* @throws TestUtilsException TestUtils error
*/
@Test
public
void
testSetGetProtectedField
()
throws
TestUtilsException
{
assertEquals
(
2501
,
TestUtils
.
getField
(
test
,
"protectedField"
));
TestUtils
.
setField
(
test
,
"protectedField"
,
0xBEEF
);
assertEquals
(
0xBEEF
,
TestUtils
.
getField
(
test
,
"protectedField"
));
}
/**
* Example to call private method and multiple parameters.
* <p/>
* It also illustrates that paramTypes must match declared type,
* not the runtime types of arguments.
*
* @throws TestUtilsException TestUtils error
*/
@Test
public
void
testCallPrivateMethod
()
throws
TestUtilsException
{
int
result
=
TestUtils
.
callMethod
(
test
,
"privateMethod"
,
new
Class
<?>[]
{
Number
.
class
,
Long
.
class
},
Long
.
valueOf
(
42
),
Long
.
valueOf
(
32
));
assertEquals
(
42
,
result
);
}
/**
* Example to call protected method and no parameters.
*
* @throws TestUtilsException TestUtils error
*/
@Test
public
void
testCallProtectedMethod
()
throws
TestUtilsException
{
int
result
=
TestUtils
.
callMethod
(
test
,
"protectedMethod"
,
new
Class
<?>[]
{});
assertEquals
(
42
,
result
);
}
/**
* Example to call method returning array.
* <p/>
* Note: It is not required to receive as Object.
* Following is just verifying it is not Boxed arrays.
*
* @throws TestUtilsException TestUtils error
*/
@Test
public
void
testCallArrayReturnMethod
()
throws
TestUtilsException
{
int
[]
array
=
{
1
,
2
,
3
};
Object
aryResult
=
TestUtils
.
callMethod
(
test
,
"arrayReturnMethod"
,
new
Class
<?>[]
{
int
[].
class
},
array
);
assertEquals
(
int
[].
class
,
aryResult
.
getClass
());
assertArrayEquals
(
array
,
(
int
[])
aryResult
);
}
/**
* Example to call void returning method.
* <p/>
* Note: Return value will be null for void methods.
*
* @throws TestUtilsException TestUtils error
*/
@Test
public
void
testCallVoidReturnMethod
()
throws
TestUtilsException
{
Object
voidResult
=
TestUtils
.
callMethod
(
test
,
"voidMethod"
,
String
.
class
,
"foobar"
);
assertNull
(
voidResult
);
}
}
Please
register
or
login
to post a comment