add working dir e2e test

This commit is contained in:
Boshi Lian 2022-07-07 06:56:41 +00:00
parent 607c3d05eb
commit 96dc3be75e
5 changed files with 324 additions and 53 deletions

View file

@ -1,4 +1,4 @@
name: Go
name: Go Unit Test
on:
push:

View file

@ -9,6 +9,15 @@ services:
- USER_NAME=user
volumes:
- shared:/shared
- sshconfig_password:/config
host-publickey:
image: lscr.io/linuxserver/openssh-server:latest
environment:
- USER_NAME=user
volumes:
- shared:/shared
- sshconfig_publickey:/config
piper-fixed:
environment:
@ -22,6 +31,21 @@ services:
depends_on:
- host-password
piper-workingdir:
environment:
- SSHPIPERD_LOG_LEVEL=trace
- SSHPIPERD_WORKINGDIR_STRICTHOSTKEY=true
volumes:
- shared:/shared
build: ../
command:
- "/sshpiperd/sshpiperd"
- "/sshpiperd/plugins/workingdir"
- "--root"
- "/shared/workingdir"
depends_on:
- host-password
- host-publickey
testrunner:
environment:
@ -32,14 +56,20 @@ services:
volumes:
- ..:/src
- shared:/shared
command: ["go", "test", "-v"]
- sshconfig_publickey:/sshconfig_publickey
- sshconfig_password:/sshconfig_password
command: ["bash", "-c", "if [ \"${SSHPIPERD_DEBUG}\" == \"1\" ]; then sleep infinity; else go test -v; fi"]
working_dir: /src/e2e
depends_on:
- host-password
- piper-fixed
- piper-workingdir
volumes:
shared:
driver_opts:
type: tmpfs
device: tmpfs
device: tmpfs
sshconfig_publickey:
sshconfig_password:

43
e2e/fixed_test.go Normal file
View file

@ -0,0 +1,43 @@
package e2e_test
import (
"fmt"
"testing"
"time"
"github.com/google/uuid"
)
func TestFixed(t *testing.T) {
waitForEndpointReady("piper-fixed:2222")
randtext := uuid.New().String()
targetfie := uuid.New().String()
c, stdin, stdout, err := runCmd(
"ssh",
"-v",
"-o",
"StrictHostKeyChecking=no",
"-o",
"UserKnownHostsFile=/dev/null",
"-p",
"2222",
"-l",
"user",
"piper-fixed",
fmt.Sprintf(`sh -c "echo -n %v > /shared/%v"`, randtext, targetfie),
)
if err != nil {
t.Errorf("failed to ssh to piper-fixed, %v", err)
}
defer killCmd(c)
enterPassword(stdin, stdout, "pass")
time.Sleep(time.Second) // wait for file flush
checkSharedFileContent(t, targetfie, randtext)
}

View file

