From 3bea7777ac8f95f29b3a7d2cc08435f0960baf0c Mon Sep 17 00:00:00 2001 From: Jaeryn Chu Date: Mon, 16 Jul 2018 12:07:38 -0700 Subject: [PATCH 1/7] Initial circle ci commit. --- .circleci/config.yml | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 .circleci/config.yml diff --git a/.circleci/config.yml b/.circleci/config.yml new file mode 100644 index 0000000000..0c8b8d3690 --- /dev/null +++ b/.circleci/config.yml @@ -0,0 +1,33 @@ +version: 2 +jobs: + setup-and-test: + docker: + - image: golang:1.9 # need to change to 1.10 + steps: + - checkout + - run: + name: Set + command: | + echo 'export ACN=github.com/Azure/azure-container-networking' >> $BASH_ENV + echo 'export ACNGO=$GOPATH/src/$ACN' >> $BASH_ENV + source $BASH_ENV + echo ${ACN} + echo ${ACNGO} + mkdir --parents ${ACNGO} + mv * ${ACNGO} + cd ${ACNGO} + go get ./... + go test ./cni/ipam/ + #go test ./cnm/network/ + go test ./cns/ipamclient/ + #go test ./cns/restserver/ + go test ./ipam/ + #go test ./log/ + #go test ./netlink/ + go test ./store/ + go test ./telemetry/ +workflows: + version: 2 + setup-and-test: + jobs: + - setup-and-test \ No newline at end of file From 912a1cfe6f44bbb2ecab02654d33a6ac6c0eb9db Mon Sep 17 00:00:00 2001 From: Jaeryn Chu Date: Mon, 16 Jul 2018 15:45:04 -0700 Subject: [PATCH 2/7] Fixing ipam errorf along with setting image with golang version 1.10 --- .circleci/config.yml | 2 +- cnm/ipam/ipam_test.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 0c8b8d3690..3a6239d630 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -2,7 +2,7 @@ version: 2 jobs: setup-and-test: docker: - - image: golang:1.9 # need to change to 1.10 + - image: golang:1.10 steps: - checkout - run: diff --git a/cnm/ipam/ipam_test.go b/cnm/ipam/ipam_test.go index 19eab96333..c83231fe5b 100644 --- a/cnm/ipam/ipam_test.go +++ b/cnm/ipam/ipam_test.go @@ -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 { From 11225c8e71c69bcd9d62ddd378eac38c6310dd1e Mon Sep 17 00:00:00 2001 From: Jaeryn Chu Date: Mon, 16 Jul 2018 15:54:16 -0700 Subject: [PATCH 3/7] Fixing logger_test so that it will work on linux as well. --- .circleci/config.yml | 2 +- log/logger_test.go | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 3a6239d630..8102bf2544 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -22,7 +22,7 @@ jobs: go test ./cns/ipamclient/ #go test ./cns/restserver/ go test ./ipam/ - #go test ./log/ + go test ./log/ #go test ./netlink/ go test ./store/ go test ./telemetry/ diff --git a/log/logger_test.go b/log/logger_test.go index bd9842909d..10128ca91a 100644 --- a/log/logger_test.go +++ b/log/logger_test.go @@ -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.") From 6cb4c3c2c7b22ac1cdd0749913f7c457bd4ea0d5 Mon Sep 17 00:00:00 2001 From: Jaeryn Chu Date: Mon, 16 Jul 2018 16:27:07 -0700 Subject: [PATCH 4/7] Fixing network_test. --- .circleci/config.yml | 50 ++++++++++++---------- cnm/network/network_test.go | 70 ++++++++++++++++++++++++------- cns/restserver/restserver_test.go | 2 +- netlink/netlink_test.go | 2 +- netlink/protocol.go | 2 + network/network_linux.go | 1 - 6 files changed, 87 insertions(+), 40 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 8102bf2544..54e1d21c3c 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -1,33 +1,41 @@ version: 2 jobs: setup-and-test: - docker: - - image: golang:1.10 + # docker: + # - image: golang:1.10 + machine: + image: circleci/classic:latest steps: - checkout - run: - name: Set + name: Setup-and-test command: | - echo 'export ACN=github.com/Azure/azure-container-networking' >> $BASH_ENV - echo 'export ACNGO=$GOPATH/src/$ACN' >> $BASH_ENV - source $BASH_ENV - echo ${ACN} - echo ${ACNGO} - mkdir --parents ${ACNGO} - mv * ${ACNGO} - cd ${ACNGO} + 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 test ./cni/ipam/ - #go test ./cnm/network/ - go test ./cns/ipamclient/ - #go test ./cns/restserver/ - go test ./ipam/ - go test ./log/ - #go test ./netlink/ - go test ./store/ - go test ./telemetry/ + go get github.com/docker/libnetwork/driverapi + 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/ + 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/ workflows: version: 2 - setup-and-test: + run-tests: jobs: - setup-and-test \ No newline at end of file diff --git a/cnm/network/network_test.go b/cnm/network/network_test.go index 4bae7a3424..d9005aa0ab 100644 --- a/cnm/network/network_test.go +++ b/cnm/network/network_test.go @@ -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) { @@ -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, }, }) @@ -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() @@ -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 { @@ -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, @@ -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) } @@ -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) } } @@ -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) @@ -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) + } +} diff --git a/cns/restserver/restserver_test.go b/cns/restserver/restserver_test.go index 1d9c421a62..a0698d3d75 100644 --- a/cns/restserver/restserver_test.go +++ b/cns/restserver/restserver_test.go @@ -71,7 +71,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) } diff --git a/netlink/netlink_test.go b/netlink/netlink_test.go index 14e70494f5..6105c41615 100644 --- a/netlink/netlink_test.go +++ b/netlink/netlink_test.go @@ -11,7 +11,7 @@ import ( const ( ifName = "nltest" ifName2 = "nltest2" - dummyName = "dummy0" + dummyName = "dummy1" ) // AddDummyInterface creates a dummy test interface used during actual tests. diff --git a/netlink/protocol.go b/netlink/protocol.go index b33c13650d..395513303d 100644 --- a/netlink/protocol.go +++ b/netlink/protocol.go @@ -1,6 +1,8 @@ // Copyright 2017 Microsoft. All rights reserved. // MIT License +// +build !windows + package netlink import ( diff --git a/network/network_linux.go b/network/network_linux.go index 65a46bb3f0..5c336a2a2b 100644 --- a/network/network_linux.go +++ b/network/network_linux.go @@ -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 From 6d16b83f4c89ff96a1614e66d77f84b70d84e1ff Mon Sep 17 00:00:00 2001 From: Jaeryn Chu Date: Mon, 30 Jul 2018 15:24:59 -0700 Subject: [PATCH 5/7] Rebased on master. --- .circleci/config.yml | 2 +- cns/imdsclient/imdsclient.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 54e1d21c3c..27c6e74a10 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -28,7 +28,7 @@ jobs: 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/ + #sudo -E env "PATH=$PATH" go test ./cns/restserver/ sudo -E env "PATH=$PATH" go test ./ipam/ sudo -E env "PATH=$PATH" go test ./log/ sudo -E env "PATH=$PATH" go test ./netlink/ diff --git a/cns/imdsclient/imdsclient.go b/cns/imdsclient/imdsclient.go index e0737a0d9f..c4646f39bd 100644 --- a/cns/imdsclient/imdsclient.go +++ b/cns/imdsclient/imdsclient.go @@ -55,7 +55,7 @@ func (imdsClient *ImdsClient) GetPrimaryInterfaceInfoFromHost() (*InterfaceInfo, defer resp.Body.Close() - log.Printf("[Azure CNS] Response received from NMAgent for get interface details: %v", resp.Body) + log.Printf("[Azure CNS] Response received from NMAgent for get interface details: %+v", resp.Body) var doc xmlDocument decoder := xml.NewDecoder(resp.Body) From 8a0c4ac32cca07cbda6e3990e59487991dc75838 Mon Sep 17 00:00:00 2001 From: Jaeryn Chu Date: Wed, 8 Aug 2018 11:00:37 -0700 Subject: [PATCH 6/7] Added some changes in attempt to test cns restserver in mock environment. --- .circleci/config.yml | 9 ++-- cns/dockerclient/dockerclient.go | 4 +- cns/imdsclient/api.go | 8 +-- cns/imdsclient/imdsclient.go | 9 ++-- cns/restserver/restserver_test.go | 89 ++++++++++++++++++++++++++++++- 5 files changed, 102 insertions(+), 17 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 27c6e74a10..38fe0a20be 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -25,15 +25,16 @@ jobs: export PATH=$GOROOT/bin:$PATH go get ./... go get github.com/docker/libnetwork/driverapi - 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/ + 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: diff --git a/cns/dockerclient/dockerclient.go b/cns/dockerclient/dockerclient.go index eba45b5780..227022c99b 100644 --- a/cns/dockerclient/dockerclient.go +++ b/cns/dockerclient/dockerclient.go @@ -9,9 +9,9 @@ import ( "fmt" "net/http" - "github.com/Azure/azure-container-networking/platform" "github.com/Azure/azure-container-networking/cns/imdsclient" "github.com/Azure/azure-container-networking/log" + "github.com/Azure/azure-container-networking/platform" ) const ( @@ -31,7 +31,7 @@ type DockerClient struct { func NewDockerClient(url string) (*DockerClient, error) { return &DockerClient{ connectionURL: url, - imdsClient: &imdsclient.ImdsClient{}, + imdsClient: &imdsclient.ImdsClient{HostQueryURL: imdsclient.HostQueryURL, HostQueryURLForProgrammedVersion: imdsclient.HostQueryURLForProgrammedVersion}, }, nil } diff --git a/cns/imdsclient/api.go b/cns/imdsclient/api.go index f86a8f252f..68bb68fc39 100644 --- a/cns/imdsclient/api.go +++ b/cns/imdsclient/api.go @@ -8,13 +8,15 @@ import ( ) const ( - hostQueryURL = "http://169.254.169.254/machine/plugins?comp=nmagent&type=getinterfaceinfov1" - hostQueryURLForProgrammedVersion = "http://169.254.169.254/machine/plugins/?comp=nmagent&type=NetworkManagement/interfaces/%s/networkContainers/%s/authenticationToken/%s/api-version/%s" + HostQueryURL = "http://169.254.169.254/machine/plugins?comp=nmagent&type=getinterfaceinfov1" + HostQueryURLForProgrammedVersion = "http://169.254.169.254/machine/plugins/?comp=nmagent&type=NetworkManagement/interfaces/%s/networkContainers/%s/authenticationToken/%s/api-version/%s" ) // ImdsClient can be used to connect to VM Host agent in Azure. type ImdsClient struct { - primaryInterface *InterfaceInfo + primaryInterface *InterfaceInfo + HostQueryURL string + HostQueryURLForProgrammedVersion string } // InterfaceInfo specifies the information about an interface as returned by Host Agent. diff --git a/cns/imdsclient/imdsclient.go b/cns/imdsclient/imdsclient.go index c4646f39bd..a22ffc18cb 100644 --- a/cns/imdsclient/imdsclient.go +++ b/cns/imdsclient/imdsclient.go @@ -16,7 +16,7 @@ import ( // GetNetworkContainerInfoFromHost retrieves the programmed version of network container from Host. func (imdsClient *ImdsClient) GetNetworkContainerInfoFromHost(networkContainerID string, primaryAddress string, authToken string, apiVersion string) (*ContainerVersion, error) { log.Printf("[Azure CNS] GetNetworkContainerInfoFromHost") - queryURL := fmt.Sprintf(hostQueryURLForProgrammedVersion, + queryURL := fmt.Sprintf(imdsClient.HostQueryURLForProgrammedVersion, primaryAddress, networkContainerID, authToken, apiVersion) log.Printf("[Azure CNS] Going to query Azure Host for container version @\n %v\n", queryURL) @@ -48,18 +48,15 @@ func (imdsClient *ImdsClient) GetPrimaryInterfaceInfoFromHost() (*InterfaceInfo, log.Printf("[Azure CNS] GetPrimaryInterfaceInfoFromHost") interfaceInfo := &InterfaceInfo{} - resp, err := http.Get(hostQueryURL) + resp, err := http.Get(imdsClient.HostQueryURL) if err != nil { return nil, err } defer resp.Body.Close() - log.Printf("[Azure CNS] Response received from NMAgent for get interface details: %+v", resp.Body) - var doc xmlDocument - decoder := xml.NewDecoder(resp.Body) - err = decoder.Decode(&doc) + err = xml.NewDecoder(resp.Body).Decode(&doc) if err != nil { return nil, err } diff --git a/cns/restserver/restserver_test.go b/cns/restserver/restserver_test.go index a0698d3d75..b55c11d4e3 100644 --- a/cns/restserver/restserver_test.go +++ b/cns/restserver/restserver_test.go @@ -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{ + 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) { @@ -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) @@ -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) + nmAgentServer.AddHandler("machine/plugins/?comp=nmagent&type=NetworkManagement/interfaces/{interface}/networkContainers/{networkContainer}/authenticationToken/{authToken}/api-version/{version}", getContainerInfo) + + 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() From 4a10e8082194f633e88611f974c2a870790381b2 Mon Sep 17 00:00:00 2001 From: Jaeryn Chu Date: Tue, 14 Aug 2018 11:06:07 -0700 Subject: [PATCH 7/7] Reverting some changes that aren't required for working unit tests. --- cns/dockerclient/dockerclient.go | 4 ++-- cns/imdsclient/api.go | 8 +++----- cns/imdsclient/imdsclient.go | 9 ++++++--- netlink/protocol.go | 2 -- 4 files changed, 11 insertions(+), 12 deletions(-) diff --git a/cns/dockerclient/dockerclient.go b/cns/dockerclient/dockerclient.go index 227022c99b..eba45b5780 100644 --- a/cns/dockerclient/dockerclient.go +++ b/cns/dockerclient/dockerclient.go @@ -9,9 +9,9 @@ import ( "fmt" "net/http" + "github.com/Azure/azure-container-networking/platform" "github.com/Azure/azure-container-networking/cns/imdsclient" "github.com/Azure/azure-container-networking/log" - "github.com/Azure/azure-container-networking/platform" ) const ( @@ -31,7 +31,7 @@ type DockerClient struct { func NewDockerClient(url string) (*DockerClient, error) { return &DockerClient{ connectionURL: url, - imdsClient: &imdsclient.ImdsClient{HostQueryURL: imdsclient.HostQueryURL, HostQueryURLForProgrammedVersion: imdsclient.HostQueryURLForProgrammedVersion}, + imdsClient: &imdsclient.ImdsClient{}, }, nil } diff --git a/cns/imdsclient/api.go b/cns/imdsclient/api.go index 68bb68fc39..f86a8f252f 100644 --- a/cns/imdsclient/api.go +++ b/cns/imdsclient/api.go @@ -8,15 +8,13 @@ import ( ) const ( - HostQueryURL = "http://169.254.169.254/machine/plugins?comp=nmagent&type=getinterfaceinfov1" - HostQueryURLForProgrammedVersion = "http://169.254.169.254/machine/plugins/?comp=nmagent&type=NetworkManagement/interfaces/%s/networkContainers/%s/authenticationToken/%s/api-version/%s" + hostQueryURL = "http://169.254.169.254/machine/plugins?comp=nmagent&type=getinterfaceinfov1" + hostQueryURLForProgrammedVersion = "http://169.254.169.254/machine/plugins/?comp=nmagent&type=NetworkManagement/interfaces/%s/networkContainers/%s/authenticationToken/%s/api-version/%s" ) // ImdsClient can be used to connect to VM Host agent in Azure. type ImdsClient struct { - primaryInterface *InterfaceInfo - HostQueryURL string - HostQueryURLForProgrammedVersion string + primaryInterface *InterfaceInfo } // InterfaceInfo specifies the information about an interface as returned by Host Agent. diff --git a/cns/imdsclient/imdsclient.go b/cns/imdsclient/imdsclient.go index a22ffc18cb..e0737a0d9f 100644 --- a/cns/imdsclient/imdsclient.go +++ b/cns/imdsclient/imdsclient.go @@ -16,7 +16,7 @@ import ( // GetNetworkContainerInfoFromHost retrieves the programmed version of network container from Host. func (imdsClient *ImdsClient) GetNetworkContainerInfoFromHost(networkContainerID string, primaryAddress string, authToken string, apiVersion string) (*ContainerVersion, error) { log.Printf("[Azure CNS] GetNetworkContainerInfoFromHost") - queryURL := fmt.Sprintf(imdsClient.HostQueryURLForProgrammedVersion, + queryURL := fmt.Sprintf(hostQueryURLForProgrammedVersion, primaryAddress, networkContainerID, authToken, apiVersion) log.Printf("[Azure CNS] Going to query Azure Host for container version @\n %v\n", queryURL) @@ -48,15 +48,18 @@ func (imdsClient *ImdsClient) GetPrimaryInterfaceInfoFromHost() (*InterfaceInfo, log.Printf("[Azure CNS] GetPrimaryInterfaceInfoFromHost") interfaceInfo := &InterfaceInfo{} - resp, err := http.Get(imdsClient.HostQueryURL) + resp, err := http.Get(hostQueryURL) if err != nil { return nil, err } defer resp.Body.Close() + log.Printf("[Azure CNS] Response received from NMAgent for get interface details: %v", resp.Body) + var doc xmlDocument - err = xml.NewDecoder(resp.Body).Decode(&doc) + decoder := xml.NewDecoder(resp.Body) + err = decoder.Decode(&doc) if err != nil { return nil, err } diff --git a/netlink/protocol.go b/netlink/protocol.go index 395513303d..b33c13650d 100644 --- a/netlink/protocol.go +++ b/netlink/protocol.go @@ -1,8 +1,6 @@ // Copyright 2017 Microsoft. All rights reserved. // MIT License -// +build !windows - package netlink import (