Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 42 additions & 0 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
version: 2
jobs:
setup-and-test:
# docker:
# - image: golang:1.10
machine:
image: circleci/classic:latest
steps:
- checkout
- run:
name: Setup-and-test
command: |
sudo -E env "PATH=$PATH" apt-get update
sudo -E env "PATH=$PATH" apt-get install -y ebtables
sudo -E env "PATH=$PATH" apt-get install -y ipset
mkdir -p /home/circleci/go1-10
mkdir --parents /home/circleci/.goproject/src/github.com/Azure/azure-container-networking
wget https://storage.googleapis.com/golang/go1.10.2.linux-amd64.tar.gz
tar -C /home/circleci/go1-10 -xvf go1.10.2.linux-amd64.tar.gz
rm go1.10.2.linux-amd64.tar.gz
mv * /home/circleci/.goproject/src/github.com/Azure/azure-container-networking
cd /home/circleci/.goproject/src/github.com/Azure/azure-container-networking
export GOROOT='/home/circleci/go1-10/go'
export GOPATH='/home/circleci/.goproject'
export PATH=$GOROOT/bin:$PATH
go get ./...
go get github.com/docker/libnetwork/driverapi
go get github.com/gorilla/mux
sudo -E env "PATH=$PATH" go test ./ipam/
sudo -E env "PATH=$PATH" go test ./log/
sudo -E env "PATH=$PATH" go test ./netlink/
sudo -E env "PATH=$PATH" go test ./store/
sudo -E env "PATH=$PATH" go test ./telemetry/
sudo -E env "PATH=$PATH" go test ./cni/ipam/
sudo -E env "PATH=$PATH" go test ./cnm/network/
sudo -E env "PATH=$PATH" go test ./cns/ipamclient/
#sudo -E env "PATH=$PATH" go test ./cns/restserver/
workflows:
version: 2
run-tests:
jobs:
- setup-and-test
2 changes: 1 addition & 1 deletion cnm/ipam/ipam_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ func handleIpamQuery(w http.ResponseWriter, r *http.Request) {
// Decodes plugin's responses to test requests.
func decodeResponse(w *httptest.ResponseRecorder, response interface{}) error {
if w.Code != http.StatusOK {
return fmt.Errorf("Request failed with HTTP error %s", w.Code)
return fmt.Errorf("Request failed with HTTP error %d", w.Code)
}

if w.Body == nil {
Expand Down
70 changes: 54 additions & 16 deletions cnm/network/network_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,13 @@ import (
var plugin NetPlugin
var mux *http.ServeMux

var anyInterface = "test0"
var anyInterface = "dummy"
var anySubnet = "192.168.1.0/24"
var ipnet = net.IPNet{IP: net.ParseIP("192.168.1.0"), Mask: net.IPv4Mask(255, 255, 255, 0)}
var networkID = "N1"

// endpoint ID must contain 7 characters
var endpointID = "E1-xxxx"

// Wraps the test run with plugin setup and teardown.
func TestMain(m *testing.M) {
Expand Down Expand Up @@ -52,7 +57,7 @@ func TestMain(m *testing.M) {
err = netlink.AddLink(&netlink.DummyLink{
LinkInfo: netlink.LinkInfo{
Type: netlink.LINK_TYPE_DUMMY,
Name: "dummy",
Name: anyInterface,
},
})

Expand All @@ -67,6 +72,12 @@ func TestMain(m *testing.M) {
os.Exit(4)
}

err = netlink.AddIpAddress(anyInterface, net.ParseIP("192.168.1.4"), &ipnet)
if err != nil {
fmt.Printf("Failed to add test IP address, err:%v.\n", err)
os.Exit(5)
}

// Get the internal http mux as test hook.
mux = plugin.(*netPlugin).Listener.GetMux()

Expand All @@ -83,7 +94,7 @@ func TestMain(m *testing.M) {
// Decodes plugin's responses to test requests.
func decodeResponse(w *httptest.ResponseRecorder, response interface{}) error {
if w.Code != http.StatusOK {
return fmt.Errorf("Request failed with HTTP error %s", w.Code)
return fmt.Errorf("Request failed with HTTP error %d", w.Code)
}

if w.Body == nil {
Expand Down Expand Up @@ -144,7 +155,7 @@ func TestCreateNetwork(t *testing.T) {
_, pool, _ := net.ParseCIDR(anySubnet)

info := &remoteApi.CreateNetworkRequest{
NetworkID: "N1",
NetworkID: networkID,
IPv4Data: []driverApi.IPAMData{
{
Pool: pool,
Expand All @@ -164,23 +175,25 @@ func TestCreateNetwork(t *testing.T) {

err = decodeResponse(w, &resp)

if err != nil || resp.Err != "" {
if err != nil || resp.Response.Err != "" {
t.Errorf("CreateNetwork response is invalid %+v", resp)
}
}

// Tests NetworkDriver.DeleteNetwork functionality.
func TestDeleteNetwork(t *testing.T) {
// Tests NetworkDriver.CreateEndpoint functionality.
func TestCreateEndpoint(t *testing.T) {
var body bytes.Buffer
var resp remoteApi.DeleteNetworkResponse
var resp remoteApi.CreateEndpointResponse

info := &remoteApi.DeleteNetworkRequest{
NetworkID: "N1",
info := &remoteApi.CreateEndpointRequest{
NetworkID: networkID,
EndpointID: endpointID,
Interface: &remoteApi.EndpointInterface{Address: anySubnet},
}

json.NewEncoder(&body).Encode(info)

req, err := http.NewRequest(http.MethodGet, deleteNetworkPath, &body)
req, err := http.NewRequest(http.MethodGet, createEndpointPath, &body)
if err != nil {
t.Fatal(err)
}
Expand All @@ -190,8 +203,8 @@ func TestDeleteNetwork(t *testing.T) {

err = decodeResponse(w, &resp)

if err != nil || resp.Err != "" {
t.Errorf("DeleteNetwork response is invalid %+v", resp)
if err != nil || resp.Response.Err != "" {
t.Errorf("CreateEndpoint response is invalid %+v", resp)
}
}

Expand All @@ -201,8 +214,8 @@ func TestEndpointOperInfo(t *testing.T) {
var resp remoteApi.EndpointInfoResponse

info := &remoteApi.EndpointInfoRequest{
NetworkID: "N1",
EndpointID: "E1",
NetworkID: networkID,
EndpointID: endpointID,
}

json.NewEncoder(&body).Encode(info)
Expand All @@ -216,8 +229,33 @@ func TestEndpointOperInfo(t *testing.T) {
mux.ServeHTTP(w, req)

err = decodeResponse(w, &resp)

if err != nil || resp.Err != "" {
t.Errorf("EndpointOperInfo response is invalid %+v", resp)
}
}

// Tests NetworkDriver.DeleteNetwork functionality.
func TestDeleteNetwork(t *testing.T) {
var body bytes.Buffer
var resp remoteApi.DeleteNetworkResponse

info := &remoteApi.DeleteNetworkRequest{
NetworkID: networkID,
}

json.NewEncoder(&body).Encode(info)

req, err := http.NewRequest(http.MethodGet, deleteNetworkPath, &body)
if err != nil {
t.Fatal(err)
}

w := httptest.NewRecorder()
mux.ServeHTTP(w, req)

err = decodeResponse(w, &resp)

if err != nil || resp.Err != "" {
t.Errorf("DeleteNetwork response is invalid %+v", resp)
}
}
91 changes: 88 additions & 3 deletions cns/restserver/restserver_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,78 @@ package restserver
import (
"bytes"
"encoding/json"
"encoding/xml"
"fmt"
"net/http"
"net/http/httptest"
"net/url"
"os"
"testing"

"github.com/Azure/azure-container-networking/cns"
"github.com/Azure/azure-container-networking/cns/common"
"github.com/Azure/azure-container-networking/cns/imdsclient"
acncommon "github.com/Azure/azure-container-networking/common"
)

var service HTTPService
var mux *http.ServeMux
type IPAddress struct {
XMLName xml.Name `xml:"IPAddress"`
Address string `xml:"Address,attr"`
IsPrimary bool `xml:"IsPrimary,attr"`
}
type IPSubnet struct {
XMLName xml.Name `xml:"IPSubnet"`
Prefix string `xml:"Prefix,attr"`
IPAddress []IPAddress
}

type Interface struct {
XMLName xml.Name `xml:"Interface"`
MacAddress string `xml:"MacAddress,attr"`
IsPrimary bool `xml:"IsPrimary,attr"`
IPSubnet []IPSubnet
}

type xmlDocument struct {
XMLName xml.Name `xml:"Interfaces"`
Interface []Interface
}

var (
service HTTPService
mux *http.ServeMux
hostQueryForProgrammedVersionResponse = `{"httpStatusCode":"200","networkContainerId":"eab2470f-test-test-test-b3cd316979d5","version":"1"}`
hostQueryResponse = xmlDocument{
XMLName: xml.Name{Local: "Interfaces"},
Interface: []Interface{Interface{
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

create some variables to avoid deep nesting for readability.

XMLName: xml.Name{Local: "Interface"},
MacAddress: "*",
IsPrimary: true,
IPSubnet: []IPSubnet{
IPSubnet{XMLName: xml.Name{Local: "IPSubnet"},
Prefix: "10.0.0.0/16",
IPAddress: []IPAddress{
IPAddress{
XMLName: xml.Name{Local: "IPAddress"},
Address: "10.0.0.4",
IsPrimary: true},
}},
},
}},
}
)

func getInterfaceInfo(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/xml")
output, _ := xml.Marshal(hostQueryResponse)
w.Write(output)
}

func getContainerInfo(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json; charset=UTF-8")
w.WriteHeader(http.StatusOK)
w.Write([]byte(hostQueryForProgrammedVersionResponse))
}

// Wraps the test run with service setup and teardown.
func TestMain(m *testing.M) {
Expand All @@ -33,6 +93,11 @@ func TestMain(m *testing.M) {

// Configure test mode.
service.(*httpRestService).Name = "cns-test-server"
service.(*httpRestService).imdsClient.HostQueryURL = imdsclient.HostQueryURL
service.(*httpRestService).imdsClient.HostQueryURLForProgrammedVersion = imdsclient.HostQueryURLForProgrammedVersion
// Following HostQueryURL and HostQueryURLForProgrammedVersion are only for mock environment.
// service.(*httpRestService).imdsClient.HostQueryURL = "http://localhost:9000/getInterface"
// service.(*httpRestService).imdsClient.HostQueryURLForProgrammedVersion = "http://localhost:9000/machine/plugins/?comp=nmagent&type=NetworkManagement/interfaces/%s/networkContainers/%s/authenticationToken/%s/api-version/%s"

// Start the service.
err = service.Start(&config)
Expand All @@ -44,6 +109,26 @@ func TestMain(m *testing.M) {
// Get the internal http mux as test hook.
mux = service.(*httpRestService).Listener.GetMux()

// Setup mock nmagent server
u, err := url.Parse("tcp://localhost:9000")
if err != nil {
fmt.Println(err.Error())
}

nmAgentServer, err := acncommon.NewListener(u)
if err != nil {
fmt.Println(err.Error())
}

nmAgentServer.AddHandler("/getInterface", getInterfaceInfo)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

create flag for const string

nmAgentServer.AddHandler("machine/plugins/?comp=nmagent&type=NetworkManagement/interfaces/{interface}/networkContainers/{networkContainer}/authenticationToken/{authToken}/api-version/{version}", getContainerInfo)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

create flag for const string


err = nmAgentServer.Start(make(chan error, 1))
if err != nil {
fmt.Printf("Failed to start agent, err:%v.\n", err)
return
}

// Run tests.
exitCode := m.Run()

Expand Down Expand Up @@ -71,7 +156,7 @@ func setEnv(t *testing.T) *httptest.ResponseRecorder {
envRequestJSON := new(bytes.Buffer)
json.NewEncoder(envRequestJSON).Encode(envRequest)

req, err := http.NewRequest(http.MethodPost, cns.V1Prefix+cns.SetEnvironmentPath, envRequestJSON)
req, err := http.NewRequest(http.MethodPost, cns.V2Prefix+cns.SetEnvironmentPath, envRequestJSON)
if err != nil {
t.Fatal(err)
}
Expand Down
6 changes: 3 additions & 3 deletions log/logger_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,21 +27,21 @@ func TestLogFileRotatesWhenSizeLimitIsReached(t *testing.T) {

l.Close()

fn := logName + ".log"
fn := l.GetLogDirectory() + logName + ".log"
_, err := os.Stat(fn)
if err != nil {
t.Errorf("Failed to find active log file.")
}
os.Remove(fn)

fn = logName + ".log.1"
fn = l.GetLogDirectory() + logName + ".log.1"
_, err = os.Stat(fn)
if err != nil {
t.Errorf("Failed to find the 1st rotated log file.")
}
os.Remove(fn)

fn = logName + ".log.2"
fn = l.GetLogDirectory() + logName + ".log.2"
_, err = os.Stat(fn)
if err == nil {
t.Errorf("Found the 2nd rotated log file which should have been deleted.")
Expand Down
2 changes: 1 addition & 1 deletion netlink/netlink_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import (
const (
ifName = "nltest"
ifName2 = "nltest2"
dummyName = "dummy0"
dummyName = "dummy1"
)

// AddDummyInterface creates a dummy test interface used during actual tests.
Expand Down
1 change: 0 additions & 1 deletion network/network_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,6 @@ func (nm *networkManager) connectExternalInterface(extIf *externalInterface, nwI
bridge, err := net.InterfaceByName(bridgeName)
if err != nil {
// Create the bridge.

if err := networkClient.CreateBridge(); err != nil {
log.Printf("Error while creating bridge %+v", err)
return err
Expand Down