Skip to content

Commit

Permalink
revert integration tests, they are on their own pr
Browse files Browse the repository at this point in the history
  • Loading branch information
ainghazal committed Feb 11, 2024
1 parent 39a9c9a commit 882725b
Show file tree
Hide file tree
Showing 2 changed files with 242 additions and 0 deletions.
55 changes: 55 additions & 0 deletions tests/integration/extract.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
#!/bin/sh
# (c) Ain Ghazal 2022
# this file converts an inline openvpn config file into
# a standalone config plus separate files for the ca.crt,
# cert.pem and key.pem.

FILE=$1
tail=0

# first lets extract the inline blocks
# ca block
tag=ca
f=ca.crt
sed -n "/<$tag>/,/<\/$tag>/p" $FILE > $f
n=$(wc -l $f | cut -f 1 -d ' ')
tail=$(($tail+n))
cat $f | tail -n $(($n-1)) | head -n $(($n-2)) | tee $f >/dev/null

# key block
tag=key
f=key.pem
sed -n "/<$tag>/,/<\/$tag>/p" $FILE > $f
n=$(wc -l $f | cut -f 1 -d ' ')
tail=$(($tail+n))
cat $f | tail -n $(($n-1)) | head -n $(($n-2)) | tee $f >/dev/null

# cert block
tag=cert
f=cert.pem
sed -n "/<$tag>/,/<\/$tag>/p" $FILE > $f
n=$(wc -l $f | cut -f 1 -d ' ')
tail=$(($tail+n))
cat $f | tail -n $(($n-1)) | head -n $(($n-2)) | tee $f >/dev/null

# tls-auth (ignored)
tag=tls-auth
f=ta.pem
sed -n "/<$tag>/,/<\/$tag>/p" $FILE > $f
n=$(wc -l $f | cut -f 1 -d ' ')
tail=$(($tail+n))
cat $f | tail -n $(($n-4)) | head -n $(($n-5)) | tee $f >/dev/null

all=$(wc -l $FILE | cut -f -1 -d ' ')
cp $FILE config.bk

echo "------------------------"
echo "Config file:"
echo "------------------------"
head -n $(($all-$tail)) $FILE | tee config
echo "------------------------"

# now enable the paths for ca, cert and key
sed -i "s/;ca ca.crt/ca ca.crt/g" config
sed -i "s/;cert cert.pem/cert cert.pem/g" config
sed -i "s/;key key.pem/key key.pem/g" config
187 changes: 187 additions & 0 deletions tests/integration/openvpn_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,187 @@
//build: +integration
package main

import (
"bufio"
"bytes"
"context"
"fmt"
"io/ioutil"
"log"
"net/http"
"os"
"os/exec"
"path/filepath"
"testing"
"time"

"github.com/ory/dockertest/v3"
dc "github.com/ory/dockertest/v3/docker"

"github.com/ooni/minivpn/extras/ping"
"github.com/ooni/minivpn/vpn"
)

const (
parseConfig = "extract.sh"
dockerImage = "ainghazal/openvpn"

Check failure on line 27 in tests/integration/openvpn_test.go

View workflow job for this annotation

GitHub Actions / integration

dockerImage redeclared in this block
dockerTag = "latest"

Check failure on line 28 in tests/integration/openvpn_test.go

View workflow job for this annotation

GitHub Actions / integration

dockerTag redeclared in this block
)

var (
target = "172.17.0.1"

Check failure on line 32 in tests/integration/openvpn_test.go

View workflow job for this annotation

GitHub Actions / integration

target redeclared in this block
count = 3

Check failure on line 33 in tests/integration/openvpn_test.go

View workflow job for this annotation

GitHub Actions / integration

count redeclared in this block
)

func copyFile(src, dst string) error {

Check failure on line 36 in tests/integration/openvpn_test.go

View workflow job for this annotation

GitHub Actions / integration

copyFile redeclared in this block
input, err := ioutil.ReadFile(src)
if err != nil {
fmt.Println(err)
return nil
}

dstFile := filepath.Join(dst, src)
err = ioutil.WriteFile(dstFile, input, 0744)
if err != nil {
fmt.Println("Error creating", dstFile)
return err
}
return nil
}

