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
Jonathan Hart
2014-10-16 11:05:52 -0700
Browse Files
Options
Browse Files
Download
Email Patches
Plain Diff
Commit
20d8e5140be71bea085f8656a7ba6b37674c8ffa
20d8e514
1 parent
97839bb7
Ported BGP tests from old codebase
Expand all
Show whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
1046 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 @
20d8e51
...
...
@@ -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 @
20d8e51
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 @
20d8e51
This diff is collapsed. Click to expand it.
apps/sdnip/src/test/java/org/onlab/onos/sdnip/bgp/BgpSessionManagerTest.java
0 → 100644
View file @
20d8e51
This diff is collapsed. Click to expand it.
apps/sdnip/src/test/java/org/onlab/onos/sdnip/bgp/PathSegmentTest.java
0 → 100644
View file @
20d8e51
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 @
20d8e51
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 @
20d8e51
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 @
20d8e51
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 @
20d8e51
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