-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
10 changed files
with
632 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,158 @@ | ||
// 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 libcni_test | ||
|
||
import ( | ||
"io/ioutil" | ||
"net" | ||
"path/filepath" | ||
|
||
"github.com/containernetworking/cni/libcni" | ||
"github.com/containernetworking/cni/pkg/skel" | ||
"github.com/containernetworking/cni/pkg/types" | ||
noop_debug "github.com/containernetworking/cni/plugins/test/noop/debug" | ||
|
||
. "github.com/onsi/ginkgo" | ||
. "github.com/onsi/gomega" | ||
) | ||
|
||
var _ = Describe("Invoking the plugin", func() { | ||
var ( | ||
debugFilePath string | ||
debug *noop_debug.Debug | ||
cniBinPath string | ||
pluginConfig string | ||
cniConfig libcni.CNIConfig | ||
netConfig *libcni.NetworkConfig | ||
runtimeConfig *libcni.RuntimeConf | ||
|
||
expectedCmdArgs skel.CmdArgs | ||
) | ||
|
||
BeforeEach(func() { | ||
debugFile, err := ioutil.TempFile("", "cni_debug") | ||
Expect(err).NotTo(HaveOccurred()) | ||
Expect(debugFile.Close()).To(Succeed()) | ||
debugFilePath = debugFile.Name() | ||
|
||
debug = &noop_debug.Debug{ | ||
ReportResult: `{ "ip4": { "ip": "10.1.2.3/24" }, "dns": {} }`, | ||
} | ||
Expect(debug.WriteDebug(debugFilePath)).To(Succeed()) | ||
|
||
cniBinPath = filepath.Dir(pathToPlugin) | ||
pluginConfig = `{ "type": "noop", "some-key": "some-value" }` | ||
cniConfig = libcni.CNIConfig{Path: []string{cniBinPath}} | ||
netConfig = &libcni.NetworkConfig{ | ||
Network: &types.NetConf{ | ||
Type: "noop", | ||
}, | ||
Bytes: []byte(pluginConfig), | ||
} | ||
runtimeConfig = &libcni.RuntimeConf{ | ||
ContainerID: "some-container-id", | ||
NetNS: "/some/netns/path", | ||
IfName: "some-eth0", | ||
Args: [][2]string{[2]string{"DEBUG", debugFilePath}}, | ||
} | ||
|
||
expectedCmdArgs = skel.CmdArgs{ | ||
ContainerID: "some-container-id", | ||
Netns: "/some/netns/path", | ||
IfName: "some-eth0", | ||
Args: "DEBUG=" + debugFilePath, | ||
Path: cniBinPath, | ||
StdinData: []byte(pluginConfig), | ||
} | ||
}) | ||
|
||
Describe("AddNetwork", func() { | ||
It("executes the plugin with command ADD", func() { | ||
result, err := cniConfig.AddNetwork(netConfig, runtimeConfig) | ||
Expect(err).NotTo(HaveOccurred()) | ||
|
||
Expect(result).To(Equal(&types.Result{ | ||
IP4: &types.IPConfig{ | ||
IP: net.IPNet{ | ||
IP: net.ParseIP("10.1.2.3"), | ||
Mask: net.IPv4Mask(255, 255, 255, 0), | ||
}, | ||
}, | ||
})) | ||
|
||
debug, err := noop_debug.ReadDebug(debugFilePath) | ||
Expect(err).NotTo(HaveOccurred()) | ||
Expect(debug.Command).To(Equal("ADD")) | ||
Expect(debug.CmdArgs).To(Equal(expectedCmdArgs)) | ||
}) | ||
|
||
Context("when finding the plugin fails", func() { | ||
BeforeEach(func() { | ||
netConfig.Network.Type = "does-not-exist" | ||
}) | ||
|
||
It("returns the error", func() { | ||
_, err := cniConfig.AddNetwork(netConfig, runtimeConfig) | ||
Expect(err).To(MatchError(ContainSubstring(`failed to find plugin "does-not-exist"`))) | ||
}) | ||
}) | ||
|
||
Context("when the plugin errors", func() { | ||
BeforeEach(func() { | ||
debug.ReportError = "plugin error: banana" | ||
Expect(debug.WriteDebug(debugFilePath)).To(Succeed()) | ||
}) | ||
It("unmarshals and returns the error", func() { | ||
result, err := cniConfig.AddNetwork(netConfig, runtimeConfig) | ||
Expect(result).To(BeNil()) | ||
Expect(err).To(MatchError("plugin error: banana")) | ||
}) | ||
}) | ||
}) | ||
|
||
Describe("DelNetwork", func() { | ||
It("executes the plugin with command DEL", func() { | ||
err := cniConfig.DelNetwork(netConfig, runtimeConfig) | ||
Expect(err).NotTo(HaveOccurred()) | ||
|
||
debug, err := noop_debug.ReadDebug(debugFilePath) | ||
Expect(err).NotTo(HaveOccurred()) | ||
Expect(debug.Command).To(Equal("DEL")) | ||
Expect(debug.CmdArgs).To(Equal(expectedCmdArgs)) | ||
}) | ||
|
||
Context("when finding the plugin fails", func() { | ||
BeforeEach(func() { | ||
netConfig.Network.Type = "does-not-exist" | ||
}) | ||
|
||
It("returns the error", func() { | ||
err := cniConfig.DelNetwork(netConfig, runtimeConfig) | ||
Expect(err).To(MatchError(ContainSubstring(`failed to find plugin "does-not-exist"`))) | ||
}) | ||
}) | ||
|
||
Context("when the plugin errors", func() { | ||
BeforeEach(func() { | ||
debug.ReportError = "plugin error: banana" | ||
Expect(debug.WriteDebug(debugFilePath)).To(Succeed()) | ||
}) | ||
It("unmarshals and returns the error", func() { | ||
err := cniConfig.DelNetwork(netConfig, runtimeConfig) | ||
Expect(err).To(MatchError("plugin error: banana")) | ||
}) | ||
}) | ||
}) | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,110 @@ | ||
// 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 libcni_test | ||
|
||
import ( | ||
"io/ioutil" | ||
"os" | ||
"path/filepath" | ||
|
||
"github.com/containernetworking/cni/libcni" | ||
"github.com/containernetworking/cni/pkg/types" | ||
. "github.com/onsi/ginkgo" | ||
. "github.com/onsi/gomega" | ||
) | ||
|
||
var _ = Describe("Loading configuration from disk", func() { | ||
var ( | ||
configDir string | ||
pluginConfig []byte | ||
) | ||
|
||
BeforeEach(func() { | ||
var err error | ||
configDir, err = ioutil.TempDir("", "plugin-conf") | ||
Expect(err).NotTo(HaveOccurred()) | ||
|
||
pluginConfig = []byte(`{ "name": "some-plugin", "some-key": "some-value" }`) | ||
Expect(ioutil.WriteFile(filepath.Join(configDir, "50-whatever.conf"), pluginConfig, 0600)).To(Succeed()) | ||
}) | ||
|
||
AfterEach(func() { | ||
Expect(os.RemoveAll(configDir)).To(Succeed()) | ||
}) | ||
|
||
Describe("LoadConf", func() { | ||
It("finds the network config file for the plugin of the given type", func() { | ||
netConfig, err := libcni.LoadConf(configDir, "some-plugin") | ||
Expect(err).NotTo(HaveOccurred()) | ||
Expect(netConfig).To(Equal(&libcni.NetworkConfig{ | ||
Network: &types.NetConf{Name: "some-plugin"}, | ||
Bytes: pluginConfig, | ||
})) | ||
}) | ||
|
||
Context("when the config directory does not exist", func() { | ||
BeforeEach(func() { | ||
Expect(os.RemoveAll(configDir)).To(Succeed()) | ||
}) | ||
|
||
It("returns a useful error", func() { | ||
_, err := libcni.LoadConf(configDir, "some-plugin") | ||
Expect(err).To(MatchError("no net configurations found")) | ||
}) | ||
}) | ||
|
||
Context("when there is no config for the desired plugin", func() { | ||
It("returns a useful error", func() { | ||
_, err := libcni.LoadConf(configDir, "some-other-plugin") | ||
Expect(err).To(MatchError(ContainSubstring(`no net configuration with name "some-other-plugin" in`))) | ||
}) | ||
}) | ||
|
||
Context("when a config file is malformed", func() { | ||
BeforeEach(func() { | ||
Expect(ioutil.WriteFile(filepath.Join(configDir, "00-bad.conf"), []byte(`{`), 0600)).To(Succeed()) | ||
}) | ||
|
||
It("returns a useful error", func() { | ||
_, err := libcni.LoadConf(configDir, "some-plugin") | ||
Expect(err).To(MatchError(`error parsing configuration: unexpected end of JSON input`)) | ||
}) | ||
}) | ||
|
||
Context("when the config is in a nested subdir", func() { | ||
BeforeEach(func() { | ||
subdir := filepath.Join(configDir, "subdir1", "subdir2") | ||
Expect(os.MkdirAll(subdir, 0700)).To(Succeed()) | ||
|
||
pluginConfig = []byte(`{ "name": "deep", "some-key": "some-value" }`) | ||
Expect(ioutil.WriteFile(filepath.Join(subdir, "90-deep.conf"), pluginConfig, 0600)).To(Succeed()) | ||
}) | ||
|
||
It("will not find the config", func() { | ||
_, err := libcni.LoadConf(configDir, "deep") | ||
Expect(err).To(MatchError(HavePrefix("no net configuration with name"))) | ||
}) | ||
}) | ||
}) | ||
|
||
Describe("ConfFromFile", func() { | ||
Context("when the file cannot be opened", func() { | ||
It("returns a useful error", func() { | ||
_, err := libcni.ConfFromFile("/tmp/nope/not-here") | ||
Expect(err).To(MatchError(HavePrefix(`error reading /tmp/nope/not-here: open /tmp/nope/not-here`))) | ||
}) | ||
}) | ||
}) | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
// 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 libcni_test | ||
|
||
import ( | ||
. "github.com/onsi/ginkgo" | ||
. "github.com/onsi/gomega" | ||
"github.com/onsi/gomega/gexec" | ||
|
||
"testing" | ||
) | ||
|
||
func TestLibcni(t *testing.T) { | ||
RegisterFailHandler(Fail) | ||
RunSpecs(t, "Libcni Suite") | ||
} | ||
|
||
const packagePath = "github.com/containernetworking/cni/plugins/test/noop" | ||
|
||
var pathToPlugin string | ||
|
||
var _ = SynchronizedBeforeSuite(func() []byte { | ||
var err error | ||
pathToPlugin, err = gexec.Build(packagePath) | ||
Expect(err).NotTo(HaveOccurred()) | ||
return []byte(pathToPlugin) | ||
}, func(crossNodeData []byte) { | ||
pathToPlugin = string(crossNodeData) | ||
}) | ||
|
||
var _ = SynchronizedAfterSuite(func() {}, func() { | ||
gexec.CleanupBuildArtifacts() | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
// 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. | ||
|
||
// debug supports tests that use the noop plugin | ||
package debug | ||
|
||
import ( | ||
"encoding/json" | ||
"io/ioutil" | ||
|
||
"github.com/containernetworking/cni/pkg/skel" | ||
) | ||
|
||
// Debug is used to control and record the behavior of the noop plugin | ||
type Debug struct { | ||
ReportResult string | ||
ReportError string | ||
Command string | ||
CmdArgs skel.CmdArgs | ||
} | ||
|
||
// ReadDebug will return a debug file recorded by the noop plugin | ||
func ReadDebug(debugFilePath string) (*Debug, error) { | ||
debugBytes, err := ioutil.ReadFile(debugFilePath) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
var debug Debug | ||
err = json.Unmarshal(debugBytes, &debug) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
return &debug, nil | ||
} | ||
|
||
// WriteDebug will create a debug file to control the noop plugin | ||
func (debug *Debug) WriteDebug(debugFilePath string) error { | ||
debugBytes, err := json.Marshal(debug) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
err = ioutil.WriteFile(debugFilePath, debugBytes, 0600) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
return nil | ||
} |
Oops, something went wrong.