Plugins: Split plugin manager into smaller components (#54384)

* split out plugin manager

* remove whitespace

* fix tests

* split up tests

* updating naming conventions

* simplify manager

* tidy

* add more fakes

* testing time

* add query verif to int test

* renaming

* add process tests

* tidy up manager tests

* add extra case to int test

* add more coverage to store and process tests

* remove comment

* fix capatilization

* init on provide

* remove addfromsource from API
This commit is contained in:
Will Browne
2022-08-30 17:30:43 +02:00
committed by GitHub
parent acbbdccba9
commit 4a707e2a88
22 changed files with 1623 additions and 1319 deletions
+91 -47
View File
@@ -2,24 +2,29 @@ package manager
import (
"context"
"encoding/json"
"net/http"
"path/filepath"
"strings"
"testing"
"time"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"go.opentelemetry.io/otel/trace"
"gopkg.in/ini.v1"
"github.com/grafana/grafana-plugin-sdk-go/backend"
"github.com/grafana/grafana-plugin-sdk-go/backend/httpclient"
"github.com/grafana/grafana/pkg/infra/tracing"
"github.com/grafana/grafana/pkg/plugins"
"github.com/grafana/grafana/pkg/plugins/backendplugin/coreplugin"
"github.com/grafana/grafana/pkg/plugins/backendplugin/provider"
"github.com/grafana/grafana/pkg/plugins/manager/client"
"github.com/grafana/grafana/pkg/plugins/manager/loader"
"github.com/grafana/grafana/pkg/plugins/manager/registry"
"github.com/grafana/grafana/pkg/plugins/manager/signature"
"github.com/grafana/grafana/pkg/plugins/manager/store"
"github.com/grafana/grafana/pkg/services/featuremgmt"
"github.com/grafana/grafana/pkg/services/licensing"
"github.com/grafana/grafana/pkg/services/searchV2"
@@ -42,7 +47,7 @@ import (
"github.com/grafana/grafana/pkg/tsdb/testdatasource"
)
func TestPluginManager_int_init(t *testing.T) {
func TestIntegrationPluginManager_Run(t *testing.T) {
t.Helper()
staticRootPath, err := filepath.Abs("../../../public/")
@@ -59,9 +64,12 @@ func TestPluginManager_int_init(t *testing.T) {
BundledPluginsPath: bundledPluginsPath,
IsFeatureToggleEnabled: features.IsEnabled,
PluginSettings: map[string]map[string]string{
"plugin.datasource-id": {
"plugin.test-app": {
"path": "testdata/test-app",
},
"plugin.test-panel": {
"not": "included",
},
},
}
@@ -92,17 +100,46 @@ func TestPluginManager_int_init(t *testing.T) {
coreRegistry := coreplugin.ProvideCoreRegistry(am, cw, cm, es, grap, idb, lk, otsdb, pr, tmpo, td, pg, my, ms, graf)
pmCfg := plugins.FromGrafanaCfg(cfg)
pm, err := ProvideService(cfg, registry.NewInMemory(), loader.New(pmCfg, license, signature.NewUnsignedAuthorizer(pmCfg),
reg := registry.ProvideService()
pm, err := ProvideService(cfg, reg, loader.New(pmCfg, license, signature.NewUnsignedAuthorizer(pmCfg),
provider.ProvideService(coreRegistry)), nil)
require.NoError(t, err)
ps := store.ProvideService(reg)
ctx := context.Background()
verifyCorePluginCatalogue(t, ctx, pm)
verifyBundledPlugins(t, ctx, pm)
verifyPluginStaticRoutes(t, ctx, pm)
verifyCorePluginCatalogue(t, ctx, ps)
verifyBundledPlugins(t, ctx, ps)
verifyPluginStaticRoutes(t, ctx, ps)
verifyBackendProcesses(t, pm.pluginRegistry.Plugins(ctx))
verifyPluginQuery(t, ctx, client.ProvideService(reg))
}
func verifyCorePluginCatalogue(t *testing.T, ctx context.Context, pm *PluginManager) {
func verifyPluginQuery(t *testing.T, ctx context.Context, c plugins.Client) {
now := time.Unix(1661420870, 0)
req := &backend.QueryDataRequest{
PluginContext: backend.PluginContext{
PluginID: "testdata",
},
Queries: []backend.DataQuery{
{
RefID: "A",
TimeRange: backend.TimeRange{
From: now.Add(-5 * time.Minute),
To: now,
},
JSON: json.RawMessage(`{"scenarioId":"csv_metric_values","stringInput":"1,20,90,30,5,0"}`),
},
},
}
resp, err := c.QueryData(ctx, req)
require.NoError(t, err)
payload, err := resp.MarshalJSON()
require.NoError(t, err)
require.JSONEq(t, `{"results":{"A":{"frames":[{"schema":{"refId":"A","fields":[{"name":"time","type":"time","typeInfo":{"frame":"time.Time"}},{"name":"A-series","type":"number","typeInfo":{"frame":"int64","nullable":true}}]},"data":{"values":[[1661420570000,1661420630000,1661420690000,1661420750000,1661420810000,1661420870000],[1,20,90,30,5,0]]}}]}}}`, string(payload))
}
func verifyCorePluginCatalogue(t *testing.T, ctx context.Context, ps *store.Service) {
t.Helper()
expPanels := map[string]struct{}{
@@ -168,78 +205,85 @@ func verifyCorePluginCatalogue(t *testing.T, ctx context.Context, pm *PluginMana
"test-app": {},
}
panels := pm.Plugins(ctx, plugins.Panel)
assert.Equal(t, len(expPanels), len(panels))
panels := ps.Plugins(ctx, plugins.Panel)
require.Equal(t, len(expPanels), len(panels))
for _, p := range panels {
p, exists := pm.Plugin(ctx, p.ID)
p, exists := ps.Plugin(ctx, p.ID)
require.NotEqual(t, plugins.PluginDTO{}, p)
assert.True(t, exists)
assert.Contains(t, expPanels, p.ID)
assert.Contains(t, pm.registeredPlugins(ctx), p.ID)
require.True(t, exists)
require.Contains(t, expPanels, p.ID)
}
dataSources := pm.Plugins(ctx, plugins.DataSource)
assert.Equal(t, len(expDataSources), len(dataSources))
dataSources := ps.Plugins(ctx, plugins.DataSource)
require.Equal(t, len(expDataSources), len(dataSources))
for _, ds := range dataSources {
p, exists := pm.Plugin(ctx, ds.ID)
p, exists := ps.Plugin(ctx, ds.ID)
require.NotEqual(t, plugins.PluginDTO{}, p)
assert.True(t, exists)
assert.Contains(t, expDataSources, ds.ID)
assert.Contains(t, pm.registeredPlugins(ctx), ds.ID)
require.True(t, exists)
require.Contains(t, expDataSources, ds.ID)
}
apps := pm.Plugins(ctx, plugins.App)
assert.Equal(t, len(expApps), len(apps))
apps := ps.Plugins(ctx, plugins.App)
require.Equal(t, len(expApps), len(apps))
for _, app := range apps {
p, exists := pm.Plugin(ctx, app.ID)
require.NotEqual(t, plugins.PluginDTO{}, p)
assert.True(t, exists)
assert.Contains(t, expApps, app.ID)
assert.Contains(t, pm.registeredPlugins(ctx), app.ID)
p, exists := ps.Plugin(ctx, app.ID)
require.True(t, exists)
require.NotNil(t, p)
require.Contains(t, expApps, app.ID)
}
assert.Equal(t, len(expPanels)+len(expDataSources)+len(expApps), len(pm.Plugins(ctx)))
require.Equal(t, len(expPanels)+len(expDataSources)+len(expApps), len(ps.Plugins(ctx)))
}
func verifyBundledPlugins(t *testing.T, ctx context.Context, pm *PluginManager) {
func verifyBundledPlugins(t *testing.T, ctx context.Context, ps *store.Service) {
t.Helper()
dsPlugins := make(map[string]struct{})
for _, p := range pm.Plugins(ctx, plugins.DataSource) {
for _, p := range ps.Plugins(ctx, plugins.DataSource) {
dsPlugins[p.ID] = struct{}{}
}
inputPlugin, exists := ps.Plugin(ctx, "input")
require.True(t, exists)
require.NotEqual(t, plugins.PluginDTO{}, inputPlugin)
require.NotNil(t, dsPlugins["input"])
pluginRoutes := make(map[string]*plugins.StaticRoute)
for _, r := range pm.Routes() {
for _, r := range ps.Routes() {
pluginRoutes[r.PluginID] = r
}
inputPlugin, exists := pm.Plugin(ctx, "input")
require.NotEqual(t, plugins.PluginDTO{}, inputPlugin)
assert.True(t, exists)
assert.NotNil(t, dsPlugins["input"])
for _, pluginID := range []string{"input"} {
assert.Contains(t, pluginRoutes, pluginID)
assert.True(t, strings.HasPrefix(pluginRoutes[pluginID].Directory, inputPlugin.PluginDir))
require.Contains(t, pluginRoutes, pluginID)
require.True(t, strings.HasPrefix(pluginRoutes[pluginID].Directory, inputPlugin.PluginDir))
}
}
func verifyPluginStaticRoutes(t *testing.T, ctx context.Context, pm *PluginManager) {
func verifyPluginStaticRoutes(t *testing.T, ctx context.Context, ps *store.Service) {
routes := make(map[string]*plugins.StaticRoute)
for _, route := range pm.Routes() {
for _, route := range ps.Routes() {
routes[route.PluginID] = route
}
assert.Len(t, routes, 2)
require.Len(t, routes, 2)
inputPlugin, _ := pm.Plugin(ctx, "input")
assert.NotNil(t, routes["input"])
assert.Equal(t, routes["input"].Directory, inputPlugin.PluginDir)
inputPlugin, _ := ps.Plugin(ctx, "input")
require.NotNil(t, routes["input"])
require.Equal(t, routes["input"].Directory, inputPlugin.PluginDir)
testAppPlugin, _ := pm.Plugin(ctx, "test-app")
assert.Contains(t, routes, "test-app")
assert.Equal(t, routes["test-app"].Directory, testAppPlugin.PluginDir)
testAppPlugin, _ := ps.Plugin(ctx, "test-app")
require.Contains(t, routes, "test-app")
require.Equal(t, routes["test-app"].Directory, testAppPlugin.PluginDir)
}
func verifyBackendProcesses(t *testing.T, ps []*plugins.Plugin) {
for _, p := range ps {
if p.Backend {
pc, exists := p.Client()
require.True(t, exists)
require.NotNil(t, pc)
}
}
}
type fakeTracer struct {