Skip to content

Commit

Permalink
Add E2E tests for different languages (#917)
Browse files Browse the repository at this point in the history
1. go
2. nginx_1.15.6
3. node_v11.5.0
4. php_7.3.5
5. python_3.6.7
6. ruby_2.5.1
7. rust
  • Loading branch information
sanketsudake committed Jul 16, 2019
1 parent b7cb529 commit 8948d92
Show file tree
Hide file tree
Showing 20 changed files with 355 additions and 6 deletions.
24 changes: 19 additions & 5 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,15 @@ jobs:
steps:
- checkout
- run: sudo apt-get update
- run: sudo apt-get install nasm qemu
- run: sudo apt-get install nasm qemu ruby rustc
- run: cd .. && git clone git@github.com:nanovms/ops.git
- run: make
- run: make test-noaccel
- run: curl https://ops.city/get.sh -sSfL | sh
- run:
command: |
OPS_DIR=$HOME/.ops
PATH=$HOME/.ops/bin:$PATH
make test-noaccel
nightly-build:
docker:
Expand All @@ -20,9 +25,14 @@ jobs:
steps:
- checkout
- run: sudo apt-get update
- run: sudo apt-get install nasm qemu
- run: sudo apt-get install nasm qemu ruby rustc
- run: make
- run: make test-noaccel
- run: curl https://ops.city/get.sh -sSfL | sh
- run:
command: |
OPS_DIR=$HOME/.ops
PATH=$HOME/.ops/bin:$PATH
make test-noaccel
- run: echo "deb http://packages.cloud.google.com/apt cloud-sdk-jessie main" | sudo tee -a /etc/apt/sources.list.d/google-cloud-sdk.list
- run: curl https://packages.cloud.google.com/apt/doc/apt-key.gpg | sudo apt-key add -
Expand Down Expand Up @@ -50,11 +60,15 @@ jobs:
- run: brew tap nanovms/homebrew-x86_64-elf
- run: brew install x86_64-elf-binutils
- run: mkdir target-root && cd target-root && wget https://storage.googleapis.com/testmisc/target-root.tar.gz && tar xfvz target-root.tar.gz
- run: curl https://ops.city/get.sh -sSfL | sh
- run:
name: macbuild
environment:
NANOS_TARGET_ROOT: target-root
command: make test-noaccel
command: |
OPS_DIR=$HOME/.ops
PATH=$HOME/.ops/bin:$PATH
make test-noaccel
nightly-build-mac:
macos:
Expand Down
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ Makefile.local
/test/go/.staging/*
/test/go/image
/test/runtime/soop.data
.ruby
test/e2e/go/main
test/e2e/rust/main

# Default build directory
/output
Expand Down
2 changes: 1 addition & 1 deletion test/Makefile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
SUBDIR= unit runtime go
SUBDIR= unit runtime go e2e

# can't do runtime until image build is common...
SUBDIR_SKIP-test= runtime
Expand Down
13 changes: 13 additions & 0 deletions test/e2e/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# Go parameters
GOBUILD= $(GO) build
GOCLEAN= $(GO) clean
GOTEST= $(GO) test
GOGET= $(GO) get
BINARY_NAME= ops

test:
$(GOTEST) -v

.PHONY: test

include ../../rules.mk
130 changes: 130 additions & 0 deletions test/e2e/e2e.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
package e2e

import (
"bytes"
"fmt"
"net/http"
"os"
"os/exec"
"syscall"
"testing"
"time"
)

// AsyncCmdStart runs cmd with asynchronously and returns *exec.Cmd, stdout/stderr as one or err if something blew up
func AsyncCmdStart(cmd string) (command *exec.Cmd, buffer *bytes.Buffer, err error) {
command = exec.Command("/bin/bash", "-c", cmd)
buffer = &bytes.Buffer{}
command.Stdout = buffer
command.Stderr = buffer
command.SysProcAttr = &syscall.SysProcAttr{}
command.SysProcAttr.Setsid = true
err = command.Start()
if err != nil {
return command, buffer, err
}
return command, buffer, nil
}

func KillProcess(command *exec.Cmd) {
pgid, err := syscall.Getpgid(command.Process.Pid)
if err == nil {
syscall.Kill(-pgid, syscall.SIGKILL)
}
command.Wait()
}

func goPrebuild(t *testing.T) {
effect, err := exec.Command("/bin/bash", "-c", "go build main.go").CombinedOutput()
if err != nil {
t.Log(effect)
t.Fatal(err)
}
}

func rubyPrebuild(t *testing.T) {
effect, err := exec.Command("/bin/bash", "-c", "mkdir -p .ruby && export GEM_HOME=.ruby && gem install sinatra --no-rdoc --no-ri").CombinedOutput()
if err != nil {
t.Log(effect)
t.Fatal(err)
}
}

func rustPrebuild(t *testing.T) {
effect, err := exec.Command("/bin/bash", "-c", "rustc http_server.rs -o main").CombinedOutput()
if err != nil {
t.Log(effect)
t.Fatal(err)
}
}

func testPackages(t *testing.T) {
var tests = []struct {
name string
pkg string
dir string
request string
elf string
prebuild func(t *testing.T)
}{
{name: "python_3.6.7", pkg: "python_3.6.7", dir: "python_3.6.7", request: "http://0.0.0.0:8000"},
{name: "node_v11.5.0", pkg: "node_v11.5.0", dir: "node_v11.5.0", request: "http://0.0.0.0:8083"},
{name: "nginx_1.15.6", pkg: "nginx_1.15.6", dir: "nginx_1.15.6", request: "http://0.0.0.0:8084"},
{name: "php_7.3.5", pkg: "php_7.3.5", dir: "php_7.3.5", request: "http://0.0.0.0:9501"},
{name: "ruby_2.5.1", pkg: "ruby_2.5.1", dir: "ruby_2.5.1", request: "http://0.0.0.0:4567", prebuild: rubyPrebuild},
{name: "go", dir: "go", request: "http://0.0.0.0:8080", elf: "main", prebuild: goPrebuild},
{name: "rust", dir: "rust", request: "http://0.0.0.0:8080", elf: "main", prebuild: rustPrebuild},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
var execcmd string
dir, err := os.Getwd()
if err != nil {
t.Fatal(err)
}
defer os.Chdir(dir)
err = os.Chdir(dir + "/" + tt.dir)
if err != nil {
t.Fatal(err)
}
if tt.prebuild != nil {
t.Log("Calling prebuild", tt.name)
tt.prebuild(t)
}
if tt.elf != "" {
execcmd = fmt.Sprintf("ops run %s -c config.json", tt.elf)
} else {
execcmd = fmt.Sprintf("ops load %s -c config.json", tt.pkg)
}
p, buffer, err := AsyncCmdStart(execcmd)
defer KillProcess(p)
if err != nil {
t.Logf("Output: %v", buffer)
t.Fatal(err)
}
time.Sleep(time.Second * 10)
for count := 0; count <= 5; count++ {
resp, err := http.Get(tt.request)
if err != nil {
t.Logf("Output: %v", buffer)
t.Fatal(err)
}
t.Log("Status code", resp.StatusCode)
if resp.StatusCode != 200 {
t.Logf("Output: %v", buffer)
t.Fatalf("Expected 200 but got %v", resp.StatusCode)
}
if resp.ContentLength == 0 {
t.Logf("Output: %v", buffer)
t.Fatalf("Received empty content")
}
}
})
}
}

// RunE2ETests runs all end to end tests
func RunE2ETests(t *testing.T) {
t.Log("Running E2E test")
t.Run("packages", testPackages)
}
7 changes: 7 additions & 0 deletions test/e2e/e2e_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package e2e

import "testing"

func TestE2E(t *testing.T) {
RunE2ETests(t)
}
9 changes: 9 additions & 0 deletions test/e2e/go/config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"Args": ["main"],
"RunConfig": {
"Ports": [8080]
},
"Boot": "../../../output/boot/boot.img",
"Kernel": "../../../output/stage3/bin/stage3.img",
"Mkfs": "../../../output/mkfs/bin/mkfs"
}
14 changes: 14 additions & 0 deletions test/e2e/go/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package main

import (
"fmt"
"net/http"
)

func main() {
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "Hello, you've requested: %s\n", r.URL.Path)
})

http.ListenAndServe(":8080", nil)
}
10 changes: 10 additions & 0 deletions test/e2e/nginx_1.15.6/config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"Files": ["index.html"],
"Dirs": ["usr"],
"RunConfig": {
"Ports": [8084]
},
"Boot": "../../../output/boot/boot.img",
"Kernel": "../../../output/stage3/bin/stage3.img",
"Mkfs": "../../../output/mkfs/bin/mkfs"
}
1 change: 1 addition & 0 deletions test/e2e/nginx_1.15.6/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
test
27 changes: 27 additions & 0 deletions test/e2e/nginx_1.15.6/usr/local/nginx/conf/nginx.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
worker_processes 1;
daemon off;
master_process off;

pid bob.pid;

error_log stderr crit;


events {
worker_connections 1024;
}

http {

access_log off;
error_log off;


server {
listen 8084;

location / {
root /;
}
}
}
9 changes: 9 additions & 0 deletions test/e2e/node_v11.5.0/config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"Args": ["hi.js"],
"RunConfig": {
"Ports": [8083]
},
"Boot": "../../../output/boot/boot.img",
"Kernel": "../../../output/stage3/bin/stage3.img",
"Mkfs": "../../../output/mkfs/bin/mkfs"
}
6 changes: 6 additions & 0 deletions test/e2e/node_v11.5.0/hi.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
var http = require('http');
http.createServer(function (req, res) {
res.writeHead(200, {'Content-Type': 'text/plain'});
res.end('Hello World\n');
}).listen(8083, "0.0.0.0");
console.log('Server running at http://127.0.0.1:8083/');
11 changes: 11 additions & 0 deletions test/e2e/php_7.3.5/b.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<?php
$http = new swoole_http_server("0.0.0.0", 9501, SWOOLE_BASE);
$http->on("start", function ($server) {
echo "Swoole http server is started at http://127.0.0.1:9501\n";
});
$http->on("request", function ($request, $response) {
$response->header("Content-Type", "text/plain");
$response->end("Hello World\n");
});
$http->start();
?>
9 changes: 9 additions & 0 deletions test/e2e/php_7.3.5/config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"Args": ["b.php"],
"RunConfig": {
"Ports": [9501]
},
"Boot": "../../../output/boot/boot.img",
"Kernel": "../../../output/stage3/bin/stage3.img",
"Mkfs": "../../../output/mkfs/bin/mkfs"
}
9 changes: 9 additions & 0 deletions test/e2e/python_3.6.7/config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"Args":["-m", "http.server"],
"RunConfig": {
"Ports": [8000]
},
"Boot": "../../../output/boot/boot.img",
"Kernel": "../../../output/stage3/bin/stage3.img",
"Mkfs": "../../../output/mkfs/bin/mkfs"
}
13 changes: 13 additions & 0 deletions test/e2e/ruby_2.5.1/config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"Args": ["myapp.rb", "-o", "0.0.0.0"],
"Dirs": [".ruby"],
"ENV": {
"GEM_HOME": ".ruby"
},
"RunConfig": {
"Ports": [4567]
},
"Boot": "../../../output/boot/boot.img",
"Kernel": "../../../output/stage3/bin/stage3.img",
"Mkfs": "../../../output/mkfs/bin/mkfs"
}
5 changes: 5 additions & 0 deletions test/e2e/ruby_2.5.1/myapp.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
require 'sinatra'

get '/' do
'Hello World!'
end
9 changes: 9 additions & 0 deletions test/e2e/rust/config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"Args": ["main"],
"RunConfig": {
"Ports": [8080]
},
"Boot": "../../../output/boot/boot.img",
"Kernel": "../../../output/stage3/bin/stage3.img",
"Mkfs": "../../../output/mkfs/bin/mkfs"
}
Loading

0 comments on commit 8948d92

Please sign in to comment.