瀏覽代碼

Add simple integration test cases

    - Enhance dnet to use codegansta/cli as the frontend
    - Add `container create/rm` commands only in dnet
    - With the above dnet enhancements add more integration tests

Signed-off-by: Jana Radhakrishnan <mrjana@docker.com>
Jana Radhakrishnan 9 年之前
父節點
當前提交
ea4cdf441e

+ 2 - 2
libnetwork/client/client_test.go

@@ -47,8 +47,8 @@ func setupMockHTTPCallback() {
 	srvList = append(srvList, ep)
 	srvList = append(srvList, ep)
 	mockServiceListJSON, _ = json.Marshal(srvList)
 	mockServiceListJSON, _ = json.Marshal(srvList)
 
 
-	var sbxList []sandboxResource
-	sb := sandboxResource{ID: mockSandboxID, ContainerID: mockContainerID}
+	var sbxList []SandboxResource
+	sb := SandboxResource{ID: mockSandboxID, ContainerID: mockContainerID}
 	mockSbJSON, _ = json.Marshal(sb)
 	mockSbJSON, _ = json.Marshal(sb)
 	sbxList = append(sbxList, sb)
 	sbxList = append(sbxList, sb)
 	mockSbListJSON, _ = json.Marshal(sbxList)
 	mockSbListJSON, _ = json.Marshal(sbxList)

+ 2 - 2
libnetwork/client/service.go

@@ -120,7 +120,7 @@ func lookupSandboxID(cli *NetworkCli, containerID string) (string, error) {
 		return "", err
 		return "", err
 	}
 	}
 
 
