Skip to content

Commit

Permalink
ci: check plugin order
Browse files Browse the repository at this point in the history
Signed-off-by: spacewander <[email protected]>
  • Loading branch information
spacewander committed Nov 21, 2024
1 parent 5affbd8 commit 4830941
Show file tree
Hide file tree
Showing 4 changed files with 118 additions and 33 deletions.
8 changes: 8 additions & 0 deletions api/pkg/plugins/plugins.go
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,14 @@ func LoadPluginType(name string) Plugin {
return pluginTypes[name]
}

func IteratePluginType(f func(key string, value Plugin) bool) {
for k, v := range pluginTypes {
if !f(k, v) {
return
}

Check warning on line 89 in api/pkg/plugins/plugins.go

View check run for this annotation

Codecov / codecov/patch

api/pkg/plugins/plugins.go#L88-L89

Added lines #L88 - L89 were not covered by tests
}
}

// We separate the plugin type storage and plugin storage, to avoid plugin type overrides the plugin by accident.

func RegisterPlugin(name string, plugin Plugin) {
Expand Down
15 changes: 15 additions & 0 deletions api/pkg/plugins/plugins_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,21 @@ import (
_ "mosn.io/htnn/api/plugins/tests/pkg/envoy" // for log implementation
)

func TestIteratePluginType(t *testing.T) {
plugin := &MockPlugin{}
RegisterPlugin("test", plugin)
RegisterPluginType("test2", plugin)

names := []string{}
IteratePluginType(func(name string, p Plugin) bool {
names = append(names, name)
assert.Equal(t, p, plugin)
return true
})
assert.Contains(t, names, "test")
assert.Contains(t, names, "test2")
}

func TestIteratePlugin(t *testing.T) {
plugin := &MockPlugin{}
RegisterPlugin("test", plugin)
Expand Down
71 changes: 39 additions & 32 deletions maintainer/feature_maturity_level.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -13,84 +13,91 @@
# When adding a new feature, please set the experimental_since field to the next release.

plugins:
- name: bandwidth_limit
# The order here is the same as the order of the plugin execution.
# This is guaranteed in the CI.
# TODO: This file only show the plugin's registried order. We should consider a fact that
# some plugins may not be executed in the DecodeHeaders phase. For example, a plugin called when
# processing response which is registried in an early place is executed after a plugin called
# when processing request which is registried in a later place.
- name: listenerPatch
status: experimental
experimental_since: 0.4.0
- name: buffer
- name: tlsInspector
status: experimental
experimental_since: 0.4.0
- name: casbin
- name: networkRBAC
status: experimental
experimental_since: 0.4.0
- name: cel_script
- name: bandwidthLimit
status: experimental
experimental_since: 0.4.0
- name: consumer_restriction
- name: buffer
status: experimental
experimental_since: 0.4.0
- name: cors
- name: localRatelimit
status: stable
stable_since: 0.4.0
- name: debug_mode
- name: outerExtProc
status: experimental
experimental_since: 0.4.0
- name: demo
- name: outerLua
status: experimental
experimental_since: 0.4.0
- name: ext_auth
- name: cors
status: stable
stable_since: 0.4.0
- name: fault
status: stable
stable_since: 0.4.0
- name: hmac_auth
status: experimental
experimental_since: 0.4.0
- name: inner_ext_proc
- name: debugMode
status: experimental
experimental_since: 0.4.0
- name: inner_lua
- name: hmacAuth
status: experimental
experimental_since: 0.4.0
- name: key_auth
- name: keyAuth
status: stable
stable_since: 0.4.0
- name: limit_count_redis
- name: oidc
status: experimental
experimental_since: 0.4.0
- name: casbin
status: experimental
experimental_since: 0.4.0
- name: consumerRestriction
status: experimental
experimental_since: 0.4.0
- name: extAuth
status: stable
stable_since: 0.4.0
- name: limit_req
- name: opa
status: experimental
experimental_since: 0.4.0
- name: listener_patch
- name: celScript
status: experimental
experimental_since: 0.4.0
- name: local_ratelimit
- name: limitCountRedis
status: stable
stable_since: 0.4.0
- name: network_rbac
- name: limitReq
status: experimental
experimental_since: 0.4.0
- name: oidc
- name: sentinel
status: experimental
experimental_since: 0.4.0
- name: opa
experimental_since: 0.5.0
- name: demo
status: experimental
experimental_since: 0.4.0
- name: outer_ext_proc
- name: innerExtProc
status: experimental
experimental_since: 0.4.0
- name: outer_lua
- name: innerLua
status: experimental
experimental_since: 0.4.0
- name: route_patch
- name: routePatch
status: experimental
experimental_since: 0.4.1
- name: sentinel
status: experimental
experimental_since: 0.5.0
- name: tls_inspector
status: experimental
experimental_since: 0.4.0

registries:
- name: consul
status: experimental
Expand Down
57 changes: 56 additions & 1 deletion tools/cmd/linter/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,18 @@ import (
"path/filepath"
"reflect"
"slices"
"sort"
"strings"

"github.com/pmezard/go-difflib/difflib"
protoparser "github.com/yoheimuta/go-protoparser/v4"
"github.com/yoheimuta/go-protoparser/v4/parser"
"golang.org/x/text/cases"
"golang.org/x/text/language"
"gopkg.in/yaml.v3"

"mosn.io/htnn/api/pkg/plugins"
_ "mosn.io/htnn/types/plugins"
)

// This tool does what the third party linters don't
Expand Down Expand Up @@ -257,6 +262,13 @@ func snakeToCamel(s string) string {
return strings.Join(words, "")
}

func filenameToPluginName(name string) string {
if name == "network_rbac" {
return "networkRBAC"
}
return snakeToCamel(name)
}

func lintFilenameForDoc(root string) error {
return filepath.Walk(root, func(path string, info fs.FileInfo, err error) error {
if err != nil {
Expand Down Expand Up @@ -594,7 +606,7 @@ func getFeatureMaturityLevel(category string) ([]maturityLevel, error) {

name := filepath.Base(path)[:len(filepath.Base(path))-len(ext)]
res = append(res, maturityLevel{
name: name,
name: filenameToPluginName(name),
maturity: status,
})
return nil
Expand Down Expand Up @@ -641,6 +653,29 @@ func lintFeatureMaturityLevel() error {
}
}

// also check the plugin execution order documented in this file
type pluginWrapper struct {
Name string
plugins.Plugin
}
var pluginList []pluginWrapper
plugins.IteratePluginType(func(name string, p plugins.Plugin) bool {
pluginList = append(pluginList, pluginWrapper{
Name: name,
Plugin: p,
})
return true
})
sort.Slice(pluginList, func(i, j int) bool {
return plugins.ComparePluginOrder(pluginList[i].Name, pluginList[j].Name)
})

var recordedOrder []string
var runtimeOrder []string
for _, p := range pluginList {
runtimeOrder = append(runtimeOrder, p.Name+"\n")
}

for category, recs := range records {
for _, record := range recs {
if record.Status == "experimental" {
Expand Down Expand Up @@ -670,6 +705,11 @@ func lintFeatureMaturityLevel() error {
if !found {
return fmt.Errorf("feature maturity record of %s %s is missing in the documentation", category, record.Name)
}

if category == "plugins" {
name := record.Name + "\n"
recordedOrder = append(recordedOrder, name)
}
}
}
for _, category := range Categories {
Expand All @@ -678,6 +718,21 @@ func lintFeatureMaturityLevel() error {
}
}

diff := difflib.UnifiedDiff{
A: recordedOrder,
B: runtimeOrder,
FromFile: "Expected",
ToFile: "Actual",
Context: 3,
}
text, err := difflib.GetUnifiedDiffString(diff)
if err != nil {
return err
}
if text != "" {
return errors.New("Plugin order is not correct:\n" + text + ". Please fix the order in " + recordFile)
}

return nil
}

Expand Down

0 comments on commit 4830941

Please sign in to comment.