Add basic unit tests of testhelpers
authorGabe Rosenhouse <grosenhouse@pivotal.io>
Mon, 18 Apr 2016 01:48:50 +0000 (18:48 -0700)
committerStefan Junker <mail@stefanjunker.de>
Thu, 19 May 2016 10:06:16 +0000 (12:06 +0200)
testhelpers/testhelpers_suite_test.go [new file with mode: 0644]
testhelpers/testhelpers_test.go [new file with mode: 0644]

diff --git a/testhelpers/testhelpers_suite_test.go b/testhelpers/testhelpers_suite_test.go
new file mode 100644 (file)
index 0000000..88bfc3d
--- /dev/null
@@ -0,0 +1,31 @@
+// Copyright 2016 CNI authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package testhelpers_test
+
+import (
+       "math/rand"
+
+       . "github.com/onsi/ginkgo"
+       "github.com/onsi/ginkgo/config"
+       . "github.com/onsi/gomega"
+
+       "testing"
+)
+
+func TestTesthelpers(t *testing.T) {
+       rand.Seed(config.GinkgoConfig.RandomSeed)
+       RegisterFailHandler(Fail)
+       RunSpecs(t, "Testhelpers Suite")
+}
diff --git a/testhelpers/testhelpers_test.go b/testhelpers/testhelpers_test.go
new file mode 100644 (file)
index 0000000..ce328f0
--- /dev/null
@@ -0,0 +1,96 @@
+// Copyright 2016 CNI authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Package testhelpers_test contains unit tests of the testhelpers
+//
+// Some of this stuff is non-trivial and can interact in surprising ways
+// with the Go runtime.  Better be safe.
+package testhelpers_test
+
+import (
+       "fmt"
+       "math/rand"
+       "path/filepath"
+
+       "golang.org/x/sys/unix"
+
+       "github.com/appc/cni/pkg/testhelpers"
+       . "github.com/onsi/ginkgo"
+       . "github.com/onsi/gomega"
+)
+
+var _ = Describe("Test helper functions", func() {
+       Describe("MakeNetworkNS", func() {
+               It("should return the filepath to a network namespace", func() {
+                       containerID := fmt.Sprintf("c-%x", rand.Int31())
+                       nsPath := testhelpers.MakeNetworkNS(containerID)
+
+                       Expect(nsPath).To(BeAnExistingFile())
+
+                       testhelpers.RemoveNetworkNS(containerID)
+               })
+
+               It("should return a network namespace different from that of the caller", func() {
+                       containerID := fmt.Sprintf("c-%x", rand.Int31())
+
+                       By("discovering the inode of the current netns")
+                       originalNetNSPath := currentNetNSPath()
+                       originalNetNSInode, err := testhelpers.GetInode(originalNetNSPath)
+                       Expect(err).NotTo(HaveOccurred())
+
+                       By("creating a new netns")
+                       createdNetNSPath := testhelpers.MakeNetworkNS(containerID)
+                       defer testhelpers.RemoveNetworkNS(createdNetNSPath)
+
+                       By("discovering the inode of the created netns")
+                       createdNetNSInode, err := testhelpers.GetInode(createdNetNSPath)
+                       Expect(err).NotTo(HaveOccurred())
+
+                       By("comparing the inodes")
+                       Expect(createdNetNSInode).NotTo(Equal(originalNetNSInode))
+               })
+
+               It("should not leak the new netns onto any threads in the process", func() {
+                       containerID := fmt.Sprintf("c-%x", rand.Int31())
+
+                       By("creating a new netns")
+                       createdNetNSPath := testhelpers.MakeNetworkNS(containerID)
+                       defer testhelpers.RemoveNetworkNS(createdNetNSPath)
+
+                       By("discovering the inode of the created netns")
+                       createdNetNSInode, err := testhelpers.GetInode(createdNetNSPath)
+                       Expect(err).NotTo(HaveOccurred())
+
+                       By("comparing against the netns inode of every thread in the process")
+                       for _, netnsPath := range allNetNSInCurrentProcess() {
+                               netnsInode, err := testhelpers.GetInode(netnsPath)
+                               Expect(err).NotTo(HaveOccurred())
+                               Expect(netnsInode).NotTo(Equal(createdNetNSInode))
+                       }
+               })
+       })
+})
+
+func currentNetNSPath() string {
+       pid := unix.Getpid()
+       tid := unix.Gettid()
+       return fmt.Sprintf("/proc/%d/task/%d/ns/net", pid, tid)
+}
+
+func allNetNSInCurrentProcess() []string {
+       pid := unix.Getpid()
+       paths, err := filepath.Glob(fmt.Sprintf("/proc/%d/task/*/ns/net", pid))
+       Expect(err).NotTo(HaveOccurred())
+       return paths
+}