@ -17,7 +17,6 @@ import (
"time"
"github.com/creack/pty"
"github.com/google/uuid"
)
const waitTimeout = time.Second * 10
@ -55,15 +54,18 @@ func runCmd(cmd string, args ...string) (*exec.Cmd, io.Writer, io.Reader, error)
log.Printf("starting %v", c.Args)
go func() {
if err := c.Wait(); err != nil {
log.Printf("wait %v returns %v", c.Args, err)
}
}()
return c, f, &buf, nil
}
func runCmdAndWait(cmd string, args ...string) error {
c, _, _, err := runCmd(cmd, args...)
if err != nil {
return err
}
return c.Wait()
}
func enterPassword(stdin io.Writer, stdout io.Reader, password string) {
st := time.Now()
for {
@ -97,10 +99,32 @@ func checkSharedFileContent(t *testing.T, targetfie string, expected string) {
}
if string(b) != expected {
t.Errorf("shared file content mismathc, expected %v, got %v", expected, string(b))
t.Errorf("shared file content mismatch, expected %v, got %v", expected, string(b))
}
}
func killCmd(c *exec.Cmd) {
if c.Process != nil {
if err := c.Process.Kill(); err != nil {
log.Printf("failed to kill ssh process, %v", err)
}
}
}
func runAndGetStdout(cmd string, args ...string) ([]byte, error) {
c, _, stdout, err := runCmd(cmd, args...)
if err != nil {
return nil, err
}
if err := c.Wait(); err != nil {
return nil, err
}
return io.ReadAll(stdout)
}
func TestMain(m *testing.M) {
if os.Getenv("SSHPIPERD_E2E_TEST") != "1" {
@ -109,53 +133,14 @@ func TestMain(m *testing.M) {
return
}
_, _, _, _ = runCmd("ssh", "-V")
_ = runCmdAndWait("ssh", "-V")
for _, ep := range []string{
"host-password:2222",
"host-publickey:2222",
} {
waitForEndpointReady(ep)
}
os.Exit(m.Run())
}
func TestFixed(t *testing.T) {
waitForEndpointReady("piper-fixed:2222")
randtext := uuid.New().String()
targetfie := uuid.New().String()
c, stdin, stdout, err := runCmd(
"ssh",
"-v",
"-o",
"StrictHostKeyChecking=no",
"-o",
"UserKnownHostsFile=/dev/null",
"-p",
"2222",
"-l",
"user",
"piper-fixed",
fmt.Sprintf(`sh -c "echo -n %v > /shared/%v"`, randtext, targetfie),
)
if err != nil {
t.Errorf("failed to ssh to piper-fixed, %v", err)
}
defer func() {
if c.Process != nil {
if err = c.Process.Kill(); err != nil {
log.Printf("failed to kill ssh process, %v", err)
}
}
}()
enterPassword(stdin, stdout, "pass")
time.Sleep(time.Second) // wait for file flush
checkSharedFileContent(t, targetfie, randtext)
}

213
e2e/workingdir_test.go Normal file
View file

@ -0,0 +1,213 @@
package e2e_test
import (
"fmt"
"io/ioutil"
"log"
"os"
"path"
"testing"
"time"
"github.com/google/uuid"
)
const workingdir = "/shared/workingdir"
func ensureWorkingDirectory() {
err := os.MkdirAll(workingdir, 0700)
if err != nil {
log.Panicf("failed to create working directory %s: %v", workingdir, err)
}
}
func TestWorkingDirectory(t *testing.T) {
ensureWorkingDirectory()
waitForEndpointReady("piper-workingdir:2222")
t.Run("bypassword", func(t *testing.T) {
userdir := path.Join(workingdir, "bypassword")
{
if err := os.MkdirAll(userdir, 0700); err != nil {
t.Errorf("failed to create working directory %s: %v", userdir, err)
}
if err := ioutil.WriteFile(path.Join(userdir, "sshpiper_upstream"), []byte("user@host-password:2222"), 0400); err != nil {
t.Errorf("failed to write upstream file: %v", err)
}
}
{
b, err := runAndGetStdout(
"ssh-keyscan",
"-p",
"2222",
"host-password",
)
if err != nil {
t.Errorf("failed to run ssh-keyscan: %v", err)
}
if err := ioutil.WriteFile(path.Join(userdir, "known_hosts"), b, 0400); err != nil {
t.Errorf("failed to write known_hosts: %v", err)
}
}
{
randtext := uuid.New().String()
targetfie := uuid.New().String()
c, stdin, stdout, err := runCmd(
"ssh",
"-v",
"-o",
"StrictHostKeyChecking=no",
"-o",
"UserKnownHostsFile=/dev/null",
"-p",
"2222",
"-l",
"bypassword",
"piper-workingdir",
fmt.Sprintf(`sh -c "echo -n %v > /shared/%v"`, randtext, targetfie),
)
if err != nil {
t.Errorf("failed to ssh to piper-workingdir, %v", err)
}
defer killCmd(c)
enterPassword(stdin, stdout, "pass")
time.Sleep(time.Second) // wait for file flush
checkSharedFileContent(t, targetfie, randtext)
}
})
t.Run("bypublickey", func(t *testing.T) {
userdir := path.Join(workingdir, "bypublickey")
if err := os.MkdirAll(userdir, 0700); err != nil {
t.Errorf("failed to create working directory %s: %v", userdir, err)
}
if err := ioutil.WriteFile(path.Join(userdir, "sshpiper_upstream"), []byte("user@host-publickey:2222"), 0400); err != nil {
t.Errorf("failed to write upstream file: %v", err)
}
{
b, err := runAndGetStdout(
"ssh-keyscan",
"-p",
"2222",
"host-publickey",
)
if err != nil {
t.Errorf("failed to run ssh-keyscan: %v", err)
}
if err := ioutil.WriteFile(path.Join(userdir, "known_hosts"), b, 0400); err != nil {
t.Errorf("failed to write known_hosts: %v", err)
}
}
keydir, err := os.MkdirTemp("", "")
// generate a local key
if err != nil {
t.Errorf("failed to create temp dir: %v", err)
}
{
if err := runCmdAndWait("rm", "-f", path.Join(keydir, "id_rsa")); err != nil {
t.Errorf("failed to remove id_rsa: %v", err)
}
if err := runCmdAndWait(
"ssh-keygen",
"-N",
"",
"-f",
path.Join(keydir, "id_rsa"),
); err != nil {
t.Errorf("failed to generate private key: %v", err)
}
if err := runCmdAndWait(
"/bin/cp",
path.Join(keydir, "id_rsa.pub"),
path.Join(userdir, "authorized_keys"),
); err != nil {
t.Errorf("failed to copy public key: %v", err)
}
if err := runCmdAndWait(
"chmod",
"0400",
path.Join(userdir, "authorized_keys"),
); err != nil {
t.Errorf("failed to chmod public key: %v", err)
}
// set upstream key
if err := runCmdAndWait("rm", "-f", path.Join(userdir, "id_rsa")); err != nil {
t.Errorf("failed to remove id_rsa: %v", err)
}
if err := runCmdAndWait(
"ssh-keygen",
"-N",
"",
"-f",
path.Join(userdir, "id_rsa"),
); err != nil {
t.Errorf("failed to generate private key: %v", err)
}
if err := runCmdAndWait(
"/bin/cp",
path.Join(userdir, "id_rsa.pub"),
"/sshconfig_publickey/.ssh/authorized_keys",
); err != nil {
t.Errorf("failed to copy public key: %v", err)
}
}
{
randtext := uuid.New().String()
targetfie := uuid.New().String()
c, _, _, err := runCmd(
"ssh",
"-v",
"-o",
"StrictHostKeyChecking=no",
"-o",
"UserKnownHostsFile=/dev/null",
"-p",
"2222",
"-l",
"bypublickey",
"-i",
path.Join(keydir, "id_rsa"),
"piper-workingdir",
fmt.Sprintf(`sh -c "echo -n %v > /shared/%v"`, randtext, targetfie),
)
if err != nil {
t.Errorf("failed to ssh to piper-workingdir, %v", err)
}
defer killCmd(c)
time.Sleep(time.Second) // wait for file flush
checkSharedFileContent(t, targetfie, randtext)
}
})
}