[MM-63345] Address Go v1.23 incompatibility issues with plugins (#30386)

* Address Go v1.23 incompatibility issues with plugins

* Install multiple Go versions for compatibility tests

* Rename
Этот коммит содержится в:
Claudio Costa
2025-03-11 11:44:42 -06:00
коммит произвёл GitHub
родитель 661f7f6a83
Коммит 7c25de2cff
5 изменённых файлов: 186 добавлений и 68 удалений

Просмотреть файл

@@ -1614,7 +1614,8 @@ func TestInterpluginPluginHTTP(t *testing.T) {
defer th.TearDown()
setupMultiPluginAPITest(t,
[]string{`
[]string{
`
package main
import (
@@ -1759,8 +1760,7 @@ func TestAPIMetrics(t *testing.T) {
pluginID := model.NewId()
backend := filepath.Join(pluginDir, pluginID, "backend.exe")
code :=
`
code := `
package main
import (
@@ -1896,6 +1896,23 @@ func TestPluginHTTPConnHijack(t *testing.T) {
require.Equal(t, "OK", string(body))
}
func makePluginHTTPRequest(t *testing.T, pluginID string, port int, token string) string {
t.Helper()
client := &http.Client{}
reqURL := fmt.Sprintf("http://localhost:%d/plugins/%s", port, pluginID)
req, err := http.NewRequest("GET", reqURL, nil)
require.NoError(t, err)
req.Header.Set(model.HeaderAuth, model.HeaderToken+" "+token)
resp, err := client.Do(req)
require.NoError(t, err)
defer resp.Body.Close()
body, err := io.ReadAll(resp.Body)
require.NoError(t, err)
return string(body)
}
func TestPluginMFAEnforcement(t *testing.T) {
th := Setup(t).InitBasic()
defer th.TearDown()
@@ -1942,22 +1959,6 @@ func TestPluginMFAEnforcement(t *testing.T) {
})
require.Nil(t, appErr)
client := &http.Client{}
makeRequest := func() string {
reqURL := fmt.Sprintf("http://localhost:%d/plugins/%s", th.Server.ListenAddr.Port, pluginID)
req, err := http.NewRequest("GET", reqURL, nil)
require.NoError(t, err)
req.Header.Set(model.HeaderAuth, model.HeaderToken+" "+session.Token)
resp, err := client.Do(req)
require.NoError(t, err)
defer resp.Body.Close()
body, err := io.ReadAll(resp.Body)
require.NoError(t, err)
return string(body)
}
t.Run("MFA not enforced", func(t *testing.T) {
th.App.UpdateConfig(func(cfg *model.Config) {
*cfg.ServiceSettings.EnableMultifactorAuthentication = true
@@ -1965,7 +1966,7 @@ func TestPluginMFAEnforcement(t *testing.T) {
})
// Should return user ID since MFA is not enforced
userID := makeRequest()
userID := makePluginHTTPRequest(t, pluginID, th.Server.ListenAddr.Port, session.Token)
assert.Equal(t, user.Id, userID)
})
@@ -1976,7 +1977,7 @@ func TestPluginMFAEnforcement(t *testing.T) {
})
// Should return empty string since MFA is enforced but not active
userID := makeRequest()
userID := makePluginHTTPRequest(t, pluginID, th.Server.ListenAddr.Port, session.Token)
assert.Empty(t, userID)
})
}
@@ -2806,3 +2807,42 @@ func TestPluginPatchChannelMembersNotifications(t *testing.T) {
assert.Equal(t, "", updated.NotifyProps["test_field"])
})
}
func TestPluginServeHTTPCompatibility(t *testing.T) {
th := Setup(t).InitBasic()
defer th.TearDown()
pluginCode := `
package main
import (
"net/http"
"github.com/mattermost/mattermost/server/public/plugin"
)
type MyPlugin struct {
plugin.MattermostPlugin
}
func (p *MyPlugin) ServeHTTP(c *plugin.Context, w http.ResponseWriter, r *http.Request) {
w.Write([]byte("plugin response"))
}
func main() {
plugin.ClientMain(&MyPlugin{})
}
`
for _, goVersion := range strings.Fields(os.Getenv("GO_COMPATIBILITY_TEST_VERSIONS")) {
t.Run(goVersion, func(t *testing.T) {
tearDown, ids, errs := SetAppEnvironmentWithPluginsGoVersion(t, []string{pluginCode}, th.App, th.NewPluginAPI, goVersion)
defer tearDown()
require.NoError(t, errs[0])
require.Len(t, ids, 1)
pluginID := ids[0]
res := makePluginHTTPRequest(t, pluginID, th.Server.ListenAddr.Port, "")
assert.Equal(t, "plugin response", res)
})
}
}

Просмотреть файл

@@ -31,6 +31,14 @@ import (
)
func SetAppEnvironmentWithPlugins(t *testing.T, pluginCode []string, app *App, apiFunc func(*model.Manifest) plugin.API) (func(), []string, []error) {
return setAppEnvironmentWithPlugins(t, pluginCode, app, apiFunc, "")
}
func SetAppEnvironmentWithPluginsGoVersion(t *testing.T, pluginCode []string, app *App, apiFunc func(*model.Manifest) plugin.API, goVersion string) (func(), []string, []error) {
return setAppEnvironmentWithPlugins(t, pluginCode, app, apiFunc, goVersion)
}
func setAppEnvironmentWithPlugins(t *testing.T, pluginCode []string, app *App, apiFunc func(*model.Manifest) plugin.API, goVersion string) (func(), []string, []error) {
pluginDir, err := os.MkdirTemp("", "")
require.NoError(t, err)
webappPluginDir, err := os.MkdirTemp("", "")
@@ -45,7 +53,7 @@ func SetAppEnvironmentWithPlugins(t *testing.T, pluginCode []string, app *App, a
for _, code := range pluginCode {
pluginID := model.NewId()
backend := filepath.Join(pluginDir, pluginID, "backend.exe")
utils.CompileGo(t, code, backend)
utils.CompileGoVersion(t, goVersion, code, backend)
err = os.WriteFile(filepath.Join(pluginDir, pluginID, "plugin.json"), []byte(`{"id": "`+pluginID+`", "server": {"executable": "backend.exe"}}`), 0600)
require.NoError(t, err)
@@ -327,7 +335,8 @@ func TestHookMessageHasBeenPosted(t *testing.T) {
func main() {
plugin.ClientMain(&MyPlugin{})
}
`}, th.App, func(*model.Manifest) plugin.API { return &mockAPI })
`,
}, th.App, func(*model.Manifest) plugin.API { return &mockAPI })
defer tearDown()
post := &model.Post{
@@ -366,7 +375,8 @@ func TestHookMessageWillBeUpdated(t *testing.T) {
func main() {
plugin.ClientMain(&MyPlugin{})
}
`}, th.App, th.NewPluginAPI)
`,
}, th.App, th.NewPluginAPI)
defer tearDown()
post := &model.Post{
@@ -414,7 +424,8 @@ func TestHookMessageHasBeenUpdated(t *testing.T) {
func main() {
plugin.ClientMain(&MyPlugin{})
}
`}, th.App, func(*model.Manifest) plugin.API { return &mockAPI })
`,
}, th.App, func(*model.Manifest) plugin.API { return &mockAPI })
defer tearDown()
post := &model.Post{
@@ -460,7 +471,8 @@ func TestHookMessageHasBeenDeleted(t *testing.T) {
func main() {
plugin.ClientMain(&MyPlugin{})
}
`}, th.App, func(*model.Manifest) plugin.API { return &mockAPI })
`,
}, th.App, func(*model.Manifest) plugin.API { return &mockAPI })
defer tearDown()
post := &model.Post{
@@ -726,7 +738,8 @@ func TestUserWillLogIn_Blocked(t *testing.T) {
func main() {
plugin.ClientMain(&MyPlugin{})
}
`}, th.App, th.NewPluginAPI)
`,
}, th.App, th.NewPluginAPI)
defer tearDown()
r := &http.Request{}
@@ -766,7 +779,8 @@ func TestUserWillLogInIn_Passed(t *testing.T) {
func main() {
plugin.ClientMain(&MyPlugin{})
}
`}, th.App, th.NewPluginAPI)
`,
}, th.App, th.NewPluginAPI)
defer tearDown()
r := &http.Request{}
@@ -808,7 +822,8 @@ func TestUserHasLoggedIn(t *testing.T) {
func main() {
plugin.ClientMain(&MyPlugin{})
}
`}, th.App, th.NewPluginAPI)
`,
}, th.App, th.NewPluginAPI)
defer tearDown()
r := &http.Request{}
@@ -850,7 +865,8 @@ func TestUserHasBeenDeactivated(t *testing.T) {
func main() {
plugin.ClientMain(&MyPlugin{})
}
`}, th.App, th.NewPluginAPI)
`,
}, th.App, th.NewPluginAPI)
defer tearDown()
user := &model.User{
@@ -898,7 +914,8 @@ func TestUserHasBeenCreated(t *testing.T) {
func main() {
plugin.ClientMain(&MyPlugin{})
}
`}, th.App, th.NewPluginAPI)
`,
}, th.App, th.NewPluginAPI)
defer tearDown()
user := &model.User{
@@ -943,7 +960,8 @@ func TestErrorString(t *testing.T) {
func main() {
plugin.ClientMain(&MyPlugin{})
}
`}, th.App, th.NewPluginAPI)
`,
}, th.App, th.NewPluginAPI)
defer tearDown()
require.Len(t, activationErrors, 1)
@@ -973,7 +991,8 @@ func TestErrorString(t *testing.T) {
func main() {
plugin.ClientMain(&MyPlugin{})
}
`}, th.App, th.NewPluginAPI)
`,
}, th.App, th.NewPluginAPI)
defer tearDown()
require.Len(t, activationErrors, 1)
@@ -1029,7 +1048,8 @@ func TestHookContext(t *testing.T) {
func main() {
plugin.ClientMain(&MyPlugin{})
}
`}, th.App, func(*model.Manifest) plugin.API { return &mockAPI })
`,
}, th.App, func(*model.Manifest) plugin.API { return &mockAPI })
defer tearDown()
post := &model.Post{
@@ -1077,7 +1097,8 @@ func TestActiveHooks(t *testing.T) {
func main() {
plugin.ClientMain(&MyPlugin{})
}
`}, th.App, th.NewPluginAPI)
`,
}, th.App, th.NewPluginAPI)
defer tearDown()
require.Len(t, pluginIDs, 1)
@@ -1133,8 +1154,7 @@ func TestHookMetrics(t *testing.T) {
pluginID := model.NewId()
backend := filepath.Join(pluginDir, pluginID, "backend.exe")
code :=
`
code := `
package main
import (
@@ -1241,7 +1261,8 @@ func TestHookReactionHasBeenAdded(t *testing.T) {
func main() {
plugin.ClientMain(&MyPlugin{})
}
`}, th.App, func(*model.Manifest) plugin.API { return &mockAPI })
`,
}, th.App, func(*model.Manifest) plugin.API { return &mockAPI })
defer tearDown()
reaction := &model.Reaction{
@@ -1283,7 +1304,8 @@ func TestHookReactionHasBeenRemoved(t *testing.T) {
func main() {
plugin.ClientMain(&MyPlugin{})
}
`}, th.App, func(*model.Manifest) plugin.API { return &mockAPI })
`,
}, th.App, func(*model.Manifest) plugin.API { return &mockAPI })
defer tearDown()
reaction := &model.Reaction{
@@ -1326,7 +1348,8 @@ func TestHookRunDataRetention(t *testing.T) {
func main() {
plugin.ClientMain(&MyPlugin{})
}
`}, th.App, th.NewPluginAPI)
`,
}, th.App, th.NewPluginAPI)
defer tearDown()
require.Len(t, pluginIDs, 1)
@@ -1370,7 +1393,8 @@ func TestHookOnSendDailyTelemetry(t *testing.T) {
func main() {
plugin.ClientMain(&MyPlugin{})
}
`}, th.App, th.NewPluginAPI)
`,
}, th.App, th.NewPluginAPI)
defer tearDown()
require.Len(t, pluginIDs, 1)
@@ -1414,7 +1438,8 @@ func TestHookOnCloudLimitsUpdated(t *testing.T) {
func main() {
plugin.ClientMain(&MyPlugin{})
}
`}, th.App, th.NewPluginAPI)
`,
}, th.App, th.NewPluginAPI)
defer tearDown()
require.Len(t, pluginIDs, 1)