func launchDocker(cipher, auth string) ([]byte, *dockertest.Pool, *dockertest.Resource, error) {
pool, err := dockertest.NewPool("")
if err != nil {
log.Fatalf("Could not connect to docker: %s", err)
}

options := &dockertest.RunOptions{
Repository: dockerImage,
Tag: dockerTag,
PortBindings: map[dc.Port][]dc.PortBinding{
"1194/udp": {{HostPort: "1194"}},
"8080/tcp": {{HostPort: "8080"}},
},
Env: []string{"OPENVPN_CIPHER=" + cipher, "OPENVPN_AUTH=" + auth},
CapAdd: []string{"NET_ADMIN"},
}
resource, err := pool.RunWithOptions(options)
if err != nil {
log.Fatalf("Could not start resource: %s", err)
}
// exponential backoff-retry, because the application in the container might not be ready to accept connections yet
// the minio client does not do service discovery for you (i.e. it does not check if connection can be established), so we have to use the health check
var config []byte
if err := pool.Retry(func() error {
url := fmt.Sprintf("http://localhost:8080/")
resp, err := http.Get(url)
if err != nil {
return err
}
if resp.StatusCode != http.StatusOK {
return fmt.Errorf("status code not OK")
}
config, err = ioutil.ReadAll(resp.Body)
if err != nil {
panic(err)
}
fmt.Println("Got OpenVPN client config")
return nil
}); err != nil {
log.Fatalf("Could not connect to docker: %s", err)
}
return config, pool, resource, nil
}

func stopContainer(p *dockertest.Pool, res *dockertest.Resource) {
fmt.Println("Stopping container")
if err := p.Purge(res); err != nil {
log.Printf("Could not purge resource: %s\n", err)
}
}

func TestClientAES256GCM(t *testing.T) {
if testing.Short() {
t.Skip("skipping test in short mode.")
}
tmp := t.TempDir()

copyFile(parseConfig, tmp)
os.Chdir(tmp)
err := os.Chmod(parseConfig, 0700)
if err != nil {
log.Fatal(err)
}

config, pool, resource, err := launchDocker("AES-256-GCM", "SHA256")

if err != nil {
log.Fatal(err)
}
// when all test done, time to kill and remove the container
defer stopContainer(pool, resource)

cfgFile, err := ioutil.TempFile(tmp, "minivpn-e2e-")
defer cfgFile.Close()
if err != nil {
log.Fatal("Cannot create temporary file", err)
}
fmt.Println("Config written to: " + cfgFile.Name())

if _, err = cfgFile.Write(config); err != nil {
log.Fatal("Failed to write config to temporary file", err)
}

// execute the extract.sh shell script, to process key blocks piecewise
cmd := exec.Command("./"+parseConfig, cfgFile.Name())
cmd.Dir = tmp
var out bytes.Buffer
cmd.Stdout = &out
cmd.Run()

if err != nil {
log.Fatal(err)
}

c, err := readLines("config")
fmt.Println("Remote:", c[len(c)-1])
// can assert that this is a remote line

// actual test begins
opt, err := vpn.NewOptionsFromFilePath(filepath.Join(tmp, "config"))
if err != nil {
log.Fatalf("Could not parse file: %s", err)
}
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
defer cancel()

tunnel := vpn.NewClientFromOptions(opt)
tunnel.Start(ctx)
pinger := ping.New(target, tunnel)
pinger.Count = count
err = pinger.Run(ctx)
defer pinger.Stop()
if err != nil {
log.Fatalf("VPN Error: %s", err)
}
if pinger.PacketLoss() != 0 {
log.Fatalf("packet loss is not zero")
}
// let's assert something wise about the pings
// can we parse the logs? get initialization etc
}

func readLines(f string) ([]string, error) {
var ll []string
rf, err := os.Open(f)
defer rf.Close()
if err != nil {
return ll, err
}
fs := bufio.NewScanner(rf)
fs.Split(bufio.ScanLines)
for fs.Scan() {
ll = append(ll, fs.Text())
}
return ll, nil
}

0 comments on commit 882725b

Please sign in to comment.