Skip to content
This repository has been archived by the owner on Feb 24, 2022. It is now read-only.

Commit

Permalink
Merge pull request #1 from AkihiroSuda/dev-ci
Browse files Browse the repository at this point in the history
add tests
  • Loading branch information
AkihiroSuda authored Jan 18, 2021
2 parents 40d4ccd + d6efd03 commit e073746
Show file tree
Hide file tree
Showing 5 changed files with 249 additions and 1 deletion.
12 changes: 11 additions & 1 deletion .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,5 +31,15 @@ jobs:
- uses: actions/checkout@v2
with:
fetch-depth: 1
- name: "Install isolation plugin"
run: |
make
sudo make install
- name: "Install other plugins"
run: |
sudo mkdir -p /opt/cni/bin
curl -L https://github.com/containernetworking/plugins/releases/download/v0.9.0/cni-plugins-linux-amd64-v0.9.0.tgz | sudo tar xzvC /opt/cni/bin
- name: "Test"
run: go test -v ./...
run: |
go test -c ./plugins/meta/isolation
sudo PATH=/opt/cni/bin:$PATH ./isolation.test -test.v -ginkgo.v
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
/bin
*.test
2 changes: 2 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,6 @@ require (
github.com/containernetworking/cni v0.8.0
github.com/containernetworking/plugins v0.9.0
github.com/coreos/go-iptables v0.4.5
github.com/onsi/ginkgo v1.12.1
github.com/onsi/gomega v1.10.3
)
207 changes: 207 additions & 0 deletions plugins/meta/isolation/isolation_integ_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,207 @@
// Copyright cni-isolation authors
// Copyright 2017 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 main

import (
"context"
"fmt"
"os"
"os/exec"
"path/filepath"
"strings"

"github.com/containernetworking/cni/libcni"
"github.com/containernetworking/cni/pkg/types/current"
"github.com/containernetworking/plugins/pkg/ns"
"github.com/containernetworking/plugins/pkg/testutils"
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
)

