nebius/SWE-rebench-V2-PRs huggingface dataset:
Repository: containernetworking/cni
Pull request #858 (2021-09-01 16:19:52)

pkg/version: add VersionsFrom function
So plugins can easily declare support for "from version 0.3 and beyond".

Signed-off-by: Casey Callendrello <cdc@redhat.com>

coveralls: 
[![Coverage Status](https://coveralls.io/builds/42584999/badge)](https://coveralls.io/builds/42584999)

Coverage increased (+0.2%) to 72.35% when pulling **83d9859a477201e981be63f603135078d4ed8c1f on squeed:version-from** into **5608690f77380743f29bb314458da9a9fb88c003 on containernetworking:master**.


Patch:
diff --git a/pkg/version/version.go b/pkg/version/version.go
index 709a1fb..1326f80 100644
--- a/pkg/version/version.go
+++ b/pkg/version/version.go
@@ -19,7 +19,7 @@ import (
 	"fmt"
 
 	"github.com/containernetworking/cni/pkg/types"
-	"github.com/containernetworking/cni/pkg/types/100"
+	types100 "github.com/containernetworking/cni/pkg/types/100"
 	"github.com/containernetworking/cni/pkg/types/create"
 )
 
@@ -38,6 +38,22 @@ func Current() string {
 var Legacy = PluginSupports("0.1.0", "0.2.0")
 var All = PluginSupports("0.1.0", "0.2.0", "0.3.0", "0.3.1", "0.4.0", "1.0.0")
 
+// VersionsFrom returns a list of versions starting from min, inclusive
+func VersionsStartingFrom(min string) PluginInfo {
+	out := []string{}
+	// cheat, just assume ordered
+	ok := false
+	for _, v := range All.SupportedVersions() {
+		if !ok && v == min {
+			ok = true
+		}
+		if ok {
+			out = append(out, v)
+		}
+	}
+	return PluginSupports(out...)
+}
+
 // Finds a Result object matching the requested version (if any) and asks
 // that object to parse the plugin result, returning an error if parsing failed.
 func NewResult(version string, resultBytes []byte) (types.Result, error) {


Test patch:
diff --git a/pkg/version/version_test.go b/pkg/version/version_test.go
index 6d869c2..c273dfb 100644
--- a/pkg/version/version_test.go
+++ b/pkg/version/version_test.go
@@ -28,6 +28,11 @@ import (
 )
 
 var _ = Describe("Version operations", func() {
+	It("computes a list of versions correctly", func() {
+		actual := version.VersionsStartingFrom("0.3.1")
+		Expect(actual.SupportedVersions()).To(Equal([]string{"0.3.1", "0.4.0", "1.0.0"}))
+	})
+
 	Context("when a prevResult is available", func() {
 		It("parses the prevResult", func() {
 			rawBytes := []byte(`{
Repository: containernetworking/cni
Pull request #860 (2021-09-08 13:19:30)

skel: print out CNI versions supported in help text.
It was suggested on Twitter that this would clarify things.

Signed-off-by: Casey Callendrello <cdc@redhat.com>


Patch:
diff --git a/pkg/skel/skel.go b/pkg/skel/skel.go
index da42db5..58fd023 100644
--- a/pkg/skel/skel.go
+++ b/pkg/skel/skel.go
@@ -196,6 +196,7 @@ func (t *dispatcher) pluginMain(cmdAdd, cmdCheck, cmdDel func(_ *CmdArgs) error,
 		// Print the about string to stderr when no command is set
 		if err.Code == types.ErrInvalidEnvironmentVariables && t.Getenv("CNI_COMMAND") == "" && about != "" {
 			_, _ = fmt.Fprintln(t.Stderr, about)
+			_, _ = fmt.Fprintf(t.Stderr, "CNI protocol versions supported: %s\n", strings.Join(versionInfo.SupportedVersions(), ", "))
 			return nil
 		}
 		return err


Test patch:
diff --git a/pkg/skel/skel_test.go b/pkg/skel/skel_test.go
index a44486a..f65a2a5 100644
--- a/pkg/skel/skel_test.go
+++ b/pkg/skel/skel_test.go
@@ -69,7 +69,7 @@ var _ = Describe("dispatching to the correct callback", func() {
 		stdinData = `{ "name":"skel-test", "some": "config", "cniVersion": "9.8.7" }`
 		stdout = &bytes.Buffer{}
 		stderr = &bytes.Buffer{}
-		versionInfo = version.PluginSupports("9.8.7")
+		versionInfo = version.PluginSupports("9.8.7", "10.0.0")
 		dispatch = &dispatcher{
 			Getenv: func(key string) string { return environment[key] },
 			Stdin:  strings.NewReader(stdinData),
@@ -430,7 +430,7 @@ var _ = Describe("dispatching to the correct callback", func() {
 			Expect(err).NotTo(HaveOccurred())
 			Expect(stdout).To(MatchJSON(fmt.Sprintf(`{
 				"cniVersion": "%s",
-				"supportedVersions": ["9.8.7"]
+				"supportedVersions": ["9.8.7", "10.0.0"]
 			}`, current.ImplementedSpecVersion)))
 		})
 
@@ -461,7 +461,7 @@ var _ = Describe("dispatching to the correct callback", func() {
 			Expect(r.ReadCount).To(Equal(0))
 			Expect(stdout).To(MatchJSON(fmt.Sprintf(`{
 				"cniVersion": "%s",
-				"supportedVersions": ["9.8.7"]
+				"supportedVersions": ["9.8.7", "10.0.0"]
 			}`, current.ImplementedSpecVersion)))
 		})
 	})
@@ -503,7 +503,7 @@ var _ = Describe("dispatching to the correct callback", func() {
 			Expect(cmdAdd.CallCount).To(Equal(0))
 			Expect(cmdDel.CallCount).To(Equal(0))
 			log := stderr.String()
-			Expect(log).To(Equal("AWESOME PLUGIN\n"))
+			Expect(log).To(Equal("AWESOME PLUGIN\nCNI protocol versions supported: 9.8.7, 10.0.0\n"))
 		})
 
 		It("fails if there is no about string", func() {
Repository: containernetworking/cni
Pull request #893 (2022-04-27 19:42:49)

libcni: handle empty version when parsing version
Without this Delete failed for empty-version configs.

Update the tests to catch this case.

Signed-off-by: Casey Callendrello <cdc@redhat.com>


Patch:
diff --git a/pkg/version/plugin.go b/pkg/version/plugin.go
index d4bc9d1..17b22b6 100644
--- a/pkg/version/plugin.go
+++ b/pkg/version/plugin.go
@@ -86,8 +86,8 @@ func (*PluginDecoder) Decode(jsonBytes []byte) (PluginInfo, error) {
 // minor, and micro numbers or returns an error
 func ParseVersion(version string) (int, int, int, error) {
 	var major, minor, micro int
-	if version == "" {
-		return -1, -1, -1, fmt.Errorf("invalid version %q: the version is empty", version)
+	if version == "" { // special case: no version declared == v0.1.0
+		return 0, 1, 0, nil
 	}
 
 	parts := strings.Split(version, ".")


Test patch:
diff --git a/libcni/backwards_compatibility_test.go b/libcni/backwards_compatibility_test.go
index 0bba36f..dabd872 100644
--- a/libcni/backwards_compatibility_test.go
+++ b/libcni/backwards_compatibility_test.go
@@ -66,6 +66,9 @@ var _ = Describe("Backwards compatibility", func() {
 
 		Expect(result).To(Equal(legacy_examples.ExpectedResult))
 
+		err = cniConfig.DelNetwork(context.TODO(), netConf, runtimeConf)
+		Expect(err).NotTo(HaveOccurred())
+
 		Expect(os.RemoveAll(pluginPath)).To(Succeed())
 	})
 
diff --git a/pkg/version/plugin_test.go b/pkg/version/plugin_test.go
index 2d1da2d..99bf6ca 100644
--- a/pkg/version/plugin_test.go
+++ b/pkg/version/plugin_test.go
@@ -91,8 +91,16 @@ var _ = Describe("Decoding versions reported by a plugin", func() {
 			Expect(micro).To(Equal(3))
 		})
 
+		It("parses an empty string as v0.1.0", func() {
+			major, minor, micro, err := version.ParseVersion("")
+			Expect(err).NotTo(HaveOccurred())
+			Expect(major).To(Equal(0))
+			Expect(minor).To(Equal(1))
+			Expect(micro).To(Equal(0))
+		})
+
 		It("returns an error for malformed versions", func() {
-			badVersions := []string{"asdfasdf", "asdf.", ".asdfas", "asdf.adsf.", "0.", "..", "1.2.3.4.5", ""}
+			badVersions := []string{"asdfasdf", "asdf.", ".asdfas", "asdf.adsf.", "0.", "..", "1.2.3.4.5"}
 			for _, v := range badVersions {
 				_, _, _, err := version.ParseVersion(v)
 				Expect(err).To(HaveOccurred())
Repository: containernetworking/cni
Pull request #1072 (2024-03-07 23:27:28)

tolerate invalid cni caches for deletion
Fixes: #1055
Closes: #1066

In `DelNetworkList` function, ignore the errors returned by `getCachedResult` and continue to invoke plugins for deletion as best effort. Also updated the test case to adapt this new behavior.

Cached results are deleted from disk in the following two cases:
1. `getCachedResult` returns an error; OR
2. `getCachedResult` succeeds and no errors are returned from plugins

Cached results are not deleted if (I think this will allow clients to retry the deletion)
1. `getCachedResult` succeeds AND 
2. Plugin fails


Patch:
diff --git a/libcni/api.go b/libcni/api.go
index e004aa9..d32c0f6 100644
--- a/libcni/api.go
+++ b/libcni/api.go
@@ -586,9 +586,9 @@ func (c *CNIConfig) DelNetworkList(ctx context.Context, list *NetworkConfigList,
 	if gtet, err := version.GreaterThanOrEqualTo(list.CNIVersion, "0.4.0"); err != nil {
 		return err
 	} else if gtet {
-		cachedResult, err = c.getCachedResult(list.Name, list.CNIVersion, rt)
-		if err != nil {
-			return fmt.Errorf("failed to get network %q cached result: %w", list.Name, err)
+		if cachedResult, err = c.getCachedResult(list.Name, list.CNIVersion, rt); err != nil {
+			_ = c.cacheDel(list.Name, rt)
+			cachedResult = nil
 		}
 	}
 
@@ -598,7 +598,10 @@ func (c *CNIConfig) DelNetworkList(ctx context.Context, list *NetworkConfigList,
 			return fmt.Errorf("plugin %s failed (delete): %w", pluginDescription(net.Network), err)
 		}
 	}
-	_ = c.cacheDel(list.Name, rt)
+
+	if cachedResult != nil {
+		_ = c.cacheDel(list.Name, rt)
+	}
 
 	return nil
 }


Test patch:
diff --git a/libcni/api_test.go b/libcni/api_test.go
index 26852f3..c00424d 100644
--- a/libcni/api_test.go
+++ b/libcni/api_test.go
@@ -1474,7 +1474,7 @@ var _ = Describe("Invoking plugins", func() {
 			})
 
 			Context("when the cached result is invalid", func() {
-				It("returns an error", func() {
+				It("tolerates the error", func() {
 					cacheFile := resultCacheFilePath(cacheDirPath, netConfigList.Name, runtimeConfig)
 					err := os.MkdirAll(filepath.Dir(cacheFile), 0o700)
 					Expect(err).NotTo(HaveOccurred())
@@ -1482,7 +1482,7 @@ var _ = Describe("Invoking plugins", func() {
 					Expect(err).NotTo(HaveOccurred())
 
 					err = cniConfig.DelNetworkList(ctx, netConfigList, runtimeConfig)
-					Expect(err).To(MatchError("failed to get network \"some-list\" cached result: decoding version from network config: invalid character 'a' looking for beginning of value"))
+					Expect(err).NotTo(HaveOccurred())
 				})
 			})
 		})