aboutsummaryrefslogtreecommitdiffstats
path: root/test/target_test.go
diff options
context:
space:
mode:
authorClément Bénier <clement.benier@iot.bzh>2018-08-22 14:06:34 +0200
committerClément Bénier <clement.benier@iot.bzh>2018-08-24 17:33:01 +0200
commit7fb08b4791214b648175d19ce14fa297b4ea2e16 (patch)
tree496515e0ebfc9d59877734bebbf82d53f35be7d5 /test/target_test.go
parent7ec4cfb73ca8ead1c816e3c7845211ddfb548a12 (diff)
- fixtures for user ssh server (authorized_keys, ssh, sshd_config, ssh_host_rsa_key, ssh.pub) - exec following cmd $ /usr/bin/sshd - D -f sshd_config -h ssh_host_rsa_key -o AuthorizedKeysFile=authorized_keys -p port - uncomment former terminal tests for open/close Change-Id: If1765c4860ef3a95f7a92f1f9652427828b98083 Signed-off-by: Clément Bénier <clement.benier@iot.bzh>
Diffstat (limited to 'test/target_test.go')
-rw-r--r--test/target_test.go263
1 files changed, 180 insertions, 83 deletions
diff --git a/test/target_test.go b/test/target_test.go
index e89011b..d7576c6 100644
--- a/test/target_test.go
+++ b/test/target_test.go
@@ -17,23 +17,128 @@
package xdsservertest
import (
+ "bytes"
+ "fmt"
+ "log"
+ "os"
+ "os/exec"
+ "path"
+ "regexp"
"strconv"
"strings"
"testing"
"time"
+ common "gerrit.automotivelinux.org/gerrit/src/xds/xds-common.git/golib"
"gerrit.automotivelinux.org/gerrit/src/xds/xds-server/lib/xsapiv1"
"github.com/stretchr/testify/assert"
)
-/*flush channel with timeout*/
-func flushChannelTerm(channel chan xsapiv1.TerminalOutMsg, ms time.Duration) {
- timeoutB := false
- for !timeoutB {
+func launchSSHd(sshDir string, proc **os.Process, sshdCmd string) (*os.File, string) {
+ port := "22222"
+ argsProcessSSHd := []string{
+ sshdCmd,
+ "-f",
+ sshDir + "/sshd_config",
+ "-D",
+ "-h",
+ sshDir + "/ssh_host_rsa_key",
+ "-o",
+ "AuthorizedKeysFile=" + sshDir + "/authorized_keys",
+ "-p",
+ port,
+ }
+ logFile := logDir + logFileSSHd
+ file, err := os.OpenFile(logFile, os.O_CREATE|os.O_WRONLY, 0644)
+ if err != nil {
+ log.Fatal(err)
+ }
+ defer file.Close()
+ tmpProc, err := os.StartProcess(argsProcessSSHd[0], argsProcessSSHd, &os.ProcAttr{
+ Files: []*os.File{os.Stdin, file, file},
+ })
+ if err != nil {
+ log.Fatal(err)
+ }
+ *proc = tmpProc
+ return file, port
+}
+
+func InitSSH(t *testing.T, procSSHd **os.Process) (string, string) {
+ Debug(t, "Initialise ssh with local user")
+ sshDir := path.Join(os.Getenv(envRootCfgDir), "ssh")
+ cmd := exec.Command("cp", "-r", sshFixturesDir, sshDir)
+ var out bytes.Buffer
+ cmd.Stdout = &out
+ assert.Nil(t, cmd.Run())
+
+ cmd = exec.Command("ls", sshDir)
+ cmd.Stdout = &out
+ assert.Nil(t, cmd.Run())
+
+ files := strings.Split(fmt.Sprint(cmd.Stdout), "\n")
+
+ for _, f := range files {
+ if f != "" {
+ file := sshDir + "/" + f
+ cmd = exec.Command("chmod", "600", file)
+ cmd.Stdout = &out
+ assert.Nil(t, cmd.Run())
+ }
+ }
+
+ var outSSHd bytes.Buffer
+ var sshdCmd string
+ cmd = exec.Command("which", "sshd")
+ cmd.Stdout = &outSSHd
+ if cmd.Run() != nil {
+ if common.Exists("/usr/sbin/sshd") {
+ sshdCmd = "/usr/sbin/sshd"
+ } else if common.Exists("/usr/bin/sshd") {
+ sshdCmd = "/usr/sbin/sshd"
+ } else {
+ assert.FailNow(t, "Cannot find sshd command, please install it or set in your PATH")
+ }
+ } else {
+ sshdCmd = strings.TrimSpace(fmt.Sprint(cmd.Stdout))
+ }
+
+ var port string
+ _, port = launchSSHd(sshDir, procSSHd, sshdCmd)
+ go func(p *os.Process) {
+ Debug(t, "sshd is launching")
+ if status, err := p.Wait(); err != nil {
+ log.Fatalf("status=%v\n err=%v\n", status, err)
+ }
+ }(*procSSHd)
+ return sshDir, port
+}
+
+/*wait for terminal prompt*/
+func waitForPrompt(t *testing.T, channel chan xsapiv1.TerminalOutMsg, prompt string) string {
+ step := 1 * time.Millisecond
+ timeout := 10 * time.Second
+ current := 0 * time.Second
+ out := ""
+ re := regexp.MustCompile("^" + prompt)
+
+ for {
select {
- case <-channel:
- case <-time.After(ms * time.Millisecond):
- timeoutB = true
+ case outMsg := <-channel:
+ out += string(outMsg.Stdout)
+ if string(outMsg.Stderr) != "" {
+ out += string(outMsg.Stderr)
+ }
+ for _, line := range strings.Split(out, "\n") {
+ if re.MatchString(line) {
+ return line
+ }
+ }
+ case <-time.After(step):
+ current = current + step
+ if current >= timeout {
+ assert.FailNow(t, "Never received prompt message from terminal (output:"+out+")")
+ }
}
}
}
@@ -122,13 +227,21 @@ func AddTargets(t *testing.T, nbTargets int, chTarget chan xsapiv1.TargetConfig)
return listID
}
-func AddTerms(t *testing.T, nbTerms int, listID []string, chTermEvt chan xsapiv1.TerminalConfig) {
+func AddTerms(t *testing.T, nbTerms int, listID []string, chTermEvt chan xsapiv1.TerminalConfig, sshDir string, port string) {
for j := 0; j < len(listID); j++ {
listTermsID := make([]string, nbTerms)
for i := 0; i < nbTerms; i++ {
term := xsapiv1.TerminalConfig{
Name: "terminal" + strconv.Itoa(i),
Type: xsapiv1.TypeTermSSH,
+ Options: []string{
+ "-p",
+ port,
+ "-i",
+ sshDir + "/ssh",
+ "-o",
+ "StrictHostKeyChecking=no",
+ },
}
/*add terminal on target*/
assert.Nil(t, HTTPCli.Post("/targets/"+listID[j]+"/terminals", term, &term))
@@ -146,7 +259,8 @@ func AddTerms(t *testing.T, nbTerms int, listID []string, chTermEvt chan xsapiv1
}
}
-func PostTerms(t *testing.T, post string, chTermEvt chan xsapiv1.TerminalConfig) {
+func PostTerms(t *testing.T, post string, chTermEvt chan xsapiv1.TerminalConfig, chTerm chan xsapiv1.TerminalOutMsg,
+ prompt string) {
var status string
switch post {
case "open":
@@ -166,6 +280,11 @@ func PostTerms(t *testing.T, post string, chTermEvt chan xsapiv1.TerminalConfig)
assert.Nil(t, HTTPCli.Post("/targets/"+targets[i].ID+"/terminals/"+terms[j].ID+"/"+post, terms[j], &term))
Debugf(t, "%v terminal %v", post, term.Name)
termEvt := <-chTermEvt //waiting for event terminalStateChange
+ if post == "open" {
+ data := []byte("PS1=" + prompt + " bash -norc\n")
+ assert.Nil(t, sCli.Conn.Emit(xsapiv1.TerminalInEvent, data))
+ waitForPrompt(t, chTerm, prompt)
+ }
assert.Equal(t, term.ID, termEvt.ID)
assert.Equal(t, term.Status, status)
assert.Equal(t, termEvt.Status, status)
@@ -203,8 +322,13 @@ func RemoveTermsTargets(t *testing.T, chTarget chan xsapiv1.TargetConfig, chTerm
}
}
func TestTarget(t *testing.T) {
- nbTargets := 3
- nbTermsByTarget := 3
+ prompt := "--PROMPT--"
+ var procSSHd *os.Process
+ sshDir, port := InitSSH(t, &procSSHd)
+ defer procSSHd.Kill()
+
+ nbTargets := 2
+ nbTermsByTarget := 2
/*channel for target events*/
chTarget := make(chan xsapiv1.TargetConfig)
defer close(chTarget)
@@ -221,78 +345,51 @@ func TestTarget(t *testing.T) {
assert.Equal(t, len(targetArray), 0)
listID := AddTargets(t, nbTargets, chTarget)
- AddTerms(t, nbTermsByTarget, listID, chTermEvt)
-
- ///*channel for TerminalOutMsg*/
- //chTerm := make(chan xsapiv1.TerminalOutMsg)
- //defer close(chTerm)
-
- ///*connect on terminalOutMsg event*/
- //sCli.Conn.On(xsapiv1.TerminalOutEvent, func(ev xsapiv1.TerminalOutMsg) {
- // chTerm <- ev
- //})
-
- ///*just for the first term*/
- //var terms []xsapiv1.TerminalConfig
- //var term xsapiv1.TerminalConfig
- //assert.Nil(t, HTTPCli.Get("/targets/"+listID[0]+"/terminals", &terms))
- //assert.Nil(t, HTTPCli.Post("/targets/"+listID[0]+"/terminals/"+terms[0].ID+"/open", terms[0], &term))
- //<-chTermEvt //waiting for event terminalStateChange
- //termOut := <-chTerm //waiting for terminalOutMsg
- //flushChannelTerm(chTerm, 50) //flushing all terminalOutMsg
- //stdoutMsg := string(termOut.Stdout)
- //if strings.Contains(stdoutMsg, "Connection refused") {
- // t.Fatalf("%vYou may have to launch ssh server", stdoutMsg)
- //} else if strings.Contains(stdoutMsg, "password") {
- // t.Fatalf("%vcopy your pub key in authorized_keys\ncat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys", stdoutMsg)
- //}
- //assert.True(t, strings.Contains(stdoutMsg, "Last login")) //first terminal msg should be Last Login
- //assert.Nil(t, HTTPCli.Post("/targets/"+listID[0]+"/terminals/"+terms[0].ID+"/close", terms[0], &term))
- //<-chTermEvt //waiting for event terminalStateChange
-
- ///*open terminals*/
- //PostTerms(t, "open", chTermEvt)
- //termOut = <-chTerm //waiting for terminalOutMsg
- //flushChannelTerm(chTerm, 50) //flushing all terminalOutMsg
- //stdoutMsg = string(termOut.Stdout)
- //if strings.Contains(stdoutMsg, "Connection refused") {
- // t.Fatalf("%vYou may have to launch ssh server", stdoutMsg)
- //} else if strings.Contains(stdoutMsg, "password") {
- // t.Fatalf("%vcopy your pub key in authorized_keys\ncat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys", stdoutMsg)
- //}
- //assert.True(t, strings.Contains(stdoutMsg, "Last login")) //first terminal msg should be Last Login
-
- ///*create toto file through terminals*/
- //rootCfgDir := os.Getenv(envRootCfgDir)
- //totoFile := path.Join(rootCfgDir, "toto")
-
- ///*test with 2 terminals*/
- //for i := 0; i < 2; i++ {
- // totoFileCurrent := totoFile + strconv.Itoa(i)
- // /*send cmd though term*/
- // data := []byte("echo helloWorld" + strconv.Itoa(i) + " >> " + totoFileCurrent + "\n")
- // Debugf(t, "send following command through terminal: %v", string(data))
- // assert.Nil(t, sCli.Conn.Emit(xsapiv1.TerminalInEvent, data))
- // flushChannelTerm(chTerm, 50) //waiting for terminal msg
-
- // /*check that toto file is created*/
- // _, err := os.Stat(totoFileCurrent)
- // assert.Nil(t, err)
-
- // /*send cmd though term*/
- // data = []byte("cat " + totoFileCurrent + "\n")
- // Debugf(t, "send following command through terminal: %v", string(data))
- // assert.Nil(t, sCli.Conn.Emit(xsapiv1.TerminalInEvent, data))
-
- // <-chTerm //cmd sent
- // termOut = <-chTerm //result of cat cmd
- // flushChannelTerm(chTerm, 50) //flushing what remains
- // /*check that terminal msg is what was written before*/
- // assert.Equal(t, string(termOut.Stdout), "helloWorld"+strconv.Itoa(i)+"\r\n")
- // Debugf(t, "check terminal output msg: %v", string(termOut.Stdout))
- //}
-
- //PostTerms(t, "close", chTermEvt)
+ AddTerms(t, nbTermsByTarget, listID, chTermEvt, sshDir, port)
+
+ /*channel for TerminalOutMsg*/
+ chTerm := make(chan xsapiv1.TerminalOutMsg)
+ defer close(chTerm)
+
+ /*connect on terminalOutMsg event*/
+ sCli.Conn.On(xsapiv1.TerminalOutEvent, func(ev xsapiv1.TerminalOutMsg) {
+ chTerm <- ev
+ })
+
+ /*open terminals*/
+ PostTerms(t, "open", chTermEvt, chTerm, prompt)
+
+ /*create toto file through terminals*/
+ rootCfgDir := os.Getenv(envRootCfgDir)
+ totoFile := path.Join(rootCfgDir, "toto")
+
+ /*test with 2 terminals*/
+ for i := 0; i < 2; i++ {
+ totoFileCurrent := totoFile + strconv.Itoa(i)
+ /*send cmd though term*/
+ data := []byte("echo helloWorld" + strconv.Itoa(i) + " >> " + totoFileCurrent + "\n")
+ Debugf(t, "send following command through terminal: %v", string(data))
+ assert.Nil(t, sCli.Conn.Emit(xsapiv1.TerminalInEvent, data))
+ waitForPrompt(t, chTerm, prompt) //waiting for terminal prompt
+
+ /*check that toto file is created*/
+ _, err := os.Stat(totoFileCurrent)
+ assert.Nil(t, err)
+
+ /*send cmd though term*/
+ data = []byte("cat " + totoFileCurrent + "\n")
+ Debugf(t, "send following command through terminal: %v", string(data))
+ assert.Nil(t, sCli.Conn.Emit(xsapiv1.TerminalInEvent, data))
+
+ <-chTerm //cmd sent
+ termOut := <-chTerm //result of cat cmd
+ waitForPrompt(t, chTerm, prompt) //wait for terminal prompt
+ /*check that terminal msg is what was written before*/
+ assert.Equal(t, string(termOut.Stdout), "helloWorld"+strconv.Itoa(i)+"\r\n")
+ Debugf(t, "check terminal output msg: %v", string(termOut.Stdout))
+ }
+
+ PostTerms(t, "close", chTermEvt, nil, prompt)
/*remove targets and terms*/
RemoveTermsTargets(t, chTarget, chTermEvt)