// To run test: go test -c . && sudo PATH=/opt/cni/bin:$PATH ./isolation.test -test.v -ginkgo.v
//
// The test is roughly based on https://github.com/containernetworking/plugins/blob/v0.9.0/plugins/meta/portmap/portmap_integ_test.go
var _ = Describe("isolation integration tests", func() {
// ns0: foo (10.88.3.0/24)
// ns1: foo (10.88.3.0/24)
// ns2: bar (10.88.4.0/24)
//
// ns0@foo can talk to ns1@foo, but cannot talk to ns2@bar
const nsCount = 3
var (
configListFoo *libcni.NetworkConfigList // "foo", 10.88.3.0/24
configListBar *libcni.NetworkConfigList // "bar", 10.88.4.0/24
cniConf *libcni.CNIConfig
namespaces [nsCount]ns.NetNS
)

BeforeEach(func() {
var err error
rawConfigFoo := `
{
"cniVersion": "0.4.0",
"name": "foo",
"plugins": [
{
"type": "bridge",
"bridge": "foo",
"isGateway": true,
"ipMasq": true,
"hairpinMode": true,
"ipam": {
"type": "host-local",
"routes": [
{
"dst": "0.0.0.0/0"
}
],
"ranges": [
[
{
"subnet": "10.88.3.0/24",
"gateway": "10.88.3.1"
}
]
]
}
},
{
"type": "firewall"
},
{
"type": "isolation"
}
]
}
`
configListFoo, err = libcni.ConfListFromBytes([]byte(rawConfigFoo))
Expect(err).NotTo(HaveOccurred())

rawConfigBar := strings.ReplaceAll(rawConfigFoo, "foo", "bar")
rawConfigBar = strings.ReplaceAll(rawConfigBar, "10.88.3.", "10.88.4.")

configListBar, err = libcni.ConfListFromBytes([]byte(rawConfigBar))
Expect(err).NotTo(HaveOccurred())

// turn PATH in to CNI_PATH.
_, err = exec.LookPath("isolation")
Expect(err).NotTo(HaveOccurred())
dirs := filepath.SplitList(os.Getenv("PATH"))
cniConf = &libcni.CNIConfig{Path: dirs}

for i := 0; i < nsCount; i++ {
targetNS, err := testutils.NewNS()
Expect(err).NotTo(HaveOccurred())
fmt.Fprintf(GinkgoWriter, "namespace %d:%s\n", i, targetNS.Path())
namespaces[i] = targetNS
}
})

AfterEach(func() {
for _, targetNS := range namespaces {
if targetNS != nil {
targetNS.Close()
}
}
})

Describe("Testing with network foo and bar", func() {
It("should isolate foo from bar", func() {
var results [nsCount]*current.Result
for i := 0; i < nsCount; i++ {
runtimeConfig := libcni.RuntimeConf{
ContainerID: fmt.Sprintf("test-cni-isolation-%d", i),
NetNS: namespaces[i].Path(),
IfName: "eth0",
}

configList := configListFoo
switch i {
case 0, 1:
// leave foo
default:
configList = configListBar
}

// Clean up garbages produced during past failed executions
_ = cniConf.DelNetworkList(context.TODO(), configList, &runtimeConfig)

// Make delete idempotent, so we can clean up on failure
netDeleted := false
deleteNetwork := func() error {
if netDeleted {
return nil
}
netDeleted = true
return cniConf.DelNetworkList(context.TODO(), configList, &runtimeConfig)
}
// Create the network
res, err := cniConf.AddNetworkList(context.TODO(), configList, &runtimeConfig)
Expect(err).NotTo(HaveOccurred())
// nolint: errcheck
defer deleteNetwork()

results[i], err = current.NewResultFromResult(res)
Expect(err).NotTo(HaveOccurred())
fmt.Fprintf(GinkgoWriter, "results[%d]: %+v\n", i, results[i])
}
ping := func(src, dst int) error {
return namespaces[src].Do(func(ns.NetNS) error {
defer GinkgoRecover()
saddr := results[src].IPs[0].Address.IP.String()
daddr := results[dst].IPs[0].Address.IP.String()
srcNetName := results[src].Interfaces[0].Name
dstNetName := results[dst].Interfaces[0].Name

fmt.Fprintf(GinkgoWriter, "ping %s (ns%d@%s) -> %s (ns%d@%s)...",
saddr, src, srcNetName, daddr, dst, dstNetName)
v6 := results[dst].IPs[0].Version == "6"
timeoutSec := 1
if err := testutils.Ping(saddr, daddr, v6, timeoutSec); err != nil {
fmt.Fprintln(GinkgoWriter, "unpingable")
return err
}
fmt.Fprintln(GinkgoWriter, "pingable")
return nil
})
}

// ns0@foo can ping to ns1@foo
err := ping(0, 1)
Expect(err).NotTo(HaveOccurred())

// ns1@foo can ping to ns0@foo
err = ping(1, 0)
Expect(err).NotTo(HaveOccurred())

// ns0@foo cannot ping to ns2@bar
err = ping(0, 2)
Expect(err).To(HaveOccurred())

// ns1@foo cannot ping to ns2@bar
err = ping(1, 2)
Expect(err).To(HaveOccurred())

// ns2@bar cannot ping to ns0@foo
err = ping(2, 0)
Expect(err).To(HaveOccurred())

// ns2@bar cannot ping to ns1@foo
err = ping(2, 1)
Expect(err).To(HaveOccurred())
})
})
})
28 changes: 28 additions & 0 deletions plugins/meta/isolation/isolation_suite_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
// Copyright cni-isolation authors
// Copyright 2017 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 main

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

"testing"
)

func TestIsolation(t *testing.T) {
RegisterFailHandler(Fail)
RunSpecs(t, "plugins/meta/isolation")
}

0 comments on commit e073746

Please sign in to comment.