testExec: error exec with a fakeid
[src/xds/xds-server.git] / test / main_test.go
1 /*
2  * Copyright (C) 2017-2018 "IoT.bzh"
3  * Author Clément Bénier <clement.benier@iot.bzh>
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  *   http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17 package xdsservertest
18
19 import (
20         "fmt"
21         "io"
22         "log"
23         "os"
24         "os/exec"
25         "sync"
26         "testing"
27         "time"
28
29         common "gerrit.automotivelinux.org/gerrit/src/xds/xds-common.git/golib"
30         "gerrit.automotivelinux.org/gerrit/src/xds/xds-server/lib/xsapiv1"
31         socketio_client "github.com/sebd71/go-socket.io-client"
32 )
33
34 // IOSockClient
35 type IOSockClient struct {
36         URL       string
37         Conn      *socketio_client.Client
38         Options   *socketio_client.Options
39         EmitMutex *sync.Mutex
40         Connected bool
41         //ServerDiscoChan chan Disconnection
42         EscapeKeys []byte
43 }
44
45 //global client
46 var HTTPCli *common.HTTPClient
47 var logDir string
48 var sCli *IOSockClient
49
50 // Debug function used to print debug logs
51 func Debug(t *testing.T, args ...interface{}) {
52         if os.Getenv("VERBOSE") != "" {
53                 t.Log(args...)
54         }
55 }
56
57 // Debugf function used to print debug logs
58 func Debugf(t *testing.T, format string, args ...interface{}) {
59         if os.Getenv("VERBOSE") != "" {
60                 t.Logf(format, args...)
61         }
62 }
63
64 // Copy copies from src to dst until either EOF
65 func Copy(src, dst string) error {
66         in, err := os.Open(src)
67         if err != nil {
68                 return err
69         }
70         defer in.Close()
71
72         out, err := os.Create(dst)
73         if err != nil {
74                 return err
75         }
76         defer out.Close()
77
78         _, err = io.Copy(out, in)
79         if err != nil {
80                 return err
81         }
82         return out.Close()
83 }
84
85 func initEnv(launchProcess bool) {
86         if launchProcess {
87                 /*kill xds-server if needed*/
88                 cmd := exec.Command("killall", "-9", "xds-server")
89                 if err := cmd.Start(); err != nil {
90                         log.Fatal(err)
91                 }
92                 cmd.Wait()
93         }
94         /*set environment variable*/
95         rootTestLog := "/tmp/xds-server-test"
96         if err := os.Setenv(envRootCfgDir, rootTestLog); err != nil {
97                 log.Fatal(err)
98         }
99         sdkDir := rootTestLog + "/sdks/"
100         if err := os.Setenv(envXdtSdk, sdkDir); err != nil {
101                 log.Fatal(err)
102         }
103         if err := os.Setenv(envXdsServerWorkspaceDir, rootTestLog); err != nil {
104                 log.Fatal(err)
105         }
106         if err := os.Setenv(envXdsServerRootCfgDir, rootTestLog); err != nil {
107                 log.Fatal(err)
108         }
109         if err := os.Setenv("XDS_LOG_SILLY", "1"); err != nil {
110                 log.Fatal(err)
111         }
112         /*remove and recreate working directories*/
113         os.RemoveAll(rootTestLog)
114         os.MkdirAll(rootTestLog, 0755)
115         logDir = rootTestLog + "/logs/"
116         os.MkdirAll(logDir, 0755)
117 }
118
119 /*prepare xds-server process*/
120 func launchXdsServer(proc **os.Process) *os.File {
121         logFile := logDir + logFileXdsServer
122         file, err := os.OpenFile(logFile, os.O_CREATE|os.O_WRONLY, 0644)
123         if err != nil {
124                 log.Fatal(err)
125         }
126         tmpProc, err := os.StartProcess(argsProcess[0], argsProcess, &os.ProcAttr{
127                 Files: []*os.File{os.Stdin, file, file},
128         })
129         if err != nil {
130                 log.Fatal(err)
131         }
132         *proc = tmpProc
133         return file
134 }
135
136 func getHTTPClient(lvl int) (*common.HTTPClient, *os.File) {
137         logFile := logDir + logFileClient
138         file, err := os.OpenFile(logFile, os.O_CREATE|os.O_WRONLY, 0644)
139         if err != nil {
140                 log.Fatal(err)
141         }
142         conf := common.HTTPClientConfig{
143                 URLPrefix:           "/api/v1",
144                 HeaderClientKeyName: "Xds-Sid",
145                 CsrfDisable:         true,
146                 LogOut:              file,
147                 LogPrefix:           "XDSSERVERTEST: ",
148                 LogLevel:            lvl,
149         }
150         HTTPcli, err := common.HTTPNewClient(prefixURL, conf)
151         if err != nil {
152                 log.Fatal(err)
153         }
154         log.Printf("HTTP session ID : %v", HTTPcli.GetClientID())
155         var ver xsapiv1.Version
156         err = HTTPcli.Get("/version", &ver)
157         if err != nil {
158                 log.Fatal(err)
159         }
160         return HTTPcli, file
161 }
162
163 func NewIoSocketClient(url, clientID string) (*IOSockClient, error) {
164         var err error
165
166         sCli := &IOSockClient{
167                 URL:       url,
168                 EmitMutex: &sync.Mutex{},
169                 Options: &socketio_client.Options{
170                         Transport: "websocket",
171                         Header:    make(map[string][]string),
172                 },
173         }
174         sCli.Options.Header["XDS-SID"] = []string{clientID}
175
176         sCli.Conn, err = socketio_client.NewClient(url, sCli.Options)
177         if err != nil {
178                 return nil, fmt.Errorf("IO.socket connection error: " + err.Error())
179         }
180
181         sCli.Conn.On("connection", func() {
182                 sCli.Connected = true
183         })
184
185         sCli.Conn.On("disconnection", func(err error) {
186                 if err != nil {
187                         log.Printf("WS disconnection event with err: %v\n", err)
188                 }
189                 sCli.Connected = false
190         })
191
192         log.Printf("Connect websocket with url=%v clientId=%v\n", prefixURL, HTTPCli.GetClientID())
193         return sCli, nil
194 }
195 func TestMain(m *testing.M) {
196         /* useful for debugging, preventing from launching xds-server
197          * it can be launch separately */
198         launchProcess := true
199         log.Printf("TestMain: launchProcess is %v, so launching xds-server", launchProcess)
200         initEnv(launchProcess)
201
202         var proc *os.Process
203         var fileXdsServer *os.File
204         if launchProcess {
205                 fileXdsServer = launchXdsServer(&proc)
206                 go func(p *os.Process) {
207                         log.Print("xds-server is launching")
208                         if status, err := p.Wait(); err != nil {
209                                 log.Fatalf("status=%v\n err=%v\n", status, err)
210                         }
211                 }(proc)
212                 defer fileXdsServer.Close()
213         }
214         time.Sleep(1 * time.Second)
215
216         lvl := common.HTTPLogLevelDebug
217         var fileHTTPClient *os.File
218         HTTPCli, fileHTTPClient = getHTTPClient(lvl)
219         defer fileHTTPClient.Close()
220         var err error
221         sCli, err = NewIoSocketClient(prefixURL, HTTPCli.GetClientID())
222         if err != nil {
223                 log.Fatal(err)
224         }
225
226         if HTTPCli == nil {
227                 log.Fatal("HTTPCLi is nil")
228         }
229         res := m.Run()
230         defer os.Exit(res)
231         proc.Kill()
232 }