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"
30 "git.fd.io/govpp.git/adapter/socketclient"
31 "git.fd.io/govpp.git/adapter/statsclient"
32 "git.fd.io/govpp.git/api"
33 "git.fd.io/govpp.git/binapi/vpe"
34 "git.fd.io/govpp.git/core"
38 defaultSyncRequestCount = 1000
39 defaultAsyncRequestCount = 10000
43 // parse optional flags
47 flag.BoolVar(&sync, "sync", false, "run synchronous perf test")
48 flag.StringVar(&sock, "api-socket", socketclient.DefaultSocketName, "Path to VPP API socket")
49 flag.String("stats-socket", statsclient.DefaultSocketName, "Path to VPP stats socket")
50 flag.IntVar(&cnt, "count", 0, "count of requests to be sent to VPP")
51 flag.StringVar(&prof, "prof", "", "enable profiling mode [mem, cpu]")
55 // no specific count defined - use defaults
57 cnt = defaultSyncRequestCount
59 cnt = defaultAsyncRequestCount
65 defer profile.Start(profile.MemProfile, profile.MemProfileRate(1)).Stop()
67 defer profile.Start(profile.CPUProfile).Stop()
70 fmt.Printf("invalid profiling mode: %q\n", prof)
75 a := socketclient.NewVppClient(sock)
78 conn, err := core.Connect(a)
80 log.Fatalln("Error:", err)
82 defer conn.Disconnect()
84 // create an API channel
85 ch, err := conn.NewAPIChannelBuffered(cnt, cnt)
87 log.Fatalln("Error:", err)
91 ch.SetReplyTimeout(time.Second * 2)
94 core.SetLogger(&logrus.Logger{Level: logrus.ErrorLevel})
96 // run the test & measure the time
100 // run synchronous test
102 //syncTest2(conn, cnt)
104 // run asynchronous test
106 //asyncTest2(conn, cnt)
109 elapsed := time.Since(start)
110 fmt.Println("Test took:", elapsed)
111 fmt.Printf("Requests per second: %.0f\n", float64(cnt)/elapsed.Seconds())
113 time.Sleep(time.Second)
116 func syncTest(ch api.Channel, cnt int) {
117 fmt.Printf("Running synchronous perf test with %d requests...\n", cnt)
119 for i := 0; i < cnt; i++ {
120 req := &vpe.ControlPing{}
121 reply := &vpe.ControlPingReply{}
123 if err := ch.SendRequest(req).ReceiveReply(reply); err != nil {
124 log.Fatalln("Error in reply:", err)
129 func syncTest2(conn api.Connection, cnt int) {
130 fmt.Printf("Running synchronous perf test with %d requests...\n", cnt)
132 stream, err := conn.NewStream(context.Background())
134 log.Fatalln("Error NewStream:", err)
136 for i := 0; i < cnt; i++ {
137 if err := stream.SendMsg(&vpe.ControlPing{}); err != nil {
138 log.Fatalln("Error SendMsg:", err)
140 if msg, err := stream.RecvMsg(); err != nil {
141 log.Fatalln("Error RecvMsg:", err)
142 } else if _, ok := msg.(*vpe.ControlPingReply); ok {
145 log.Fatalf("unexpected reply: %v", msg.GetMessageName())
150 func asyncTest(ch api.Channel, cnt int) {
151 fmt.Printf("Running asynchronous perf test with %d requests...\n", cnt)
153 ctxChan := make(chan api.RequestCtx, cnt)
156 for i := 0; i < cnt; i++ {
157 ctxChan <- ch.SendRequest(&vpe.ControlPing{})
160 fmt.Printf("Sending asynchronous requests finished\n")
163 for ctx := range ctxChan {
164 reply := &vpe.ControlPingReply{}
165 if err := ctx.ReceiveReply(reply); err != nil {
166 log.Fatalln("Error in reply:", err)
171 func asyncTest2(conn api.Connection, cnt int) {
172 fmt.Printf("Running asynchronous perf test with %d requests...\n", cnt)
174 ctxChan := make(chan api.Stream, cnt)
177 for i := 0; i < cnt; i++ {
178 stream, err := conn.NewStream(context.Background())
180 log.Fatalln("Error NewStream:", err)
182 if err := stream.SendMsg(&vpe.ControlPing{}); err != nil {
183 log.Fatalln("Error SendMsg:", err)
188 fmt.Printf("Sending asynchronous requests finished\n")
191 for ctx := range ctxChan {
192 if msg, err := ctx.RecvMsg(); err != nil {
193 log.Fatalln("Error RecvMsg:", err)
194 } else if _, ok := msg.(*vpe.ControlPingReply); ok {
197 log.Fatalf("unexpected reply: %v", msg.GetMessageName())