-	var sandboxList []sandboxResource
+	var sandboxList []SandboxResource
 	err = json.Unmarshal(obj, &sandboxList)
 	err = json.Unmarshal(obj, &sandboxList)
 	if err != nil {
 	if err != nil {
 		return "", err
 		return "", err
@@ -268,7 +268,7 @@ func getBackendID(cli *NetworkCli, servID string) (string, error) {
 	)
 	)
 
 
 	if obj, _, err = readBody(cli.call("GET", "/services/"+servID+"/backend", nil, nil)); err == nil {
 	if obj, _, err = readBody(cli.call("GET", "/services/"+servID+"/backend", nil, nil)); err == nil {
-		var sr sandboxResource
+		var sr SandboxResource
 		if err := json.NewDecoder(bytes.NewReader(obj)).Decode(&sr); err == nil {
 		if err := json.NewDecoder(bytes.NewReader(obj)).Decode(&sr); err == nil {
 			bk = sr.ContainerID
 			bk = sr.ContainerID
 		} else {
 		} else {

+ 4 - 3
libnetwork/client/types.go

@@ -21,8 +21,8 @@ type serviceResource struct {
 	Network string `json:"network"`
 	Network string `json:"network"`
 }
 }
 
 
-// sandboxResource is the body of "get service backend" response message
-type sandboxResource struct {
+// SandboxResource is the body of "get service backend" response message
+type SandboxResource struct {
 	ID          string `json:"id"`
 	ID          string `json:"id"`
 	Key         string `json:"key"`
 	Key         string `json:"key"`
 	ContainerID string `json:"container_id"`
 	ContainerID string `json:"container_id"`
@@ -52,7 +52,8 @@ type serviceAttach struct {
 	SandboxID string `json:"sandbox_id"`
 	SandboxID string `json:"sandbox_id"`
 }
 }
 
 
-type sandboxCreate struct {
+// SandboxCreate is the body of the "post /sandboxes" http request message
+type SandboxCreate struct {
 	ContainerID       string      `json:"container_id"`
 	ContainerID       string      `json:"container_id"`
 	HostName          string      `json:"host_name"`
 	HostName          string      `json:"host_name"`
 	DomainName        string      `json:"domain_name"`
 	DomainName        string      `json:"domain_name"`

+ 146 - 0
libnetwork/cmd/dnet/cmd.go

@@ -0,0 +1,146 @@
+package main
+
+import (
+	"encoding/json"
+	"fmt"
+	"io"
+	"io/ioutil"
+	"net/http"
+	"os"
+
+	"github.com/codegangsta/cli"
+	"github.com/docker/docker/pkg/term"
+	"github.com/docker/libnetwork/client"
+)
+
+var (
+	containerCreateCommand = cli.Command{
+		Name:   "create",
+		Usage:  "Create a container",
+		Action: runContainerCreate,
+	}
+
+	containerRmCommand = cli.Command{
+		Name:   "rm",
+		Usage:  "Remove a container",
+		Action: runContainerRm,
+	}
+
+	containerCommands = []cli.Command{
+		containerCreateCommand,
+		containerRmCommand,
+	}
+
+	dnetCommands = []cli.Command{
+		createDockerCommand("network"),
+		createDockerCommand("service"),
+		{
+			Name:        "container",
+			Usage:       "Container management commands",
+			Subcommands: containerCommands,
+		},
+	}
+)
+
+func runContainerCreate(c *cli.Context) {
+	if len(c.Args()) == 0 {
+		fmt.Printf("Please provide container id argument\n")
+		os.Exit(1)
+	}
+
+	sc := client.SandboxCreate{ContainerID: c.Args()[0]}
+	obj, _, err := readBody(epConn.httpCall("POST", "/sandboxes", sc, nil))
+	if err != nil {
+		fmt.Printf("POST failed during create container: %v\n", err)
+		os.Exit(1)
+	}
+
+	var replyID string
+	err = json.Unmarshal(obj, &replyID)
+	if err != nil {
+		fmt.Printf("Unmarshall of response failed during create container: %v\n", err)
+		os.Exit(1)
+	}
+
+	fmt.Printf("%s\n", replyID)
+
+}
+
+func runContainerRm(c *cli.Context) {
+	var sbList []*client.SandboxResource
+
+	if len(c.Args()) == 0 {
+		fmt.Printf("Please provide container id argument\n")
+		os.Exit(1)
+	}
+
+	obj, _, err := readBody(epConn.httpCall("GET", "/sandboxes?partial-container-id="+c.Args()[0], nil, nil))
+	if err != nil {
+		fmt.Printf("GET failed during container id lookup: %v\n", err)
+		os.Exit(1)
+	}
+
+	err = json.Unmarshal(obj, &sbList)
+	if err != nil {
+		fmt.Printf("Unmarshall of container id lookup response failed: %v", err)
+		os.Exit(1)
+	}
+
+	if len(sbList) == 0 {
+		fmt.Printf("No sandbox for container %s found\n", c.Args()[0])
+		os.Exit(1)
+	}
+
+	_, _, err = readBody(epConn.httpCall("DELETE", "/sandboxes/"+sbList[0].ID, nil, nil))
+	if err != nil {
+		fmt.Printf("DELETE of sandbox id %s failed: %v", sbList[0].ID, err)
+		os.Exit(1)
+	}
+}
+
+func runDockerCommand(c *cli.Context, cmd string) {
+	_, stdout, stderr := term.StdStreams()
+	oldcli := client.NewNetworkCli(stdout, stderr, epConn.httpCall)
+	var args []string
+	args = append(args, cmd)
+	if c.Bool("h") {
+		args = append(args, "--help")
+	} else {
+		args = append(args, c.Args()...)
+	}
+	if err := oldcli.Cmd("dnet", args...); err != nil {
+		fmt.Println(err)
+		os.Exit(1)
+	}
+}
+
+func createDockerCommand(cmd string) cli.Command {
+	return cli.Command{
+		Name:            cmd,
+		Usage:           fmt.Sprintf("%s management commands", cmd),
+		SkipFlagParsing: true,
+		Action: func(c *cli.Context) {
+			runDockerCommand(c, cmd)
+		},
+		Subcommands: []cli.Command{
+			{
+				Name:  "h, -help",
+				Usage: fmt.Sprintf("%s help", cmd),
+			},
+		},
+	}
+}
+
+func readBody(stream io.ReadCloser, hdr http.Header, statusCode int, err error) ([]byte, int, error) {
+	if stream != nil {
+		defer stream.Close()
+	}
+	if err != nil {
+		return nil, statusCode, err
+	}
+	body, err := ioutil.ReadAll(stream)
+	if err != nil {
+		return nil, -1, err
+	}
+	return body, statusCode, nil
+}

+ 14 - 58
libnetwork/cmd/dnet/dnet.go

@@ -10,7 +10,7 @@ import (
 	"os"
 	"os"
 	"strings"
 	"strings"
 
 
-	flag "github.com/docker/docker/pkg/mflag"
+	"github.com/codegangsta/cli"
 	"github.com/docker/docker/pkg/parsers"
 	"github.com/docker/docker/pkg/parsers"
 	"github.com/docker/docker/pkg/reexec"
 	"github.com/docker/docker/pkg/reexec"
 
 
@@ -18,7 +18,6 @@ import (
 	"github.com/docker/docker/pkg/term"
 	"github.com/docker/docker/pkg/term"
 	"github.com/docker/libnetwork"
 	"github.com/docker/libnetwork"
 	"github.com/docker/libnetwork/api"
 	"github.com/docker/libnetwork/api"
-	"github.com/docker/libnetwork/client"
 	"github.com/docker/libnetwork/config"
 	"github.com/docker/libnetwork/config"
 	"github.com/docker/libnetwork/netlabel"
 	"github.com/docker/libnetwork/netlabel"
 	"github.com/docker/libnetwork/options"
 	"github.com/docker/libnetwork/options"
@@ -36,6 +35,8 @@ const (
 	defaultCfgFile    = "/etc/default/libnetwork.toml"
 	defaultCfgFile    = "/etc/default/libnetwork.toml"
 )
 )
 
 
+var epConn *dnetConnection
+
 func main() {
 func main() {
 	if reexec.Init() {
 	if reexec.Init() {
 		return
 		return
@@ -44,7 +45,7 @@ func main() {
 	_, stdout, stderr := term.StdStreams()
 	_, stdout, stderr := term.StdStreams()
 	logrus.SetOutput(stderr)
 	logrus.SetOutput(stderr)
 
 
-	err := dnetCommand(stdout, stderr)
+	err := dnetApp(stdout, stderr)
 	if err != nil {
 	if err != nil {
 		os.Exit(1)
 		os.Exit(1)
 	}
 	}
@@ -89,61 +90,16 @@ func processConfig(cfg *config.Config) []config.Option {
 	return options
 	return options
 }
 }
 
 
-func dnetCommand(stdout, stderr io.Writer) error {
-	flag.Parse()
-
-	if *flHelp {
-		flag.Usage()
-		return nil
-	}
-
-	if *flLogLevel != "" {
-		lvl, err := logrus.ParseLevel(*flLogLevel)
-		if err != nil {
-			fmt.Fprintf(stderr, "Unable to parse logging level: %s\n", *flLogLevel)
-			return err
-		}
-		logrus.SetLevel(lvl)
-	} else {
-		logrus.SetLevel(logrus.InfoLevel)
-	}
-
-	if *flDebug {
-		logrus.SetLevel(logrus.DebugLevel)
-	}
+func dnetApp(stdout, stderr io.Writer) error {
+	app := cli.NewApp()
 
 
-	if *flHost == "" {
-		defaultHost := os.Getenv("DNET_HOST")
-		if defaultHost == "" {
-			// TODO : Add UDS support
-			defaultHost = fmt.Sprintf("tcp://%s:%d", DefaultHTTPHost, DefaultHTTPPort)
-		}
-		*flHost = defaultHost
-	}
+	app.Name = "dnet"
+	app.Usage = "A self-sufficient runtime for container networking."
+	app.Flags = dnetFlags
+	app.Before = processFlags
+	app.Commands = dnetCommands
 
 
-	dc, err := newDnetConnection(*flHost)
-	if err != nil {
-		if *flDaemon {
-			logrus.Error(err)
-		} else {
-			fmt.Fprint(stderr, err)
-		}
-		return err
-	}
-
-	if *flDaemon {
-		err := dc.dnetDaemon()
-		if err != nil {
-			logrus.Errorf("dnet Daemon exited with an error : %v", err)
-		}
-		return err
-	}
-
-	cli := client.NewNetworkCli(stdout, stderr, dc.httpCall)
-	if err := cli.Cmd("dnet", flag.Args()...); err != nil {
-		fmt.Fprintln(stderr, err)
-		return err
-	}
+	app.Run(os.Args)
 	return nil
 	return nil
 }
 }
 
 
@@ -177,8 +133,8 @@ type dnetConnection struct {
 	addr string
 	addr string
 }
 }
 
 
-func (d *dnetConnection) dnetDaemon() error {
-	cfg, err := parseConfig(*flCfgFile)
+func (d *dnetConnection) dnetDaemon(cfgFile string) error {
+	cfg, err := parseConfig(cfgFile)
 	var cOptions []config.Option
 	var cOptions []config.Option
 	if err == nil {
 	if err == nil {
 		cOptions = processConfig(cfg)
 		cOptions = processConfig(cfg)

+ 0 - 132
libnetwork/cmd/dnet/dnet_test.go

@@ -1,132 +0,0 @@
-package main
-
-import (
-	"fmt"
-	"io/ioutil"
-	"os"
-	"testing"
-	"time"
-
-	"github.com/docker/libnetwork/testutils"
-)
-
-const dnetCommandName = "dnet"
-
-var origStdOut = os.Stdout
-
-func TestDnetDaemonCustom(t *testing.T) {
-	if !testutils.IsRunningInContainer() {
-		t.Skip("This test must run inside a container ")
-	}
-	customPort := 4567
-	doneChan := make(chan bool)
-	go func() {
-		args := []string{dnetCommandName, "-d", fmt.Sprintf("-H=:%d", customPort)}
-		executeDnetCommand(t, args, true)
-		doneChan <- true
-	}()
-
-	select {
-	case <-doneChan:
-		t.Fatal("dnet Daemon is not supposed to exit")
-	case <-time.After(3 * time.Second):
-		args := []string{dnetCommandName, "-d=false", fmt.Sprintf("-H=:%d", customPort), "-D", "network", "ls"}
-		executeDnetCommand(t, args, true)
-	}
-}
-
-func TestDnetDaemonInvalidCustom(t *testing.T) {
-	if !testutils.IsRunningInContainer() {
-		t.Skip("This test must run inside a container ")
-	}
-	customPort := 4668
-	doneChan := make(chan bool)
-	go func() {
-		args := []string{dnetCommandName, "-d=true", fmt.Sprintf("-H=:%d", customPort)}
-		executeDnetCommand(t, args, true)
-		doneChan <- true
-	}()
-
-	select {
-	case <-doneChan:
-		t.Fatal("dnet Daemon is not supposed to exit")
-	case <-time.After(3 * time.Second):
-		args := []string{dnetCommandName, "-d=false", "-H=:6669", "-D", "network", "ls"}
-		executeDnetCommand(t, args, false)
-	}
-}
-
-func TestDnetDaemonInvalidParams(t *testing.T) {
-	if !testutils.IsRunningInContainer() {
-		t.Skip("This test must run inside a container ")
-	}
-	args := []string{dnetCommandName, "-d=false", "-H=tcp:/127.0.0.1:8080"}
-	executeDnetCommand(t, args, false)
-
-	args = []string{dnetCommandName, "-d=false", "-H=unix://var/run/dnet.sock"}
-	executeDnetCommand(t, args, false)
-
-	args = []string{dnetCommandName, "-d=false", "-H=", "-l=invalid"}
-	executeDnetCommand(t, args, false)
-
-	args = []string{dnetCommandName, "-d=false", "-H=", "-l=error", "invalid"}
-	executeDnetCommand(t, args, false)
-}
-
-func TestDnetDefaultsWithFlags(t *testing.T) {
-	if !testutils.IsRunningInContainer() {
-		t.Skip("This test must run inside a container ")
-	}
-	doneChan := make(chan bool)
-	go func() {
-		args := []string{dnetCommandName, "-d=true", "-H=", "-l=error"}
-		executeDnetCommand(t, args, true)
-		doneChan <- true
-	}()
-
-	select {
-	case <-doneChan:
-		t.Fatal("dnet Daemon is not supposed to exit")
-	case <-time.After(3 * time.Second):
-		args := []string{dnetCommandName, "-d=false", "network", "create", "-d=null", "test"}
-		executeDnetCommand(t, args, true)
-
-		args = []string{dnetCommandName, "-d=false", "-D", "network", "ls"}
-		executeDnetCommand(t, args, true)
-	}
-}
-
-func TestDnetMain(t *testing.T) {
-	if !testutils.IsRunningInContainer() {
-		t.Skip("This test must run inside a container ")
-	}
-	customPort := 4568
-	doneChan := make(chan bool)
-	go func() {
-		args := []string{dnetCommandName, "-d=true", "-h=false", fmt.Sprintf("-H=:%d", customPort)}
-		os.Args = args
-		main()
-		doneChan <- true
-	}()
-	select {
-	case <-doneChan:
-		t.Fatal("dnet Daemon is not supposed to exit")
-	case <-time.After(2 * time.Second):
-	}
-}
-
-func executeDnetCommand(t *testing.T, args []string, shouldSucced bool) {
-	_, w, _ := os.Pipe()
-	os.Stdout = w
-
-	os.Args = args
-	err := dnetCommand(ioutil.Discard, ioutil.Discard)
-	if shouldSucced && err != nil {
-		os.Stdout = origStdOut
-		t.Fatalf("cli [%v] must succeed, but failed with an error :  %v", args, err)
-	} else if !shouldSucced && err == nil {
-		os.Stdout = origStdOut
-		t.Fatalf("cli [%v] must fail, but succeeded with an error :  %v", args, err)
-	}
-	os.Stdout = origStdOut
-}

+ 67 - 31
libnetwork/cmd/dnet/flags.go

@@ -4,48 +4,84 @@ import (
 	"fmt"
 	"fmt"
 	"os"
 	"os"
 
 
-	flag "github.com/docker/docker/pkg/mflag"
+	"github.com/Sirupsen/logrus"
+	"github.com/codegangsta/cli"
 )
 )
 
 
-type command struct {
-	name        string
-	description string
-}
-
-type byName []command
-
 var (
 var (
-	flDaemon   = flag.Bool([]string{"d", "-daemon"}, false, "Enable daemon mode")
-	flHost     = flag.String([]string{"H", "-host"}, "", "Daemon socket to connect to")
-	flLogLevel = flag.String([]string{"l", "-log-level"}, "info", "Set the logging level")
-	flDebug    = flag.Bool([]string{"D", "-debug"}, false, "Enable debug mode")
-	flCfgFile  = flag.String([]string{"c", "-cfg-file"}, "/etc/default/libnetwork.toml", "Configuration file")
-	flHelp     = flag.Bool([]string{"h", "-help"}, false, "Print usage")
-
-	dnetCommands = []command{
-		{"network", "Network management commands"},
-		{"service", "Service management commands"},
+	dnetFlags = []cli.Flag{
+		cli.BoolFlag{
+			Name:  "d, -daemon",
+			Usage: "Enable daemon mode",
+		},
+		cli.StringFlag{
+			Name:  "H, -host",
+			Value: "",
+			Usage: "Daemon socket to connect to",
+		},
+		cli.StringFlag{
+			Name:  "l, -log-level",
+			Value: "info",
+			Usage: "Set the logging level",
+		},
+		cli.BoolFlag{
+			Name:  "D, -debug",
+			Usage: "Enable debug mode",
+		},
+		cli.StringFlag{
+			Name:  "c, -cfg-file",
+			Value: "/etc/default/libnetwork.toml",
+			Usage: "Configuration file",
+		},
 	}
 	}
 )
 )
 
 
-func init() {
-	flag.Usage = func() {
-		fmt.Fprint(os.Stdout, "Usage: dnet [OPTIONS] COMMAND [arg...]\n\nA self-sufficient runtime for container networking.\n\nOptions:\n")
+func processFlags(c *cli.Context) error {
+	var err error
+
+	if c.String("l") != "" {
+		lvl, err := logrus.ParseLevel(c.String("l"))
+		if err != nil {
+			fmt.Printf("Unable to parse logging level: %s\n", c.String("l"))
+			os.Exit(1)
+		}
+		logrus.SetLevel(lvl)
+	} else {
+		logrus.SetLevel(logrus.InfoLevel)
+	}
 
 
-		flag.CommandLine.SetOutput(os.Stdout)
-		flag.PrintDefaults()
+	if c.Bool("D") {
+		logrus.SetLevel(logrus.DebugLevel)
+	}
 
 
-		help := "\nCommands:\n"
+	hostFlag := c.String("H")
+	if hostFlag == "" {
+		defaultHost := os.Getenv("DNET_HOST")
+		if defaultHost == "" {
+			// TODO : Add UDS support
+			defaultHost = fmt.Sprintf("tcp://%s:%d", DefaultHTTPHost, DefaultHTTPPort)
+		}
+		hostFlag = defaultHost
+	}
 
 
-		for _, cmd := range dnetCommands {
-			help += fmt.Sprintf("    %-10.10s%s\n", cmd.name, cmd.description)
+	epConn, err = newDnetConnection(hostFlag)
+	if err != nil {
+		if c.Bool("d") {
+			logrus.Error(err)
+		} else {
+			fmt.Println(err)
 		}
 		}
+		os.Exit(1)
+	}
 
 
-		help += "\nRun 'dnet COMMAND --help' for more information on a command."
-		fmt.Fprintf(os.Stdout, "%s\n", help)
+	if c.Bool("d") {
+		err = epConn.dnetDaemon(c.String("c"))
+		if err != nil {
+			logrus.Errorf("dnet Daemon exited with an error : %v", err)
+			os.Exit(1)
+		}
+		os.Exit(1)
 	}
 	}
-}
 
 
-func printUsage() {
-	fmt.Println("Usage: dnet <OPTIONS> COMMAND [arg...]")
+	return nil
 }
 }

+ 31 - 0
libnetwork/test/integration/dnet/dnet.bats

@@ -0,0 +1,31 @@
+#!/usr/bin/env bats
+
+load helpers
+
+@test "Test dnet custom port" {
+    start_dnet 1 a none null 4567
+    dnet_cmd 4567 network ls
+    stop_dnet 1 a
+}
+
+@test "Test dnet invalid custom port" {
+    start_dnet 1 b none null 4567
+    run dnet_cmd 4568 network ls
+    echo ${output}
+    [ "$status" -ne 0 ]
+    stop_dnet 1 b
+}
+
+@test "Test dnet invalid params" {
+    start_dnet 1 c none null
+    run dnet_cmd 8080 network ls
+    echo ${output}
+    [ "$status" -ne 0 ]
+    run ./cmd/dnet/dnet -H=unix://var/run/dnet.sock network ls
+    echo ${output}
+    [ "$status" -ne 0 ]
+    run ./cmd/dnet/dnet -H= -l=invalid network ls
+    echo ${output}
+    [ "$status" -ne 0 ]
+    stop_dnet 1 c
+}

+ 51 - 11
libnetwork/test/integration/dnet/helpers.bash

@@ -1,10 +1,21 @@
+function inst_id2port() {
+    echo $((41000+${1}-1))
+}
+
 function start_consul() {
 function start_consul() {
     stop_consul
     stop_consul
-    docker run -d --name=pr_consul -p 8500:8500 -p 8300-8302:8300-8302/tcp -p 8300-8302:8300-8302/udp -h consul progrium/consul -server -bootstrap
+    docker run -d \
+	   --name=pr_consul \
+	   -p 8500:8500 \
+	   -p 8300-8302:8300-8302/tcp \
+	   -p 8300-8302:8300-8302/udp \
+	   -h consul \
+	   progrium/consul -server -bootstrap
     sleep 2
     sleep 2
 }
 }
 
 
 function stop_consul() {
 function stop_consul() {
+    echo "consul started"
     docker stop pr_consul || true
     docker stop pr_consul || true
     # You cannot destroy a container in Circle CI. So do not attempt destroy in circleci
     # You cannot destroy a container in Circle CI. So do not attempt destroy in circleci
     if [ -z "$CIRCLECI" ]; then
     if [ -z "$CIRCLECI" ]; then
@@ -13,11 +24,19 @@ function stop_consul() {
 }
 }
 
 
 function start_dnet() {
 function start_dnet() {
-    stop_dnet $1
-    name="dnet-$1"
-    hport=$((41000+${1}-1))
+    stop_dnet $1 $2
+    name="dnet-$1-$2"
+    if [ -z "$5" ]
+    then
+	hport=$((41000+${1}-1))
+	cport=2385
+	hopt=""
+    else
+	hport=$5
+	cport=$5
+	hopt="-H tcp://0.0.0.0:${cport}"
+    fi
 
 
-    bridge_ip=$(docker inspect --format '{{.NetworkSettings.Gateway}}' pr_consul)
     mkdir -p /tmp/dnet/${name}
     mkdir -p /tmp/dnet/${name}
     tomlfile="/tmp/dnet/${name}/libnetwork.toml"
     tomlfile="/tmp/dnet/${name}/libnetwork.toml"
     cat > ${tomlfile} <<EOF
     cat > ${tomlfile} <<EOF
@@ -25,21 +44,42 @@ title = "LibNetwork Configuration file"
 
 
 [daemon]
 [daemon]
   debug = false
   debug = false
-  defaultnetwork = "${2}"
-  defaultdriver = "${3}"
+  defaultnetwork = "${3}"
+  defaultdriver = "${4}"
   labels = ["com.docker.network.driver.overlay.bind_interface=eth0"]
   labels = ["com.docker.network.driver.overlay.bind_interface=eth0"]
 [datastore]
 [datastore]
   embedded = false
   embedded = false
+EOF
+    if [ "${4}" == "overlay" ]
+    then
+	bridge_ip=$(docker inspect --format '{{.NetworkSettings.Gateway}}' pr_consul)
+	cat >> ${tomlfile} <<EOF
 [datastore.client]
 [datastore.client]
   provider = "consul"
   provider = "consul"
   Address = "${bridge_ip}:8500"
   Address = "${bridge_ip}:8500"
 EOF
 EOF
-    docker run -d --name=${name}  --privileged -p ${hport}:2385 -v $(pwd)/:/go/src/github.com/docker/libnetwork -v /tmp:/tmp -w /go/src/github.com/docker/libnetwork golang:1.4 ./cmd/dnet/dnet -dD -c ${tomlfile}
+    fi
+
+    docker run \
+	   -d \
+	   --name=${name}  \
+	   --privileged \
+	   -p ${hport}:${cport} \
+	   -v $(pwd)/:/go/src/github.com/docker/libnetwork \
+	   -v /tmp:/tmp \
+	   -w /go/src/github.com/docker/libnetwork \
+	   golang:1.4 ./cmd/dnet/dnet -d -D ${hopt} -c ${tomlfile}
     sleep 2
     sleep 2
 }
 }
 
 
+function skip_for_circleci() {
+    if [ -n "$CIRCLECI" ]; then
+	skip
+    fi
+}
+
 function stop_dnet() {
 function stop_dnet() {
-    name="dnet-$1"
+    name="dnet-$1-$2"
     rm -rf /tmp/dnet/${name} || true
     rm -rf /tmp/dnet/${name} || true
     docker stop ${name} || true
     docker stop ${name} || true
     # You cannot destroy a container in Circle CI. So do not attempt destroy in circleci
     # You cannot destroy a container in Circle CI. So do not attempt destroy in circleci
@@ -50,7 +90,7 @@ function stop_dnet() {
 }
 }
 
 
 function dnet_cmd() {
 function dnet_cmd() {
-    hport=$((41000+${1}-1))
+    hport=$1
     shift
     shift
-    ./cmd/dnet/dnet -H 127.0.0.1:${hport} $*
+    ./cmd/dnet/dnet -H tcp://127.0.0.1:${hport} $*
 }
 }

+ 75 - 10
libnetwork/test/integration/dnet/simple.bats

@@ -2,28 +2,24 @@
 
 
 load helpers
 load helpers
 
 
-export BATS_TEST_CNT=0
-
 function setup() {
 function setup() {
-    if [ "${BATS_TEST_CNT}" -eq 0 ]; then
+    if [ "${BATS_TEST_NUMBER}" -eq 1 ]; then
 	start_consul
 	start_consul
-	start_dnet 1 multihost overlay
-	export BATS_TEST_CNT=$((${BATS_TEST_CNT}+1))
+	start_dnet 1 simple multihost overlay
     fi
     fi
 }
 }
 
 
 function teardown() {
 function teardown() {
-    export BATS_TEST_CNT=$((${BATS_TEST_CNT}-1))
-    if [ "${BATS_TEST_CNT}" -eq 0 ]; then
-	stop_dnet 1
+    if [ "${BATS_TEST_NUMBER}" -eq 6 ]; then
+	stop_dnet 1 simple
 	stop_consul
 	stop_consul
     fi
     fi
 }
 }
 
 
-
 @test "Test default network" {
 @test "Test default network" {
     echo $(docker ps)
     echo $(docker ps)
-    run dnet_cmd 1 network ls
+    run dnet_cmd $(inst_id2port 1) network ls
+    [ "$status" -eq 0 ]
     echo ${output}
     echo ${output}
     echo ${lines[1]}
     echo ${lines[1]}
     name=$(echo ${lines[1]} | cut -d" " -f2)
     name=$(echo ${lines[1]} | cut -d" " -f2)
@@ -32,3 +28,72 @@ function teardown() {
     [ "$name" = "multihost" ]
     [ "$name" = "multihost" ]
     [ "$driver" = "overlay" ]
     [ "$driver" = "overlay" ]
 }
 }
+
+@test "Test network create" {
+    echo $(docker ps)
+    run dnet_cmd $(inst_id2port 1) network create -d overlay mh1
+    [ "$status" -eq 0 ]
+    line=$(dnet_cmd $(inst_id2port 1) network ls | grep mh1)
+    echo ${line}
+    name=$(echo ${line} | cut -d" " -f2)
+    driver=$(echo ${line} | cut -d" " -f3)
+    echo ${name} ${driver}
+    [ "$name" = "mh1" ]
+    [ "$driver" = "overlay" ]
+    dnet_cmd $(inst_id2port 1) network rm mh1
+}
+
+@test "Test network delete with id" {
+    echo $(docker ps)
+    run dnet_cmd $(inst_id2port 1) network create -d overlay mh1
+    [ "$status" -eq 0 ]
+    echo ${output}
+    dnet_cmd $(inst_id2port 1) network rm ${output}
+}
+
+@test "Test service create" {
+    echo $(docker ps)
+    run dnet_cmd $(inst_id2port 1) service publish svc1.multihost
+    [ "$status" -eq 0 ]
+    echo ${output}
+    run dnet_cmd $(inst_id2port 1) service ls
+    [ "$status" -eq 0 ]
+    echo ${output}
+    echo ${lines[1]}
+    svc=$(echo ${lines[1]} | cut -d" " -f2)
+    network=$(echo ${lines[1]} | cut -d" " -f3)
+    echo ${svc} ${network}
+    [ "$network" = "multihost" ]
+    [ "$svc" = "svc1" ]
+    dnet_cmd $(inst_id2port 1) service unpublish svc1.multihost
+}
+
+@test "Test service delete with id" {
+    echo $(docker ps)
+    run dnet_cmd $(inst_id2port 1) service publish svc1.multihost
+    [ "$status" -eq 0 ]
+    echo ${output}
+    run dnet_cmd $(inst_id2port 1) service ls
+    [ "$status" -eq 0 ]
+    echo ${output}
+    echo ${lines[1]}
+    id=$(echo ${lines[1]} | cut -d" " -f1)
+    dnet_cmd $(inst_id2port 1) service unpublish ${id}
+}
+
+@test "Test service attach" {
+    skip_for_circleci
+    echo $(docker ps)
+    dnet_cmd $(inst_id2port 1) service publish svc1.multihost
+    dnet_cmd $(inst_id2port 1) container create container_1
+    dnet_cmd $(inst_id2port 1) service attach container_1 svc1.multihost
+    run dnet_cmd $(inst_id2port 1) service ls
+    [ "$status" -eq 0 ]
+    echo ${output}
+    echo ${lines[1]}
+    container=$(echo ${lines[1]} | cut -d" " -f4)
+    [ "$container" = "container_1" ]
+    dnet_cmd $(inst_id2port 1) service detach container_1 svc1.multihost
+    dnet_cmd $(inst_id2port 1) container rm container_1
+    dnet_cmd $(inst_id2port 1) service unpublish svc1.multihost
+}