f54b6c4d91053d71967f9623489e70cc268156a6
[vpp.git] / extras / hs-test / main.go
1 package main
2
3 import (
4         "context"
5         "encoding/json"
6         "fmt"
7         "os"
8         "os/exec"
9         "os/signal"
10
11         "git.fd.io/govpp.git/api"
12 )
13
14 type CfgTable map[string]func([]string) *ActionResult
15
16 var cfgTable CfgTable
17
18 type ConfFn func(context.Context, api.Connection) error
19
20 func newVppContext() (context.Context, context.CancelFunc) {
21         ctx, cancel := signal.NotifyContext(
22                 context.Background(),
23                 os.Interrupt,
24         )
25         return ctx, cancel
26 }
27
28 func Vppcli(runDir, command string) (string, error) {
29         cmd := exec.Command("vppctl", "-s", fmt.Sprintf("%s/var/run/vpp/cli.sock", runDir), command)
30         o, err := cmd.CombinedOutput()
31         if err != nil {
32                 fmt.Printf("failed to execute command: '%v'.\n", err)
33         }
34         fmt.Printf("Command output %s", string(o))
35         return string(o), err
36 }
37
38 func exitOnErrCh(ctx context.Context, cancel context.CancelFunc, errCh <-chan error) {
39         // If we already have an error, log it and exit
40         select {
41         case err := <-errCh:
42                 fmt.Printf("%v", err)
43         default:
44         }
45         go func(ctx context.Context, errCh <-chan error) {
46                 <-errCh
47                 cancel()
48         }(ctx, errCh)
49 }
50
51 func writeSyncFile(res *ActionResult) error {
52         syncFile := "/tmp/sync/rc"
53
54         var jsonRes JsonResult
55
56         jsonRes.ErrOutput = res.ErrOutput
57         jsonRes.StdOutput = res.StdOutput
58         if res.Err != nil {
59                 jsonRes.Code = 1
60                 jsonRes.Desc = fmt.Sprintf("%s :%v", res.Desc, res.Err)
61         } else {
62                 jsonRes.Code = 0
63         }
64
65         str, err := json.Marshal(jsonRes)
66         if err != nil {
67                 return fmt.Errorf("error marshaling json result data! %v", err)
68         }
69
70         _, err = os.Open(syncFile)
71         if err != nil {
72                 // expecting the file does not exist
73                 f, e := os.Create(syncFile)
74                 if e != nil {
75                         return fmt.Errorf("failed to open sync file")
76                 }
77                 defer f.Close()
78                 f.Write([]byte(str))
79         } else {
80                 return fmt.Errorf("sync file exists, delete the file first")
81         }
82         return nil
83 }
84
85 func NewActionResult(err error, opts ...ActionResultOptionFn) *ActionResult {
86         res := &ActionResult{
87                 Err: err,
88         }
89         for _, o := range opts {
90                 o(res)
91         }
92         return res
93 }
94
95 type ActionResultOptionFn func(res *ActionResult)
96
97 func ActionResultWithDesc(s string) ActionResultOptionFn {
98         return func(res *ActionResult) {
99                 res.Desc = s
100         }
101 }
102
103 func ActionResultWithStderr(s string) ActionResultOptionFn {
104         return func(res *ActionResult) {
105                 res.ErrOutput = s
106         }
107 }
108
109 func ActionResultWithStdout(s string) ActionResultOptionFn {
110         return func(res *ActionResult) {
111                 res.StdOutput = s
112         }
113 }
114
115 func OkResult() *ActionResult {
116         return NewActionResult(nil)
117 }
118
119 func reg(key string, fn func([]string) *ActionResult) {
120         cfgTable[key] = fn
121 }
122
123 func processArgs() *ActionResult {
124         fn := cfgTable[os.Args[1]]
125         if fn == nil {
126                 return NewActionResult(fmt.Errorf("internal: no config found for %s", os.Args[1]))
127         }
128         return fn(os.Args)
129 }
130
131 func main() {
132         if len(os.Args) == 0 {
133                 fmt.Println("args required")
134                 return
135         }
136
137         if os.Args[1] == "rm" {
138                 topology, err := LoadTopology(TopologyDir, os.Args[2])
139                 if err != nil {
140                         fmt.Printf("falied to load topologies: %v\n", err)
141                         os.Exit(1)
142                 }
143                 topology.Unconfigure()
144                 os.Exit(0)
145         }
146
147         RegisterActions()
148
149         var err error
150         res := processArgs()
151         err = writeSyncFile(res)
152         if err != nil {
153                 fmt.Printf("failed to write to sync file: %v\n", err)
154         }
155 }