Skip to content

Commit

Permalink
Merge pull request #386 from heschlie/install-cni-tests
Browse files Browse the repository at this point in the history
Adding tests for install-cni.sh
  • Loading branch information
caseydavenport authored Oct 6, 2017
2 parents c7960b8 + 7e43e0b commit 1498db1
Show file tree
Hide file tree
Showing 8 changed files with 273 additions and 9 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,5 @@ delstats
*.pyc
*.created
tmp-cni
k8s-install/scripts/tmp/
install_cni.test
24 changes: 20 additions & 4 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ docker-image: $(DEPLOY_CONTAINER_MARKER)

.PHONY: clean
clean:
rm -rf dist vendor $(DEPLOY_CONTAINER_MARKER) .go-pkg-cache
rm -rf dist vendor $(DEPLOY_CONTAINER_MARKER) .go-pkg-cache k8s-install/scripts/install_cni.test

release: clean
ifndef VERSION
Expand Down Expand Up @@ -92,7 +92,7 @@ dist/calico-ipam: $(SRCFILES) vendor

.PHONY: test
## Run the unit tests.
test: dist/calico dist/calico-ipam dist/host-local run-etcd run-k8s-apiserver
test: dist/calico dist/calico-ipam dist/host-local run-etcd run-k8s-apiserver test-install-cni
# The tests need to run as root
sudo CGO_ENABLED=0 ETCD_IP=127.0.0.1 PLUGIN=calico GOPATH=$(GOPATH) $(shell which ginkgo)

Expand Down Expand Up @@ -129,6 +129,22 @@ test-containerized: run-etcd run-k8s-apiserver build-containerized dist/host-loc
ginkgo'
make stop-etcd

# We pre-build the test binary so that we can run it outside a container and allow it
# to interact with docker.
k8s-install/scripts/install_cni.test: vendor
-mkdir -p .go-pkg-cache
docker run --rm \
-e LOCAL_USER_ID=$(LOCAL_USER_ID) \
-v $(CURDIR):/go/src/github.com/projectcalico/cni-plugin:rw \
-v $(CURDIR)/.go-pkg-cache:/go/pkg/:rw \
$(CALICO_BUILD) sh -c '\
cd /go/src/github.com/projectcalico/cni-plugin && \
go test ./k8s-install/scripts -c --tags install_cni_test -o ./k8s-install/scripts/install_cni.test'

.PHONY: test-install-cni
## Test the install-cni.sh script
test-install-cni: docker-image k8s-install/scripts/install_cni.test
cd k8s-install/scripts && ./install_cni.test

run-test-containerized-without-building: run-etcd run-k8s-apiserver
docker run --rm --privileged --net=host \
Expand Down Expand Up @@ -163,7 +179,7 @@ build-containerized: vendor
$(CALICO_BUILD) sh -c '\
cd /go/src/github.com/projectcalico/cni-plugin && \
make binary'

## Etcd is used by the tests
run-etcd: stop-etcd
docker run --detach \
Expand Down Expand Up @@ -294,7 +310,7 @@ run-kube-proxy:
-docker rm -f calico-kube-proxy
docker run --name calico-kube-proxy -d --net=host --privileged gcr.io/google_containers/hyperkube:v$(K8S_VERSION) /hyperkube proxy --master=http://127.0.0.1:8080 --v=2

ci: clean static-checks test-containerized-cni-versions docker-image
ci: clean static-checks test-containerized-cni-versions docker-image test-install-cni

.PHONY: help
help: # Some kind of magic from https://gist.github.com/rcmachado/af3db315e31383502660
Expand Down
11 changes: 8 additions & 3 deletions glide.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions glide.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -35,3 +35,7 @@ import:
- kubernetes
- tools/clientcmd
- package: github.com/mcuadros/go-version
- package: github.com/projectcalico/felix
subpackages:
- fv
- fv.containers
20 changes: 20 additions & 0 deletions k8s-install/scripts/expected_10-calico.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
"name": "k8s-pod-network",
"type": "calico",
"etcd_endpoints": "",
"etcd_key_file": "",
"etcd_cert_file": "",
"etcd_ca_cert_file": "",
"log_level": "warn",
"ipam": {
"type": "calico-ipam"
},
"policy": {
"type": "k8s",
"k8s_api_root": "https://127.0.0.1:8080",
"k8s_auth_token": "my-secret-key"
},
"kubernetes": {
"kubeconfig": "/etc/cni/net.d/calico-kubeconfig"
}
}
4 changes: 2 additions & 2 deletions k8s-install/scripts/install-cni.sh
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
# - Expects the host CNI network config path to be mounted at /host/etc/cni/net.d.
# - Expects the desired CNI config in the CNI_NETWORK_CONFIG env variable.

# Ensure all variables are defined.
set -u
# Ensure all variables are defined, and that the script fails when an error is hit.
set -u -e

# The directory on the host where CNI networks are installed. Defaults to
# /etc/cni/net.d, but can be overridden by setting CNI_NET_DIR. This is used
Expand Down
204 changes: 204 additions & 0 deletions k8s-install/scripts/install_cni_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,204 @@
package scripts_test

import (
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
"github.com/projectcalico/felix/fv/containers"

"fmt"
"io/ioutil"
"os"
"time"
)

var secretFile = "tmp/serviceaccount/token"

