diff --git a/pkg/sdk/symbols/info/info.go b/pkg/sdk/symbols/info/info.go index acf33d1..647b3a0 100644 --- a/pkg/sdk/symbols/info/info.go +++ b/pkg/sdk/symbols/info/info.go @@ -117,17 +117,21 @@ func splitVersionString(version string) (string, string, string) { func SetRequiredAPIVersion(apiVer string) { if apiVer != "" { - requiredMajor, requiredMinor, requiredPatch := splitVersionString(apiVer) - pluginMajor, pluginMinor, pluginPatch := splitVersionString(C.GoString(C.get_default_required_api_version())) - - if pluginMajor != requiredMajor { - panic("Plugin SDK Go required API version incompatible major number. Expected: Major version should be equal to " + pluginMajor + " but got " + requiredMajor) + pluginRequiredMajor, pluginRequiredMinor, pluginRequiredPatch := splitVersionString(apiVer) + sdkRequiredMajor, sdkRequiredMinor, sdkRequiredPatch := splitVersionString(C.GoString(C.get_default_required_api_version())) + + // The plugin should always require a version lower or equal to the one required by the SDK + // because the SDK couldn't support features coming from new framework versions. + // On the other side the plugin could require a lower version because maybe it doesn't + // need all features provided by the framework. + if sdkRequiredMajor != pluginRequiredMajor { + panic("Incompatible required Major version between SDK and the plugin. Major SDK version is equal to " + sdkRequiredMajor + " but the plugin uses " + pluginRequiredMajor + ". The 2 Major versions should be equal.") } - if pluginMinor < requiredMinor { - panic("Plugin SDK Go required API version incompatible minor number. Expected: Minor version should be less than/equal to " + pluginMinor + " but got " + requiredMinor) + if sdkRequiredMinor < pluginRequiredMinor { + panic("The plugin requires a Minor version greater than the SDK one. Minor SDK version is equal to " + sdkRequiredMinor + " but the plugin uses " + pluginRequiredMinor + ". The plugin should always require a Minor version lower or equal to the SDK one.") } - if pluginMinor == requiredMinor && pluginPatch < requiredPatch { - panic("Plugin SDK Go required API version incompatible patch number. Expected: Patch version should be less than/equal to " + pluginPatch + " but got " + requiredPatch) + if sdkRequiredMinor == pluginRequiredMinor && sdkRequiredPatch < pluginRequiredPatch { + panic("The plugin requires a Patch version greater than the SDK one. Patch SDK version is equal to " + sdkRequiredPatch + " but the plugin uses " + pluginRequiredPatch + ". The plugin should always require a Patch version lower or equal to the SDK one.") } } pRequiredAPIVersion.Write(apiVer) diff --git a/pkg/sdk/symbols/info/info_test.go b/pkg/sdk/symbols/info/info_test.go index e86aa47..33feca1 100644 --- a/pkg/sdk/symbols/info/info_test.go +++ b/pkg/sdk/symbols/info/info_test.go @@ -29,10 +29,6 @@ import ( var testStr = "test" var testU32 = uint32(1) var testStrSlice = []string{"hello", "world"} -var testCurAPIVerMajor = 3 -var testCurAPIVerMinor = 0 -var testCurAPIVerPatch = 0 -var testCurAPIVer = testFormatVer(testCurAPIVerMajor, testCurAPIVerMinor, testCurAPIVerPatch) func testFormatVer(major, minor, patch int) string { return fmt.Sprintf("%d.%d.%d", major, minor, patch) @@ -46,7 +42,7 @@ func TestInfo(t *testing.T) { SetId(testU32) resU32 = plugin_get_id() if resU32 != testU32 { - t.Errorf("(id) expected %d, but found %d", testU32, resU32) + t.Errorf("(plugin id) expected %d, but found %d", testU32, resU32) } SetName(testStr) @@ -73,12 +69,6 @@ func TestInfo(t *testing.T) { t.Errorf("(version) expected %s, but found %s", testStr, resStr) } - SetRequiredAPIVersion(testCurAPIVer) - resStr = ptr.GoString(unsafe.Pointer(plugin_get_required_api_version())) - if resStr != testCurAPIVer { - t.Errorf("(requiredApiVersion) expected %s, but found %s", testStr, resStr) - } - SetEventSource(testStr) resStr = ptr.GoString(unsafe.Pointer(plugin_get_event_source())) if resStr != testStr { @@ -113,52 +103,108 @@ func TestInfo(t *testing.T) { } } -func TestSemver(t *testing.T) { - t.Run("success_check", func(t *testing.T) { +func TestSplitVersionString(t *testing.T) { + t.Run("invalid version string 1", func(t *testing.T) { panicFunc := func() { - SetRequiredAPIVersion(testCurAPIVer) + splitVersionString("2..1..2") } - assert.NotPanics(t, panicFunc) + assert.Panics(t, panicFunc) }) - t.Run("default_version", func(t *testing.T) { - version := "" + t.Run("invalid version string 2", func(t *testing.T) { panicFunc := func() { - SetRequiredAPIVersion(version) + splitVersionString("2.2.3..32") } - assert.NotPanics(t, panicFunc) + assert.Panics(t, panicFunc) }) - t.Run("invalid_version", func(t *testing.T) { - version := "invalid" - errMsg := "Incorrect format. Expected: Semantic Versioning: X.Y.Z" + t.Run("invalid version string 3", func(t *testing.T) { panicFunc := func() { - SetRequiredAPIVersion(version) + splitVersionString("2.2.3.") } - assert.PanicsWithValue(t, errMsg, panicFunc) + assert.Panics(t, panicFunc) }) - t.Run("incompatible_major_number", func(t *testing.T) { - v := testFormatVer(testCurAPIVerMajor+1, testCurAPIVerMinor, testCurAPIVerPatch) + t.Run("invalid version string 4", func(t *testing.T) { panicFunc := func() { - SetRequiredAPIVersion(v) + splitVersionString("2..2.3") } assert.Panics(t, panicFunc) }) - t.Run("incompatible_minor_number", func(t *testing.T) { - v := testFormatVer(testCurAPIVerMajor, testCurAPIVerMinor+1, testCurAPIVerPatch) + t.Run("valid version string", func(t *testing.T) { panicFunc := func() { - SetRequiredAPIVersion(v) + splitVersionString("2.2.3") + } + assert.NotPanics(t, panicFunc) + }) + + t.Run("check split version string", func(t *testing.T) { + major, minor, patch := splitVersionString("2.4.3") + if major != "2" { + t.Errorf("(Major) expected %s, but found %s", "2", major) + } + if minor != "4" { + t.Errorf("(Minor) expected %s, but found %s", "4", minor) + } + if patch != "3" { + t.Errorf("(Patch) expected %s, but found %s", "3", patch) + } + }) +} + +func TestSemver(t *testing.T) { + // Get the SDK required version + // we set an empty string to obtain the default SDK version + SetRequiredAPIVersion("") + versionSDK := ptr.GoString(unsafe.Pointer(plugin_get_required_api_version())) + var majorSDK, minorSDK, patchSDK int + nums, err := fmt.Sscanf(versionSDK, "%d.%d.%d", &majorSDK, &minorSDK, &patchSDK) + if nums != 3 || err != nil { + t.Errorf("Unable to obtain the default SDK version") + } + + // plguin Major == SDK Major && plguin Minor == SDK Minor && plguin Patch == SDK Patch + t.Run("plguin Major == SDK Major && plguin Minor == SDK Minor && plguin Patch == SDK Patch", func(t *testing.T) { + SetRequiredAPIVersion(testFormatVer(majorSDK, minorSDK, patchSDK)) + requiredAPIVersion := ptr.GoString(unsafe.Pointer(plugin_get_required_api_version())) + expectedRequiredAPIVersion := testFormatVer(majorSDK, minorSDK, patchSDK) + if expectedRequiredAPIVersion != requiredAPIVersion { + t.Errorf("(requiredApiVersion) expected %s, but found %s", expectedRequiredAPIVersion, requiredAPIVersion) } - assert.Panics(t, panicFunc) }) - t.Run("incompatible_patch_number", func(t *testing.T) { - v := testFormatVer(testCurAPIVerMajor, testCurAPIVerMinor, testCurAPIVerPatch+1) + // plguin Major > SDK Major + t.Run("plguin Major > SDK Major", func(t *testing.T) { panicFunc := func() { - SetRequiredAPIVersion(v) + SetRequiredAPIVersion(testFormatVer(majorSDK+1, minorSDK, patchSDK)) + } + assert.PanicsWithValue(t, fmt.Sprintf("Incompatible required Major version between SDK and the plugin. Major SDK version is equal to %d but the plugin uses %d. The 2 Major versions should be equal.", majorSDK, majorSDK+1), panicFunc) + }) + + // plguin Major == SDK Major && plguin Minor > SDK Minor + t.Run("plguin Major == SDK Major && plguin Minor > SDK Minor", func(t *testing.T) { + panicFunc := func() { + SetRequiredAPIVersion(testFormatVer(majorSDK, minorSDK+1, patchSDK)) + } + assert.PanicsWithValue(t, fmt.Sprintf("The plugin requires a Minor version greater than the SDK one. Minor SDK version is equal to %d but the plugin uses %d. The plugin should always require a Minor version lower or equal to the SDK one.", minorSDK, minorSDK+1), panicFunc) + }) + + // plguin Major == SDK Major && plguin Minor == SDK Minor && plguin Patch > SDK Patch + t.Run("plguin Major == SDK Major && plguin Minor == SDK Minor && plguin Patch > SDK Patch", func(t *testing.T) { + panicFunc := func() { + SetRequiredAPIVersion(testFormatVer(majorSDK, minorSDK, patchSDK+1)) + } + assert.PanicsWithValue(t, fmt.Sprintf("The plugin requires a Patch version greater than the SDK one. Patch SDK version is equal to %d but the plugin uses %d. The plugin should always require a Patch version lower or equal to the SDK one.", patchSDK, patchSDK+1), panicFunc) + }) + + t.Run("empty plugin version", func(t *testing.T) { + // This should set as default the SDK required version since we don't provide the required plugin version + SetRequiredAPIVersion("") + requiredAPIVersion := ptr.GoString(unsafe.Pointer(plugin_get_required_api_version())) + expectedRequiredAPIVersion := testFormatVer(majorSDK, minorSDK, patchSDK) + if expectedRequiredAPIVersion != requiredAPIVersion { + t.Errorf("(requiredApiVersion) expected %s, but found %s", expectedRequiredAPIVersion, requiredAPIVersion) } - assert.Panics(t, panicFunc) }) }