1 // Copyright (c) 2017 Cisco and/or its affiliates.
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at:
7 // http://www.apache.org/licenses/LICENSE-2.0
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
15 // Binary simple-client is an example VPP management application that exercises the
16 // govpp API on real-world use-cases.
27 "github.com/pkg/profile"
28 "github.com/sirupsen/logrus"
31 "git.fd.io/govpp.git/api"
32 "git.fd.io/govpp.git/core"
33 "git.fd.io/govpp.git/core/bin_api/vpe"
37 defaultSyncRequestCount = 1000
38 defaultAsyncRequestCount = 1000000
42 // parse optional flags
45 flag.BoolVar(&sync, "sync", false, "run synchronous perf test")
46 flag.IntVar(&cnt, "cnt", 0, "count of requests to be sent to VPP")
47 flag.BoolVar(&prof, "prof", false, "generate profile data")
51 // no specific count defined - use defaults
53 cnt = defaultSyncRequestCount
55 cnt = defaultAsyncRequestCount
60 defer profile.Start().Stop()
64 core.SetLogger(&logrus.Logger{Level: logrus.ErrorLevel})
67 conn, err := govpp.Connect("")
69 log.Println("Error:", err)
72 defer conn.Disconnect()
74 // create an API channel
75 ch, err := conn.NewAPIChannelBuffered(cnt, cnt)
77 log.Println("Error:", err)
82 // run the test & measure the time
86 // run synchronous test
89 // run asynchronous test
93 elapsed := time.Since(start)
94 fmt.Println("Test took:", elapsed)
95 fmt.Printf("Requests per second: %.0f\n", float64(cnt)/elapsed.Seconds())
98 func syncTest(ch api.Channel, cnt int) {
99 fmt.Printf("Running synchronous perf test with %d requests...\n", cnt)
101 for i := 0; i < cnt; i++ {
102 req := &vpe.ControlPing{}
103 reply := &vpe.ControlPingReply{}
105 err := ch.SendRequest(req).ReceiveReply(reply)
107 log.Println("Error in reply:", err)
113 func asyncTest(ch api.Channel, cnt int) {
114 fmt.Printf("Running asynchronous perf test with %d requests...\n", cnt)
116 // start a new go routine that reads the replies
117 var wg sync.WaitGroup
119 go readAsyncReplies(ch, cnt, &wg)
121 // send asynchronous requests
122 sendAsyncRequests(ch, cnt)
124 // wait until all replies are recieved
128 func sendAsyncRequests(ch api.Channel, cnt int) {
129 for i := 0; i < cnt; i++ {
130 ch.GetRequestChannel() <- &api.VppRequest{
131 Message: &vpe.ControlPing{},
136 func readAsyncReplies(ch api.Channel, expectedCnt int, wg *sync.WaitGroup) {
141 reply := <-ch.GetReplyChannel()
142 if reply.Error != nil {
143 log.Println("Error in reply:", reply.Error)
147 // decode the message
148 msg := &vpe.ControlPingReply{}
149 err := ch.GetMessageDecoder().DecodeMsg(reply.Data, msg)
150 if reply.Error != nil {
151 log.Println("Error by decoding:", err)
155 // count and return if done
157 if cnt >= expectedCnt {