// runCniContainer will run install-cni.sh.
// TODO: We should be returning an error if the command fails, there currently is
// not a way to get that from the container package.
func runCniContainer(extraArgs ...string) error {
// Get the CWD for mounting directories into container.
cwd, err := os.Getwd()
if err != nil {
Fail("Could not get CWD")
}

// Assemble our arguments.
args := []string{
"-e", "SLEEP=false",
"-e", "KUBERNETES_SERVICE_HOST=127.0.0.1",
"-e", "KUBERNETES_SERVICE_PORT=8080",
"-v", cwd + "/tmp/bin:/host/opt/cni/bin",
"-v", cwd + "/tmp/net.d:/host/etc/cni/net.d",
"-v", cwd + "/tmp/serviceaccount:/var/run/secrets/kubernetes.io/serviceaccount",
}
args = append(args, extraArgs...)
args = append(args, "calico/cni:latest", "/install-cni.sh")

c := containers.Run("cni", args...)
Eventually(func() bool { return c.Stopped() }, 5*time.Second, 100*time.Millisecond).Should(BeTrue())

return nil
}

// cleanup uses the calico/cni container to cleanup after itself as it creates
// things as root.
func cleanup() {
cwd, err := os.Getwd()
if err != nil {
Fail("Could not get CWD")
}
containers.Run("cni",
"-e", "SLEEP=false",
"-e", "KUBERNETES_SERVICE_HOST=127.0.0.1",
"-e", "KUBERNETES_SERVICE_PORT=8080",
"-v", cwd+"/tmp/bin:/host/opt/cni/bin",
"-v", cwd+"/tmp/net.d:/host/etc/cni/net.d",
"-v", cwd+"/tmp/serviceaccount:/var/run/secrets/kubernetes.io/serviceaccount",
"calico/cni:latest",
"sh", "-c", "rm -f /host/opt/cni/bin/* /host/etc/cni/net.d/*")
}

var _ = BeforeSuite(func() {
// Make the directories we'll need for storing files.
err := os.MkdirAll("tmp/bin", 0755)
if err != nil {
Fail("Failed to create directory tmp/bin")
}
err = os.MkdirAll("tmp/net.d", 0755)
if err != nil {
Fail("Failed to create directory tmp/net.d")
}
err = os.MkdirAll("tmp/serviceaccount", 0755)
if err != nil {
Fail("Failed to create directory tmp/serviceaccount")
}
cleanup()

// Create a secrets file for parsing.
k8sSecret := []byte("my-secret-key")
err = ioutil.WriteFile(secretFile, k8sSecret, 0755)
if err != nil {
Fail(fmt.Sprintf("Failed to write k8s secret file: %v", err))
}
})

var _ = AfterSuite(func() {
err := os.RemoveAll("tmp")
if err != nil {
fmt.Println("Failed to clean up directories")
}
})

var _ = Describe("install-cni.sh tests", func() {
AfterEach(func() {
cleanup()
})

Describe("Run install-cni", func() {
Context("With default values", func() {
It("Should install bins and config", func() {
err := runCniContainer()
Expect(err).NotTo(HaveOccurred())

// Get a list of files in the defualt CNI bin location.
files, err := ioutil.ReadDir("tmp/bin")
if err != nil {
Fail("Could not list the files in tmp/bin")
}
names := []string{}
for _, file := range files {
names = append(names, file.Name())
}

// Get a list of files in the default location for CNI config.
files, err = ioutil.ReadDir("tmp/net.d")
if err != nil {
Fail("Could not list the files in tmp/net.d")
}
for _, file := range files {
names = append(names, file.Name())
}

Expect(names).To(ContainElement("calico"))
Expect(names).To(ContainElement("calico-ipam"))
Expect(names).To(ContainElement("10-calico.conf"))
})
It("Should parse and output a templated config", func() {
err := runCniContainer()
Expect(err).NotTo(HaveOccurred())

expectedFile := "expected_10-calico.conf"

var expected = []byte{}
if file, err := os.Open(expectedFile); err != nil {
Fail("Could not open " + expectedFile + " for reading")
} else {
_, err := file.Read(expected)
if err != nil {
Fail("Could not read from expected_10-calico.conf")
}
err = file.Close()
if err != nil {
fmt.Println("Failed to close expected_10-calico.conf")
}
}

var received = []byte{}
if file, err := os.Open("tmp/net.d/10-calico.conf"); err != nil {
Fail("Could not open 10-calico.conf for reading")
} else {
_, err := file.Read(received)
if err != nil {
Fail("Could not read from 10-calico.conf")
}
err = file.Close()
if err != nil {
fmt.Println("Failed to close 10-calico.conf")
}
}

Expect(expected).To(Equal(received))
})
})

Context("With modified env vars", func() {
It("Should rename '10-calico.conf' to '10-calico.conflist'", func() {
err := runCniContainer("-e", "CNI_CONF_NAME=10-calico.conflist")
Expect(err).NotTo(HaveOccurred())

expectedFile := "expected_10-calico.conf"

var expected = []byte{}
if file, err := os.Open(expectedFile); err != nil {
Fail("Could not open " + expectedFile + " for reading")
} else {
_, err := file.Read(expected)
if err != nil {
Fail("Could not read from expected_10-calico.conf")
}
err = file.Close()
if err != nil {
fmt.Println("Failed to close expected_10-calico.conf")
}
}

var received = []byte{}
if file, err := os.Open("tmp/net.d/10-calico.conflist"); err != nil {
Fail("Could not open 10-calico.conflist for reading")
} else {
_, err := file.Read(received)
if err != nil {
Fail("Could not read from 10-calico.conflist")
}
err = file.Close()
if err != nil {
fmt.Println("Failed to close 10-calico.conflist")
}
}

Expect(expected).To(Equal(received))
})
})
})
})
13 changes: 13 additions & 0 deletions k8s-install/scripts/scripts_suite_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package scripts_test

import (
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"

"testing"
)

func TestScripts(t *testing.T) {
RegisterFailHandler(Fail)
RunSpecs(t, "Scripts Suite")
}

0 comments on commit 1498db1

Please sign in to comment.