Skip to content

Commit 8ed74fa

Browse files
jiceathomejuagargi
authored andcommitted
testing: improved stream synthesis and cores use in router benchmark (scionproto#4457)
* testing: improved stream synthesis in router benchmark Changes: * Update the flowID of packets (and a couple of checksums) on the fly (just before sending) as opposed to pre-constructing a different packet for each stream. * As a result, the test cases are simplified, they no-longer need to provide one packet per flowID. * In passing, deleted the dumping of /proc/cpuinfo in the log. That has served its purpose. * In the test harness, left in the form of comments, a suggestion of core partitioning. Not sure how to apply that in general. This is what provides the best results on my machine. * testing: simplify the checksum updates out of the blaster. Also enable core-partitioning to see how it behaves on the CI system. * testing: Add check for proper saturation in the router benchmark. In passing: fixed a couple of function names (camel-> snake) * testing: fix expectation for droppage in the router benchmark Was expressed in pkts instead of %. * testing: cosmetic change to the output of expected drop ratio. * testing: linter friendship * testing: include a cpu selection in the router benchmark Also: fixed the broken prom query string. * testing: please the linter. * testing: log lscpus on the CI system. * testing: fix bad string formating. * testing: Improve core selection in the router benchmark. Added L2 cache criteria. The test harness will prefer configuration where either cores share no L2 cache or all cores share the same one. * testing: make the router benchmark test harness compatible with more variants of lscpu (hopefully). * testing: log the CPU serial number in the router benchmark. This is done as an attempt at detecting live migration. * build: added dmidecode as a required package. * build: Complete the list of files that affect the list of packages to install. Three files were missing, most notably the pkgs.txt files which are typically the ones modified when adding a dependency. As a result new packages weren't getting installed. * build: Delete use of dmidecode. This proved useless as a means of spotting migrations. The information doesn't even change from instance to instance. * build: fix trailing blank line. * router: reduce the benchmarks expectations for saturation. After fixing an arithmetic error, it seems we are not able to reliably cause the router to drop more than 1% of the packets (and then sometimes no even that). Until we figure out how to reach higher levels, making sure that other PRs aren't blocked. * testing: fixed bugs in router_benchmark core selection code. * testing: update the expectations of the router benchmark. After switching to non-overbooked aws instances, performance has become much better and repeatable.
1 parent 3e1c623 commit 8ed74fa

File tree

8 files changed

+297
-136
lines changed

8 files changed

+297
-136
lines changed

.buildkite/provision-agent.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,4 +13,4 @@ echo "~~~ Install build tools"
1313
tools/install_bazel
1414
tools/install_deps
1515

16-
sha1sum tools/install_bazel tools/install_deps tools/env/pip3/deps tools/env/pip3/requirements.txt tools/env/rhel/deps > /tmp/buildkite-scionproto-runner-provision.sum
16+
sha1sum tools/install_bazel tools/install_deps tools/env/pip3/deps tools/env/pip3/requirements.txt tools/env/rhel/deps tools/env/rhel/pkgs.txt tools/env/debian/deps tools/env/debian/pkgs.txt > /tmp/buildkite-scionproto-runner-provision.sum

acceptance/router_benchmark/brload/main.go

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
package main
1616

1717
import (
18+
"encoding/binary"
1819
"errors"
1920
"fmt"
2021
"hash"
@@ -38,7 +39,7 @@ import (
3839
"github.com/scionproto/scion/private/keyconf"
3940
)
4041

41-
type Case func(payload string, mac hash.Hash, numDistinct int) (string, string, [][]byte)
42+
type Case func(payload string, mac hash.Hash) (string, string, []byte)
4243

4344
type caseChoice string
4445

@@ -74,7 +75,7 @@ var (
7475
logConsole string
7576
dir string
7677
numPackets int
77-
numStreams int
78+
numStreams uint16
7879
caseToRun caseChoice
7980
interfaces []string
8081
)
@@ -99,7 +100,7 @@ func main() {
99100
},
100101
}
101102
runCmd.Flags().IntVar(&numPackets, "num-packets", 10, "Number of packets to send")
102-
runCmd.Flags().IntVar(&numStreams, "num-streams", 4,
103+
runCmd.Flags().Uint16Var(&numStreams, "num-streams", 4,
103104
"Number of independent streams (flowID) to use")
104105
runCmd.Flags().StringVar(&logConsole, "log.console", "error",
105106
"Console logging level: debug|info|error|etc.")
@@ -136,8 +137,6 @@ func run(cmd *cobra.Command) int {
136137
}
137138
defer log.HandlePanic()
138139

139-
caseFunc := allCases[string(caseToRun)] // key already checked.
140-
141140
artifactsDir := dir
142141
if v := os.Getenv("TEST_ARTIFACTS_DIR"); v != "" {
143142
artifactsDir = v
@@ -166,7 +165,8 @@ func run(cmd *cobra.Command) int {
166165
log.Info("BRLoad acceptance tests:")
167166

168167
payloadString := "actualpayloadbytes"
169-
caseDevIn, caseDevOut, rawPkts := caseFunc(payloadString, hfMAC, numStreams)
168+
caseFunc := allCases[string(caseToRun)] // key already checked.
169+
caseDevIn, caseDevOut, rawPkt := caseFunc(payloadString, hfMAC)
170170

171171
writePktTo, ok := handles[caseDevIn]
172172
if !ok {
@@ -195,8 +195,18 @@ func run(cmd *cobra.Command) int {
195195
// We started everything that could be started. So the best window for perf mertics
196196
// opens somewhere around now.
197197
metricsBegin := time.Now().Unix()
198+
// Because we're using IPV4 only, the UDP checksum is optional, so we are allowed to
199+
// just set it to zero instead of recomputing it. The IP checksum does not cover the payload, so
200+
// we don't need to update it.
201+
binary.BigEndian.PutUint16(rawPkt[40:42], 0)
202+
198203
for i := 0; i < numPackets; i++ {
199-
if err := writePktTo.WritePacketData(rawPkts[i%numStreams]); err != nil {
204+
// Rotate through flowIDs. We patch it directly into the SCION header of the packet. The
205+
// SCION header starts at offset 42. The flowID is the 20 least significant bits of the
206+
// first 32 bit field. To make our life simpler, we only use the last 16 bits (so no more
207+
// than 64K flows).
208+
binary.BigEndian.PutUint16(rawPkt[44:46], uint16(i%int(numStreams)))
209+
if err := writePktTo.WritePacketData(rawPkt); err != nil {
200210
log.Error("writing input packet", "case", string(caseToRun), "error", err)
201211
return 1
202212
}
@@ -255,7 +265,7 @@ func receivePackets(packetChan chan gopacket.Packet, payload string) int {
255265
if string(layer.LayerContents()) == payload {
256266
// To return the count of all packets received, just remove the "return" below.
257267
// Return will occur once packetChan closes (which happens after a short timeout at
258-
// the end of the test.
268+
// the end of the test).
259269
numRcv++
260270
return numRcv
261271
}

acceptance/router_benchmark/cases/br_transit.go

Lines changed: 5 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -32,9 +32,9 @@ import (
3232
// AS3 (br3) ---+
3333
// See topo.go
3434

35-
// oneBrTransit generates one packet of "br_transit" traffic over the router under test.
36-
// The outcome is a raw packet which the test must feed to the router.
37-
func oneBrTransit(payload string, mac hash.Hash, flowId uint32) []byte {
35+
// BrTransit generates one packet of "br_transit" traffic over the router under test.
36+
// The outcome is a raw packet which the test must feed to the router. The flowID field is 0.
37+
func BrTransit(payload string, mac hash.Hash) (string, string, []byte) {
3838

3939
var (
4040
originIA = ISDAS(2)
@@ -100,7 +100,7 @@ func oneBrTransit(payload string, mac hash.Hash, flowId uint32) []byte {
100100
scionL := &slayers.SCION{
101101
Version: 0,
102102
TrafficClass: 0xb8,
103-
FlowID: flowId,
103+
FlowID: 0,
104104
NextHdr: slayers.L4UDP,
105105
PathType: scion.PathType,
106106
SrcIA: originIA,
@@ -128,17 +128,6 @@ func oneBrTransit(payload string, mac hash.Hash, flowId uint32) []byte {
128128
); err != nil {
129129
panic(err)
130130
}
131-
return input.Bytes()
132-
}
133131

134-
// BrTransit generates numDistinct packets (each with a unique flowID) with the given payload
135-
// constructed to cause br_transit traffic at the br1a router.
136-
// numDistrinct is a small number, only to enable multiple parallel streams. Each distinct packet
137-
// is meant to be replayed a large number of times for performance measurement.
138-
func BrTransit(payload string, mac hash.Hash, numDistinct int) (string, string, [][]byte) {
139-
packets := make([][]byte, numDistinct)
140-
for i := 0; i < numDistinct; i++ {
141-
packets[i] = oneBrTransit(payload, mac, uint32(i+1))
142-
}
143-
return DeviceName(1, 2), DeviceName(1, 3), packets
132+
return DeviceName(1, 2), DeviceName(1, 3), input.Bytes()
144133
}

acceptance/router_benchmark/cases/in.go

Lines changed: 4 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,8 @@ import (
3333
// See topo.go
3434

3535
// oneIn generates one packet of incoming traffic into AS1 at br1a. The outcome is a raw packet
36-
// that the test must feed into the router.
37-
func oneIn(payload string, mac hash.Hash, flowId uint32) []byte {
36+
// that the test must feed into the router. The flow ID is 0.
37+
func In(payload string, mac hash.Hash) (string, string, []byte) {
3838

3939
var (
4040
originIA = ISDAS(2)
@@ -87,7 +87,7 @@ func oneIn(payload string, mac hash.Hash, flowId uint32) []byte {
8787
scionL := &slayers.SCION{
8888
Version: 0,
8989
TrafficClass: 0xb8,
90-
FlowID: flowId,
90+
FlowID: 0,
9191
NextHdr: slayers.L4UDP,
9292
PathType: scion.PathType,
9393
SrcIA: originIA,
@@ -115,17 +115,5 @@ func oneIn(payload string, mac hash.Hash, flowId uint32) []byte {
115115
); err != nil {
116116
panic(err)
117117
}
118-
return input.Bytes()
119-
}
120-
121-
// In generates numDistinct packets (each with a unique flowID) with the given payload
122-
// constructed to cause "in" traffic at the br1a router.
123-
// numDistrinct is a small number, only to enable multiple parallel streams. Each distinct packet
124-
// is meant to be replayed a large number of times for performance measurement.
125-
func In(payload string, mac hash.Hash, numDistinct int) (string, string, [][]byte) {
126-
packets := make([][]byte, numDistinct)
127-
for i := 0; i < numDistinct; i++ {
128-
packets[i] = oneIn(payload, mac, uint32(i+1))
129-
}
130-
return DeviceName(1, 2), DeviceName(1, 0), packets
118+
return DeviceName(1, 2), DeviceName(1, 0), input.Bytes()
131119
}

acceptance/router_benchmark/cases/in_transit.go

Lines changed: 4 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,8 @@ import (
3333
// See topo.go
3434

3535
// oneInTransit generates one packet of "in_transit" traffic over the router under test.
36-
// The outcome is a raw packet that the test must feed into the router.
37-
func oneInTransit(payload string, mac hash.Hash, flowId uint32) []byte {
36+
// The outcome is a raw packet that the test must feed into the router. The flow ID is 0.
37+
func InTransit(payload string, mac hash.Hash) (string, string, []byte) {
3838

3939
var (
4040
originIA = ISDAS(2)
@@ -100,7 +100,7 @@ func oneInTransit(payload string, mac hash.Hash, flowId uint32) []byte {
100100
scionL := &slayers.SCION{
101101
Version: 0,
102102
TrafficClass: 0xb8,
103-
FlowID: flowId,
103+
FlowID: 0,
104104
NextHdr: slayers.L4UDP,
105105
PathType: scion.PathType,
106106
SrcIA: originIA,
@@ -128,17 +128,5 @@ func oneInTransit(payload string, mac hash.Hash, flowId uint32) []byte {
128128
); err != nil {
129129
panic(err)
130130
}
131-
return input.Bytes()
132-
}
133-
134-
// InTransit generates numDistinct packets (each with a unique flowID) with the given payload
135-
// constructed to cause in_transit traffic at the br1a router.
136-
// numDistrinct is a small number, only to enable multiple parallel streams. Each distinct packet
137-
// is meant to be replayed a large number of times for performance measurement.
138-
func InTransit(payload string, mac hash.Hash, numDistinct int) (string, string, [][]byte) {
139-
packets := make([][]byte, numDistinct)
140-
for i := 0; i < numDistinct; i++ {
141-
packets[i] = oneInTransit(payload, mac, uint32(i+1))
142-
}
143-
return DeviceName(1, 2), DeviceName(1, 0), packets
131+
return DeviceName(1, 2), DeviceName(1, 0), input.Bytes()
144132
}

acceptance/router_benchmark/cases/out.go

Lines changed: 4 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,8 @@ import (
3333
// See topo.go
3434

3535
// oneOut generates one packet of outgoing traffic from AS1 at br1a. The outcome is a raw packet
36-
// that the test must feed into the router.
37-
func oneOut(payload string, mac hash.Hash, flowId uint32) []byte {
36+
// that the test must feed into the router. The flow ID is 0.
37+
func Out(payload string, mac hash.Hash) (string, string, []byte) {
3838

3939
var (
4040
originIA = ISDAS(1)
@@ -88,7 +88,7 @@ func oneOut(payload string, mac hash.Hash, flowId uint32) []byte {
8888
scionL := &slayers.SCION{
8989
Version: 0,
9090
TrafficClass: 0xb8,
91-
FlowID: flowId,
91+
FlowID: 0,
9292
NextHdr: slayers.L4UDP,
9393
PathType: scion.PathType,
9494
SrcIA: originIA,
@@ -117,17 +117,5 @@ func oneOut(payload string, mac hash.Hash, flowId uint32) []byte {
117117
panic(err)
118118
}
119119

120-
return input.Bytes()
121-
}
122-
123-
// Out generates numDistinct packets (each with a unique flowID) with the given payload
124-
// constructed to cause "out" traffic at the br1a router.
125-
// numDistrinct is a small number, only to enable multiple parallel streams. Each distinct packet
126-
// is meant to be replayed a large number of times for performance measurement.
127-
func Out(payload string, mac hash.Hash, numDistinct int) (string, string, [][]byte) {
128-
packets := make([][]byte, numDistinct)
129-
for i := 0; i < numDistinct; i++ {
130-
packets[i] = oneOut(payload, mac, uint32(i+1))
131-
}
132-
return DeviceName(1, 0), DeviceName(1, 2), packets
120+
return DeviceName(1, 0), DeviceName(1, 2), input.Bytes()
133121
}

acceptance/router_benchmark/cases/out_transit.go

Lines changed: 4 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,8 @@ import (
3333
// See topo.go
3434

3535
// oneOutTransit generates one packet of "out_transit" traffic over the router under test.
36-
// The outcome is a raw packet that the test must feed to the router.
37-
func oneOutTransit(payload string, mac hash.Hash, flowId uint32) []byte {
36+
// The outcome is a raw packet that the test must feed to the router. The flow ID is 0.
37+
func OutTransit(payload string, mac hash.Hash) (string, string, []byte) {
3838

3939
var (
4040
originIA = ISDAS(4)
@@ -101,7 +101,7 @@ func oneOutTransit(payload string, mac hash.Hash, flowId uint32) []byte {
101101
scionL := &slayers.SCION{
102102
Version: 0,
103103
TrafficClass: 0xb8,
104-
FlowID: flowId,
104+
FlowID: 0,
105105
NextHdr: slayers.L4UDP,
106106
PathType: scion.PathType,
107107
SrcIA: originIA,
@@ -129,17 +129,5 @@ func oneOutTransit(payload string, mac hash.Hash, flowId uint32) []byte {
129129
); err != nil {
130130
panic(err)
131131
}
132-
return input.Bytes()
133-
}
134-
135-
// OutTransit generates numDistinct packets (each with a unique flowID) with the given payload
136-
// constructed to cause out_transit traffic at the br1a router.
137-
// numDistrinct is a small number, only to enable multiple parallel streams. Each distinct packet
138-
// is meant to be replayed a large number of times for performance measurement.
139-
func OutTransit(payload string, mac hash.Hash, numDistinct int) (string, string, [][]byte) {
140-
packets := make([][]byte, numDistinct)
141-
for i := 0; i < numDistinct; i++ {
142-
packets[i] = oneOutTransit(payload, mac, uint32(i+1))
143-
}
144-
return DeviceName(1, 0), DeviceName(1, 2), packets
132+
return DeviceName(1, 0), DeviceName(1, 2), input.Bytes()
145133
}

0 commit comments

Comments
 (0)