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.
26 "github.com/pkg/profile"
27 "github.com/sirupsen/logrus"
29 "git.fd.io/govpp.git/adapter/socketclient"
30 "git.fd.io/govpp.git/adapter/statsclient"
31 "git.fd.io/govpp.git/api"
32 "git.fd.io/govpp.git/core"
33 "git.fd.io/govpp.git/examples/binapi/vpe"
37 defaultSyncRequestCount = 1000
38 defaultAsyncRequestCount = 10000
42 // parse optional flags
46 flag.BoolVar(&sync, "sync", false, "run synchronous perf test")
47 flag.StringVar(&sock, "api-socket", socketclient.DefaultSocketName, "Path to VPP API socket")
48 flag.String("stats-socket", statsclient.DefaultSocketName, "Path to VPP stats socket")
49 flag.IntVar(&cnt, "count", 0, "count of requests to be sent to VPP")
50 flag.StringVar(&prof, "prof", "", "enable profiling mode [mem, cpu]")
54 // no specific count defined - use defaults
56 cnt = defaultSyncRequestCount
58 cnt = defaultAsyncRequestCount
64 defer profile.Start(profile.MemProfile, profile.MemProfileRate(1)).Stop()
66 defer profile.Start(profile.CPUProfile).Stop()
69 fmt.Printf("invalid profiling mode: %q\n", prof)
74 a := socketclient.NewVppClient(sock)
77 conn, err := core.Connect(a)
79 log.Fatalln("Error:", err)
81 defer conn.Disconnect()
83 // create an API channel
84 ch, err := conn.NewAPIChannelBuffered(cnt, cnt)
86 log.Fatalln("Error:", err)
90 ch.SetReplyTimeout(time.Second * 2)
93 core.SetLogger(&logrus.Logger{Level: logrus.ErrorLevel})
95 // run the test & measure the time
99 // run synchronous test
102 // run asynchronous test
106 elapsed := time.Since(start)
107 fmt.Println("Test took:", elapsed)
108 fmt.Printf("Requests per second: %.0f\n", float64(cnt)/elapsed.Seconds())
110 time.Sleep(time.Second)
113 func syncTest(ch api.Channel, cnt int) {
114 fmt.Printf("Running synchronous perf test with %d requests...\n", cnt)
116 for i := 0; i < cnt; i++ {
117 req := &vpe.ControlPing{}
118 reply := &vpe.ControlPingReply{}
120 if err := ch.SendRequest(req).ReceiveReply(reply); err != nil {
121 log.Fatalln("Error in reply:", err)
126 func asyncTest(ch api.Channel, cnt int) {
127 fmt.Printf("Running asynchronous perf test with %d requests...\n", cnt)
129 ctxChan := make(chan api.RequestCtx, cnt)
132 for i := 0; i < cnt; i++ {
133 ctxChan <- ch.SendRequest(&vpe.ControlPing{})
136 fmt.Printf("Sending asynchronous requests finished\n")
139 for ctx := range ctxChan {
140 reply := &vpe.ControlPingReply{}
141 if err := ctx.ReceiveReply(reply); err != nil {
142 log.Fatalln("Error in reply:", err)