Implemented unit tests for the generated LXC config

This commit is contained in:
Sam Alba 2013-03-11 19:15:29 -07:00
parent 75d04a5a75
commit 4e5ae88372
4 changed files with 67 additions and 19 deletions

View File

@ -1,9 +1,12 @@
package docker package docker
import ( import (
"bufio"
"fmt" "fmt"
"io" "io"
"io/ioutil" "io/ioutil"
"math/rand"
"os"
"sort" "sort"
"strings" "strings"
"testing" "testing"
@ -561,6 +564,58 @@ func TestEnv(t *testing.T) {
} }
} }
func grepFile(t *testing.T, path string, pattern string) {
f, err := os.Open(path)
if err != nil {
t.Fatal(err)
}
defer f.Close()
r := bufio.NewReader(f)
var (
line string
)
err = nil
for err == nil {
line, err = r.ReadString('\n')
if strings.Contains(line, pattern) == true {
return
}
}
t.Fatalf("grepFile: pattern \"%s\" not found in \"%s\"", pattern, path)
}
func TestLXCConfig(t *testing.T) {
docker, err := newTestDocker()
if err != nil {
t.Fatal(err)
}
// Ram is allocated randomly for testing
rand.Seed(time.Now().UTC().UnixNano())
ramMin := 33554432
ramMax := 536870912
ram := ramMin + rand.Intn(ramMax-ramMin)
container, err := docker.Create(
"config_test",
"/bin/true",
[]string{},
[]string{testLayerPath},
&Config{
Hostname: "foobar",
Ram: int64(ram),
},
)
if err != nil {
t.Fatal(err)
}
defer docker.Destroy(container)
container.generateLXCConfig()
grepFile(t, container.lxcConfigPath, "lxc.utsname = foobar")
grepFile(t, container.lxcConfigPath,
fmt.Sprintf("lxc.cgroup.memory.limit_in_bytes = %d", ram))
grepFile(t, container.lxcConfigPath,
fmt.Sprintf("lxc.cgroup.memory.memsw.limit_in_bytes = %d", ram*2))
}
func BenchmarkRunSequencial(b *testing.B) { func BenchmarkRunSequencial(b *testing.B) {
docker, err := newTestDocker() docker, err := newTestDocker()
if err != nil { if err != nil {

View File

@ -1,13 +1,12 @@
package rcli package rcli
import ( import (
"fmt"
"net/http" "net/http"
"net/url" "net/url"
"path" "path"
"fmt"
) )
// Use this key to encode an RPC call into an URL, // Use this key to encode an RPC call into an URL,
// eg. domain.tld/path/to/method?q=get_user&q=gordon // eg. domain.tld/path/to/method?q=get_user&q=gordon
const ARG_URL_KEY = "q" const ARG_URL_KEY = "q"
@ -16,18 +15,16 @@ func URLToCall(u *url.URL) (method string, args []string) {
return path.Base(u.Path), u.Query()[ARG_URL_KEY] return path.Base(u.Path), u.Query()[ARG_URL_KEY]
} }
func ListenAndServeHTTP(addr string, service Service) error { func ListenAndServeHTTP(addr string, service Service) error {
return http.ListenAndServe(addr, http.HandlerFunc( return http.ListenAndServe(addr, http.HandlerFunc(
func (w http.ResponseWriter, r *http.Request) { func(w http.ResponseWriter, r *http.Request) {
cmd, args := URLToCall(r.URL) cmd, args := URLToCall(r.URL)
if err := call(service, r.Body, &AutoFlush{w}, append([]string{cmd}, args...)...); err != nil { if err := call(service, r.Body, &AutoFlush{w}, append([]string{cmd}, args...)...); err != nil {
fmt.Fprintf(w, "Error: " + err.Error() + "\n") fmt.Fprintf(w, "Error: "+err.Error()+"\n")
} }
})) }))
} }
type AutoFlush struct { type AutoFlush struct {
http.ResponseWriter http.ResponseWriter
} }

View File

@ -1,13 +1,13 @@
package rcli package rcli
import ( import (
"bufio"
"encoding/json"
"fmt"
"io" "io"
"io/ioutil" "io/ioutil"
"net"
"log" "log"
"fmt" "net"
"encoding/json"
"bufio"
) )
// Connect to a remote endpoint using protocol `proto` and address `addr`, // Connect to a remote endpoint using protocol `proto` and address `addr`,
@ -44,7 +44,7 @@ func ListenAndServe(proto, addr string, service Service) error {
go func() { go func() {
if err := Serve(conn, service); err != nil { if err := Serve(conn, service); err != nil {
log.Printf("Error: " + err.Error() + "\n") log.Printf("Error: " + err.Error() + "\n")
fmt.Fprintf(conn, "Error: " + err.Error() + "\n") fmt.Fprintf(conn, "Error: "+err.Error()+"\n")
} }
conn.Close() conn.Close()
}() }()
@ -53,7 +53,6 @@ func ListenAndServe(proto, addr string, service Service) error {
return nil return nil
} }
// Parse an rcli call on a new connection, and pass it to `service` if it // Parse an rcli call on a new connection, and pass it to `service` if it
// is valid. // is valid.
func Serve(conn io.ReadWriter, service Service) error { func Serve(conn io.ReadWriter, service Service) error {
@ -68,4 +67,3 @@ func Serve(conn io.ReadWriter, service Service) error {
} }
return nil return nil
} }

View File

@ -8,13 +8,13 @@ package rcli
// are the usual suspects. // are the usual suspects.
import ( import (
"errors"
"flag"
"fmt" "fmt"
"io" "io"
"reflect"
"flag"
"log" "log"
"reflect"
"strings" "strings"
"errors"
) )
type Service interface { type Service interface {
@ -25,7 +25,6 @@ type Service interface {
type Cmd func(io.ReadCloser, io.Writer, ...string) error type Cmd func(io.ReadCloser, io.Writer, ...string) error
type CmdMethod func(Service, io.ReadCloser, io.Writer, ...string) error type CmdMethod func(Service, io.ReadCloser, io.Writer, ...string) error
func call(service Service, stdin io.ReadCloser, stdout io.Writer, args ...string) error { func call(service Service, stdin io.ReadCloser, stdout io.Writer, args ...string) error {
if len(args) == 0 { if len(args) == 0 {
args = []string{"help"} args = []string{"help"}
@ -63,7 +62,7 @@ func getMethod(service Service, name string) Cmd {
return nil return nil
} }
} }
methodName := "Cmd"+strings.ToUpper(name[:1])+strings.ToLower(name[1:]) methodName := "Cmd" + strings.ToUpper(name[:1]) + strings.ToLower(name[1:])
method, exists := reflect.TypeOf(service).MethodByName(methodName) method, exists := reflect.TypeOf(service).MethodByName(methodName)
if !exists { if !exists {
return nil return nil
@ -91,4 +90,3 @@ func Subcmd(output io.Writer, name, signature, description string) *flag.FlagSet
} }
return flags return flags
} }