2021-11-01 04:53:33 -05:00
|
|
|
package loader
|
|
|
|
|
|
|
|
import (
|
2022-01-14 06:30:39 -06:00
|
|
|
"context"
|
2023-06-07 10:22:43 -05:00
|
|
|
"errors"
|
2021-11-01 04:53:33 -05:00
|
|
|
"path/filepath"
|
|
|
|
"sort"
|
|
|
|
"testing"
|
|
|
|
|
|
|
|
"github.com/google/go-cmp/cmp"
|
|
|
|
"github.com/google/go-cmp/cmp/cmpopts"
|
2022-01-14 06:30:39 -06:00
|
|
|
"github.com/stretchr/testify/require"
|
2021-11-01 04:53:33 -05:00
|
|
|
|
|
|
|
"github.com/grafana/grafana/pkg/plugins"
|
2023-04-12 04:34:16 -05:00
|
|
|
"github.com/grafana/grafana/pkg/plugins/backendplugin"
|
2022-09-14 08:35:35 -05:00
|
|
|
"github.com/grafana/grafana/pkg/plugins/config"
|
2023-02-28 09:10:27 -06:00
|
|
|
"github.com/grafana/grafana/pkg/plugins/log"
|
2022-09-23 07:27:01 -05:00
|
|
|
"github.com/grafana/grafana/pkg/plugins/manager/fakes"
|
2023-07-04 04:03:10 -05:00
|
|
|
"github.com/grafana/grafana/pkg/plugins/manager/loader/angular/angularinspector"
|
2023-03-20 08:35:49 -05:00
|
|
|
"github.com/grafana/grafana/pkg/plugins/manager/loader/assetpath"
|
2021-11-01 04:53:33 -05:00
|
|
|
"github.com/grafana/grafana/pkg/plugins/manager/loader/initializer"
|
2023-07-27 08:29:13 -05:00
|
|
|
"github.com/grafana/grafana/pkg/plugins/manager/pipeline/bootstrap"
|
|
|
|
"github.com/grafana/grafana/pkg/plugins/manager/pipeline/discovery"
|
|
|
|
"github.com/grafana/grafana/pkg/plugins/manager/registry"
|
2021-11-01 04:53:33 -05:00
|
|
|
"github.com/grafana/grafana/pkg/plugins/manager/signature"
|
2023-03-20 08:35:49 -05:00
|
|
|
"github.com/grafana/grafana/pkg/plugins/manager/sources"
|
|
|
|
"github.com/grafana/grafana/pkg/plugins/pluginscdn"
|
2023-06-08 05:21:19 -05:00
|
|
|
"github.com/grafana/grafana/pkg/services/org"
|
2021-11-01 04:53:33 -05:00
|
|
|
"github.com/grafana/grafana/pkg/setting"
|
|
|
|
)
|
|
|
|
|
2023-04-27 03:26:15 -05:00
|
|
|
var compareOpts = []cmp.Option{cmpopts.IgnoreFields(plugins.Plugin{}, "client", "log"), fsComparer}
|
2023-03-07 09:47:02 -06:00
|
|
|
|
2023-04-27 03:26:15 -05:00
|
|
|
var fsComparer = cmp.Comparer(func(fs1 plugins.FS, fs2 plugins.FS) bool {
|
|
|
|
fs1Files, err := fs1.Files()
|
|
|
|
if err != nil {
|
|
|
|
panic(err)
|
|
|
|
}
|
|
|
|
fs2Files, err := fs2.Files()
|
|
|
|
if err != nil {
|
|
|
|
panic(err)
|
|
|
|
}
|
2023-03-07 09:47:02 -06:00
|
|
|
|
|
|
|
sort.SliceStable(fs1Files, func(i, j int) bool {
|
|
|
|
return fs1Files[i] < fs1Files[j]
|
|
|
|
})
|
|
|
|
|
|
|
|
sort.SliceStable(fs2Files, func(i, j int) bool {
|
|
|
|
return fs2Files[i] < fs2Files[j]
|
|
|
|
})
|
|
|
|
|
|
|
|
return cmp.Equal(fs1Files, fs2Files) && fs1.Base() == fs2.Base()
|
|
|
|
})
|
2021-11-01 04:53:33 -05:00
|
|
|
|
|
|
|
func TestLoader_Load(t *testing.T) {
|
|
|
|
corePluginDir, err := filepath.Abs("./../../../../public")
|
|
|
|
if err != nil {
|
|
|
|
t.Errorf("could not construct absolute path of core plugins dir")
|
|
|
|
return
|
|
|
|
}
|
|
|
|
parentDir, err := filepath.Abs("../")
|
|
|
|
if err != nil {
|
|
|
|
t.Errorf("could not construct absolute path of current dir")
|
|
|
|
return
|
|
|
|
}
|
|
|
|
tests := []struct {
|
2022-09-23 07:27:01 -05:00
|
|
|
name string
|
|
|
|
class plugins.Class
|
|
|
|
cfg *config.Cfg
|
|
|
|
pluginPaths []string
|
|
|
|
want []*plugins.Plugin
|
|
|
|
pluginErrors map[string]*plugins.Error
|
2021-11-01 04:53:33 -05:00
|
|
|
}{
|
|
|
|
{
|
2022-09-14 08:35:35 -05:00
|
|
|
name: "Load a Core plugin",
|
2023-06-08 05:21:19 -05:00
|
|
|
class: plugins.ClassCore,
|
2022-09-14 08:35:35 -05:00
|
|
|
cfg: &config.Cfg{},
|
2021-11-01 04:53:33 -05:00
|
|
|
pluginPaths: []string{filepath.Join(corePluginDir, "app/plugins/datasource/cloudwatch")},
|
|
|
|
want: []*plugins.Plugin{
|
|
|
|
{
|
|
|
|
JSONData: plugins.JSONData{
|
|
|
|
ID: "cloudwatch",
|
2023-06-08 05:21:19 -05:00
|
|
|
Type: plugins.TypeDataSource,
|
2021-11-01 04:53:33 -05:00
|
|
|
Name: "CloudWatch",
|
|
|
|
Info: plugins.Info{
|
|
|
|
Author: plugins.InfoLink{
|
|
|
|
Name: "Grafana Labs",
|
|
|
|
URL: "https://grafana.com",
|
|
|
|
},
|
|
|
|
Description: "Data source for Amazon AWS monitoring service",
|
|
|
|
Logos: plugins.Logos{
|
|
|
|
Small: "public/app/plugins/datasource/cloudwatch/img/amazon-web-services.png",
|
|
|
|
Large: "public/app/plugins/datasource/cloudwatch/img/amazon-web-services.png",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
Includes: []*plugins.Includes{
|
|
|
|
{Name: "EC2", Path: "dashboards/ec2.json", Type: "dashboard", Role: "Viewer"},
|
|
|
|
{Name: "EBS", Path: "dashboards/EBS.json", Type: "dashboard", Role: "Viewer"},
|
|
|
|
{Name: "Lambda", Path: "dashboards/Lambda.json", Type: "dashboard", Role: "Viewer"},
|
|
|
|
{Name: "Logs", Path: "dashboards/Logs.json", Type: "dashboard", Role: "Viewer"},
|
|
|
|
{Name: "RDS", Path: "dashboards/RDS.json", Type: "dashboard", Role: "Viewer"},
|
|
|
|
},
|
|
|
|
Dependencies: plugins.Dependencies{
|
|
|
|
GrafanaVersion: "*",
|
|
|
|
Plugins: []plugins.Dependency{},
|
|
|
|
},
|
|
|
|
Category: "cloud",
|
|
|
|
Annotations: true,
|
|
|
|
Metrics: true,
|
|
|
|
Alerting: true,
|
|
|
|
Logs: true,
|
2021-12-22 10:59:26 -06:00
|
|
|
Backend: true,
|
2021-11-01 04:53:33 -05:00
|
|
|
QueryOptions: map[string]bool{"minInterval": true},
|
|
|
|
},
|
2023-03-07 09:47:02 -06:00
|
|
|
Module: "app/plugins/datasource/cloudwatch/module",
|
|
|
|
BaseURL: "public/app/plugins/datasource/cloudwatch",
|
2023-04-27 03:26:15 -05:00
|
|
|
|
|
|
|
FS: mustNewStaticFSForTests(t, filepath.Join(corePluginDir, "app/plugins/datasource/cloudwatch")),
|
2023-06-08 05:21:19 -05:00
|
|
|
Signature: plugins.SignatureStatusInternal,
|
|
|
|
Class: plugins.ClassCore,
|
2021-11-01 04:53:33 -05:00
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
{
|
2022-09-14 08:35:35 -05:00
|
|
|
name: "Load a Bundled plugin",
|
2023-06-08 05:21:19 -05:00
|
|
|
class: plugins.ClassBundled,
|
2022-09-14 08:35:35 -05:00
|
|
|
cfg: &config.Cfg{},
|
2021-11-01 04:53:33 -05:00
|
|
|
pluginPaths: []string{"../testdata/valid-v2-signature"},
|
|
|
|
want: []*plugins.Plugin{
|
|
|
|
{
|
|
|
|
JSONData: plugins.JSONData{
|
2022-08-22 11:11:45 -05:00
|
|
|
ID: "test-datasource",
|
2023-06-08 05:21:19 -05:00
|
|
|
Type: plugins.TypeDataSource,
|
2021-11-01 04:53:33 -05:00
|
|
|
Name: "Test",
|
|
|
|
Info: plugins.Info{
|
|
|
|
Author: plugins.InfoLink{
|
|
|
|
Name: "Will Browne",
|
|
|
|
URL: "https://willbrowne.com",
|
|
|
|
},
|
|
|
|
Version: "1.0.0",
|
|
|
|
Logos: plugins.Logos{
|
|
|
|
Small: "public/img/icn-datasource.svg",
|
|
|
|
Large: "public/img/icn-datasource.svg",
|
|
|
|
},
|
|
|
|
Description: "Test",
|
|
|
|
},
|
|
|
|
Dependencies: plugins.Dependencies{
|
|
|
|
GrafanaVersion: "*",
|
|
|
|
Plugins: []plugins.Dependency{},
|
|
|
|
},
|
|
|
|
Executable: "test",
|
|
|
|
Backend: true,
|
|
|
|
State: "alpha",
|
|
|
|
},
|
2023-04-27 03:26:15 -05:00
|
|
|
Module: "plugins/test-datasource/module",
|
|
|
|
BaseURL: "public/plugins/test-datasource",
|
|
|
|
FS: mustNewStaticFSForTests(t, filepath.Join(parentDir, "testdata/valid-v2-signature/plugin/")),
|
2021-11-01 04:53:33 -05:00
|
|
|
Signature: "valid",
|
2023-06-08 05:21:19 -05:00
|
|
|
SignatureType: plugins.SignatureTypeGrafana,
|
2021-11-01 04:53:33 -05:00
|
|
|
SignatureOrg: "Grafana Labs",
|
2023-06-08 05:21:19 -05:00
|
|
|
Class: plugins.ClassBundled,
|
2021-11-01 04:53:33 -05:00
|
|
|
},
|
|
|
|
},
|
|
|
|
}, {
|
2022-09-14 08:35:35 -05:00
|
|
|
name: "Load plugin with symbolic links",
|
2023-06-08 05:21:19 -05:00
|
|
|
class: plugins.ClassExternal,
|
2022-09-14 08:35:35 -05:00
|
|
|
cfg: &config.Cfg{},
|
2021-11-01 04:53:33 -05:00
|
|
|
pluginPaths: []string{"../testdata/symbolic-plugin-dirs"},
|
|
|
|
want: []*plugins.Plugin{
|
|
|
|
{
|
|
|
|
JSONData: plugins.JSONData{
|
|
|
|
ID: "test-app",
|
|
|
|
Type: "app",
|
|
|
|
Name: "Test App",
|
|
|
|
Info: plugins.Info{
|
|
|
|
Author: plugins.InfoLink{
|
|
|
|
Name: "Test Inc.",
|
|
|
|
URL: "http://test.com",
|
|
|
|
},
|
|
|
|
Logos: plugins.Logos{
|
|
|
|
Small: "public/plugins/test-app/img/logo_small.png",
|
|
|
|
Large: "public/plugins/test-app/img/logo_large.png",
|
|
|
|
},
|
|
|
|
Links: []plugins.InfoLink{
|
|
|
|
{Name: "Project site", URL: "http://project.com"},
|
|
|
|
{Name: "License & Terms", URL: "http://license.com"},
|
|
|
|
},
|
|
|
|
Description: "Official Grafana Test App & Dashboard bundle",
|
|
|
|
Screenshots: []plugins.Screenshots{
|
|
|
|
{Path: "public/plugins/test-app/img/screenshot1.png", Name: "img1"},
|
|
|
|
{Path: "public/plugins/test-app/img/screenshot2.png", Name: "img2"},
|
|
|
|
},
|
|
|
|
Version: "1.0.0",
|
|
|
|
Updated: "2015-02-10",
|
|
|
|
},
|
|
|
|
Dependencies: plugins.Dependencies{
|
|
|
|
GrafanaVersion: "3.x.x",
|
|
|
|
Plugins: []plugins.Dependency{
|
|
|
|
{Type: "datasource", ID: "graphite", Name: "Graphite", Version: "1.0.0"},
|
|
|
|
{Type: "panel", ID: "graph", Name: "Graph", Version: "1.0.0"},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
Includes: []*plugins.Includes{
|
|
|
|
{
|
|
|
|
Name: "Nginx Connections",
|
|
|
|
Path: "dashboards/connections.json",
|
|
|
|
Type: "dashboard",
|
2023-06-08 05:21:19 -05:00
|
|
|
Role: org.RoleViewer,
|
2021-11-01 04:53:33 -05:00
|
|
|
Slug: "nginx-connections",
|
|
|
|
},
|
|
|
|
{
|
|
|
|
Name: "Nginx Memory",
|
|
|
|
Path: "dashboards/memory.json",
|
|
|
|
Type: "dashboard",
|
2023-06-08 05:21:19 -05:00
|
|
|
Role: org.RoleViewer,
|
2021-11-01 04:53:33 -05:00
|
|
|
Slug: "nginx-memory",
|
|
|
|
},
|
|
|
|
{
|
|
|
|
Name: "Nginx Panel",
|
2023-06-08 05:21:19 -05:00
|
|
|
Type: string(plugins.TypePanel),
|
|
|
|
Role: org.RoleViewer,
|
2021-11-01 04:53:33 -05:00
|
|
|
Slug: "nginx-panel"},
|
|
|
|
{
|
|
|
|
Name: "Nginx Datasource",
|
2023-06-08 05:21:19 -05:00
|
|
|
Type: string(plugins.TypeDataSource),
|
|
|
|
Role: org.RoleViewer,
|
2021-11-01 04:53:33 -05:00
|
|
|
Slug: "nginx-datasource",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
2023-06-08 05:21:19 -05:00
|
|
|
Class: plugins.ClassExternal,
|
2023-04-27 03:26:15 -05:00
|
|
|
Module: "plugins/test-app/module",
|
|
|
|
BaseURL: "public/plugins/test-app",
|
|
|
|
FS: mustNewStaticFSForTests(t, filepath.Join(parentDir, "testdata/includes-symlinks")),
|
2021-11-01 04:53:33 -05:00
|
|
|
Signature: "valid",
|
2023-06-08 05:21:19 -05:00
|
|
|
SignatureType: plugins.SignatureTypeGrafana,
|
2021-11-01 04:53:33 -05:00
|
|
|
SignatureOrg: "Grafana Labs",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
}, {
|
2022-01-14 06:30:39 -06:00
|
|
|
name: "Load an unsigned plugin (development)",
|
2023-06-08 05:21:19 -05:00
|
|
|
class: plugins.ClassExternal,
|
2022-09-14 08:35:35 -05:00
|
|
|
cfg: &config.Cfg{
|
|
|
|
DevMode: true,
|
2021-11-01 04:53:33 -05:00
|
|
|
},
|
|
|
|
pluginPaths: []string{"../testdata/unsigned-datasource"},
|
|
|
|
want: []*plugins.Plugin{
|
|
|
|
{
|
|
|
|
JSONData: plugins.JSONData{
|
2022-08-22 11:11:45 -05:00
|
|
|
ID: "test-datasource",
|
2023-06-08 05:21:19 -05:00
|
|
|
Type: plugins.TypeDataSource,
|
2021-11-01 04:53:33 -05:00
|
|
|
Name: "Test",
|
|
|
|
Info: plugins.Info{
|
|
|
|
Author: plugins.InfoLink{
|
|
|
|
Name: "Grafana Labs",
|
|
|
|
URL: "https://grafana.com",
|
|
|
|
},
|
|
|
|
Logos: plugins.Logos{
|
|
|
|
Small: "public/img/icn-datasource.svg",
|
|
|
|
Large: "public/img/icn-datasource.svg",
|
|
|
|
},
|
|
|
|
Description: "Test",
|
|
|
|
},
|
|
|
|
Dependencies: plugins.Dependencies{
|
|
|
|
GrafanaVersion: "*",
|
|
|
|
Plugins: []plugins.Dependency{},
|
|
|
|
},
|
|
|
|
Backend: true,
|
2023-06-08 05:21:19 -05:00
|
|
|
State: plugins.ReleaseStateAlpha,
|
2021-11-01 04:53:33 -05:00
|
|
|
},
|
2023-06-08 05:21:19 -05:00
|
|
|
Class: plugins.ClassExternal,
|
2023-04-27 03:26:15 -05:00
|
|
|
Module: "plugins/test-datasource/module",
|
|
|
|
BaseURL: "public/plugins/test-datasource",
|
|
|
|
FS: mustNewStaticFSForTests(t, filepath.Join(parentDir, "testdata/unsigned-datasource/plugin")),
|
2021-11-01 04:53:33 -05:00
|
|
|
Signature: "unsigned",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
}, {
|
2022-09-14 08:35:35 -05:00
|
|
|
name: "Load an unsigned plugin (production)",
|
2023-06-08 05:21:19 -05:00
|
|
|
class: plugins.ClassExternal,
|
2022-09-14 08:35:35 -05:00
|
|
|
cfg: &config.Cfg{},
|
2021-11-01 04:53:33 -05:00
|
|
|
pluginPaths: []string{"../testdata/unsigned-datasource"},
|
|
|
|
want: []*plugins.Plugin{},
|
|
|
|
pluginErrors: map[string]*plugins.Error{
|
2022-08-22 11:11:45 -05:00
|
|
|
"test-datasource": {
|
|
|
|
PluginID: "test-datasource",
|
2021-11-01 04:53:33 -05:00
|
|
|
ErrorCode: "signatureMissing",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
{
|
2022-01-14 06:30:39 -06:00
|
|
|
name: "Load an unsigned plugin using PluginsAllowUnsigned config (production)",
|
2023-06-08 05:21:19 -05:00
|
|
|
class: plugins.ClassExternal,
|
2022-09-14 08:35:35 -05:00
|
|
|
cfg: &config.Cfg{
|
2022-08-22 11:11:45 -05:00
|
|
|
PluginsAllowUnsigned: []string{"test-datasource"},
|
2021-11-01 04:53:33 -05:00
|
|
|
},
|
|
|
|
pluginPaths: []string{"../testdata/unsigned-datasource"},
|
|
|
|
want: []*plugins.Plugin{
|
|
|
|
{
|
|
|
|
JSONData: plugins.JSONData{
|
2022-08-22 11:11:45 -05:00
|
|
|
ID: "test-datasource",
|
2023-06-08 05:21:19 -05:00
|
|
|
Type: plugins.TypeDataSource,
|
2021-11-01 04:53:33 -05:00
|
|
|
Name: "Test",
|
|
|
|
Info: plugins.Info{
|
|
|
|
Author: plugins.InfoLink{
|
|
|
|
Name: "Grafana Labs",
|
|
|
|
URL: "https://grafana.com",
|
|
|
|
},
|
|
|
|
Logos: plugins.Logos{
|
|
|
|
Small: "public/img/icn-datasource.svg",
|
|
|
|
Large: "public/img/icn-datasource.svg",
|
|
|
|
},
|
|
|
|
Description: "Test",
|
|
|
|
},
|
|
|
|
Dependencies: plugins.Dependencies{
|
|
|
|
GrafanaVersion: "*",
|
|
|
|
Plugins: []plugins.Dependency{},
|
|
|
|
},
|
|
|
|
Backend: true,
|
2023-06-08 05:21:19 -05:00
|
|
|
State: plugins.ReleaseStateAlpha,
|
2021-11-01 04:53:33 -05:00
|
|
|
},
|
2023-06-08 05:21:19 -05:00
|
|
|
Class: plugins.ClassExternal,
|
2023-04-27 03:26:15 -05:00
|
|
|
Module: "plugins/test-datasource/module",
|
|
|
|
BaseURL: "public/plugins/test-datasource",
|
|
|
|
FS: mustNewStaticFSForTests(t, filepath.Join(parentDir, "testdata/unsigned-datasource/plugin")),
|
2023-06-08 05:21:19 -05:00
|
|
|
Signature: plugins.SignatureStatusUnsigned,
|
2021-11-01 04:53:33 -05:00
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
{
|
2022-10-21 06:54:55 -05:00
|
|
|
name: "Load a plugin with v1 manifest should return signatureInvalid",
|
2023-06-08 05:21:19 -05:00
|
|
|
class: plugins.ClassExternal,
|
2022-09-14 08:35:35 -05:00
|
|
|
cfg: &config.Cfg{},
|
2021-11-01 04:53:33 -05:00
|
|
|
pluginPaths: []string{"../testdata/lacking-files"},
|
|
|
|
want: []*plugins.Plugin{},
|
|
|
|
pluginErrors: map[string]*plugins.Error{
|
2022-08-22 11:11:45 -05:00
|
|
|
"test-datasource": {
|
|
|
|
PluginID: "test-datasource",
|
2022-10-21 06:54:55 -05:00
|
|
|
ErrorCode: "signatureInvalid",
|
2021-11-01 04:53:33 -05:00
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
{
|
2022-10-21 06:54:55 -05:00
|
|
|
name: "Load a plugin with v1 manifest using PluginsAllowUnsigned config (production) should return signatureInvali",
|
2023-06-08 05:21:19 -05:00
|
|
|
class: plugins.ClassExternal,
|
2022-09-14 08:35:35 -05:00
|
|
|
cfg: &config.Cfg{
|
2022-08-22 11:11:45 -05:00
|
|
|
PluginsAllowUnsigned: []string{"test-datasource"},
|
2021-11-01 04:53:33 -05:00
|
|
|
},
|
|
|
|
pluginPaths: []string{"../testdata/lacking-files"},
|
|
|
|
want: []*plugins.Plugin{},
|
|
|
|
pluginErrors: map[string]*plugins.Error{
|
2022-08-22 11:11:45 -05:00
|
|
|
"test-datasource": {
|
|
|
|
PluginID: "test-datasource",
|
2022-10-21 06:54:55 -05:00
|
|
|
ErrorCode: "signatureInvalid",
|
2021-11-01 04:53:33 -05:00
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
2022-07-15 10:42:20 -05:00
|
|
|
{
|
|
|
|
name: "Load a plugin with manifest which has a file not found in plugin folder",
|
2023-06-08 05:21:19 -05:00
|
|
|
class: plugins.ClassExternal,
|
2022-09-14 08:35:35 -05:00
|
|
|
cfg: &config.Cfg{
|
2022-08-22 11:11:45 -05:00
|
|
|
PluginsAllowUnsigned: []string{"test-datasource"},
|
2022-07-15 10:42:20 -05:00
|
|
|
},
|
|
|
|
pluginPaths: []string{"../testdata/invalid-v2-missing-file"},
|
|
|
|
want: []*plugins.Plugin{},
|
|
|
|
pluginErrors: map[string]*plugins.Error{
|
2022-08-22 11:11:45 -05:00
|
|
|
"test-datasource": {
|
|
|
|
PluginID: "test-datasource",
|
2022-07-15 10:42:20 -05:00
|
|
|
ErrorCode: "signatureModified",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name: "Load a plugin with file which is missing from the manifest",
|
2023-06-08 05:21:19 -05:00
|
|
|
class: plugins.ClassExternal,
|
2022-09-14 08:35:35 -05:00
|
|
|
cfg: &config.Cfg{
|
2022-08-22 11:11:45 -05:00
|
|
|
PluginsAllowUnsigned: []string{"test-datasource"},
|
2022-07-15 10:42:20 -05:00
|
|
|
},
|
|
|
|
pluginPaths: []string{"../testdata/invalid-v2-extra-file"},
|
|
|
|
want: []*plugins.Plugin{},
|
|
|
|
pluginErrors: map[string]*plugins.Error{
|
2022-08-22 11:11:45 -05:00
|
|
|
"test-datasource": {
|
|
|
|
PluginID: "test-datasource",
|
2022-07-15 10:42:20 -05:00
|
|
|
ErrorCode: "signatureModified",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
2022-01-14 06:30:39 -06:00
|
|
|
{
|
|
|
|
name: "Load an app with includes",
|
2023-06-08 05:21:19 -05:00
|
|
|
class: plugins.ClassExternal,
|
2022-09-14 08:35:35 -05:00
|
|
|
cfg: &config.Cfg{
|
2022-01-14 06:30:39 -06:00
|
|
|
PluginsAllowUnsigned: []string{"test-app"},
|
|
|
|
},
|
|
|
|
pluginPaths: []string{"../testdata/test-app-with-includes"},
|
|
|
|
want: []*plugins.Plugin{
|
|
|
|
{JSONData: plugins.JSONData{
|
|
|
|
ID: "test-app",
|
2023-06-08 05:21:19 -05:00
|
|
|
Type: plugins.TypeApp,
|
2022-01-14 06:30:39 -06:00
|
|
|
Name: "Test App",
|
|
|
|
Info: plugins.Info{
|
|
|
|
Author: plugins.InfoLink{
|
|
|
|
Name: "Test Inc.",
|
|
|
|
URL: "http://test.com",
|
|
|
|
},
|
|
|
|
Description: "Official Grafana Test App & Dashboard bundle",
|
|
|
|
Version: "1.0.0",
|
|
|
|
Links: []plugins.InfoLink{
|
|
|
|
{Name: "Project site", URL: "http://project.com"},
|
|
|
|
{Name: "License & Terms", URL: "http://license.com"},
|
|
|
|
},
|
|
|
|
Logos: plugins.Logos{
|
|
|
|
Small: "public/img/icn-app.svg",
|
|
|
|
Large: "public/img/icn-app.svg",
|
|
|
|
},
|
|
|
|
Updated: "2015-02-10",
|
|
|
|
},
|
|
|
|
Dependencies: plugins.Dependencies{
|
|
|
|
GrafanaDependency: ">=8.0.0",
|
|
|
|
GrafanaVersion: "*",
|
|
|
|
Plugins: []plugins.Dependency{},
|
|
|
|
},
|
|
|
|
Includes: []*plugins.Includes{
|
2023-06-08 05:21:19 -05:00
|
|
|
{Name: "Nginx Memory", Path: "dashboards/memory.json", Type: "dashboard", Role: org.RoleViewer, Slug: "nginx-memory"},
|
|
|
|
{Name: "Root Page (react)", Type: "page", Role: org.RoleViewer, Path: "/a/my-simple-app", DefaultNav: true, AddToNav: true, Slug: "root-page-react"},
|
2022-01-14 06:30:39 -06:00
|
|
|
},
|
|
|
|
Backend: false,
|
|
|
|
},
|
|
|
|
DefaultNavURL: "/plugins/test-app/page/root-page-react",
|
2023-04-27 03:26:15 -05:00
|
|
|
FS: mustNewStaticFSForTests(t, filepath.Join(parentDir, "testdata/test-app-with-includes")),
|
2023-06-08 05:21:19 -05:00
|
|
|
Class: plugins.ClassExternal,
|
|
|
|
Signature: plugins.SignatureStatusUnsigned,
|
2023-04-27 03:26:15 -05:00
|
|
|
Module: "plugins/test-app/module",
|
|
|
|
BaseURL: "public/plugins/test-app",
|
2022-01-14 06:30:39 -06:00
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
2021-11-01 04:53:33 -05:00
|
|
|
}
|
|
|
|
for _, tt := range tests {
|
2022-09-23 07:27:01 -05:00
|
|
|
reg := fakes.NewFakePluginRegistry()
|
|
|
|
procPrvdr := fakes.NewFakeBackendProcessProvider()
|
|
|
|
procMgr := fakes.NewFakeProcessManager()
|
Plugins: Angular detector: Remote patterns fetching (#69843)
* Plugins: Angular detector: Remote patterns fetching
* Renamed PatternType to GCOMPatternType
* Renamed files
* Renamed more files
* Moved files again
* Add type checks, unexport GCOM structs
* Cache failures, update log messages, fix GCOM URL
* Fail silently for unknown pattern types, update docstrings
* Fix tests
* Rename gcomPattern.Value to gcomPattern.Pattern
* Refactoring
* Add FlagPluginsRemoteAngularDetectionPatterns feature flag
* Fix tests
* Re-generate feature flags
* Add TestProvideInspector, renamed TestDefaultStaticDetectorsInspector
* Add TestProvideInspector
* Add TestContainsBytesDetector and TestRegexDetector
* Renamed getter to provider
* More tests
* TestStaticDetectorsProvider, TestSequenceDetectorsProvider
* GCOM tests
* Lint
* Made detector.detect unexported, updated docstrings
* Allow changing grafana.com URL
* Fix API path, add more logs
* Update tryUpdateRemoteDetectors docstring
* Use angulardetector http client
* Return false, nil if module.js does not exist
* Chore: Split angualrdetector into angularinspector and angulardetector packages
Moved files around, changed references and fixed tests:
- Split the old angulardetector package into angular/angulardetector and angular/angularinspector
- angulardetector provides the detection structs/interfaces (Detector, DetectorsProvider...)
- angularinspector provides the actual angular detection service used directly in pluginsintegration
- Exported most of the stuff that was private and now put into angulardetector, as it is not required by angularinspector
* Renamed detector.go -> angulardetector.go and inspector.go -> angularinspector.go
Forgot to rename those two files to match the package's names
* Renamed angularinspector.ProvideInspector to angularinspector.ProvideService
* Renamed "harcoded" to "static" and "remote" to "dynamic"
from PR review, matches the same naming schema used for signing keys fetching
* Fix merge conflict on updated angular patterns
* Removed GCOM cache
* Renamed Detect to DetectAngular and Detector to AngularDetector
* Fix call to NewGCOMDetectorsProvider in newDynamicInspector
* Removed unused test function newError500GCOMScenario
* Added angularinspector service definition in pluginsintegration
* Moved dynamic inspector into pluginsintegration
* Move gcom angulardetectorsprovider into pluginsintegration
* Log errUnknownPatternType at debug level
* re-generate feature flags
* fix error log
2023-06-26 08:33:21 -05:00
|
|
|
l := newLoader(t, tt.cfg, func(l *Loader) {
|
2022-09-23 07:27:01 -05:00
|
|
|
l.pluginRegistry = reg
|
|
|
|
l.processManager = procMgr
|
|
|
|
l.pluginInitializer = initializer.New(tt.cfg, procPrvdr, &fakes.FakeLicensingService{})
|
|
|
|
})
|
|
|
|
|
2021-11-01 04:53:33 -05:00
|
|
|
t.Run(tt.name, func(t *testing.T) {
|
2023-03-20 08:35:49 -05:00
|
|
|
got, err := l.Load(context.Background(), sources.NewLocalSource(tt.class, tt.pluginPaths))
|
2021-11-01 04:53:33 -05:00
|
|
|
require.NoError(t, err)
|
2023-03-07 09:47:02 -06:00
|
|
|
if !cmp.Equal(got, tt.want, compareOpts...) {
|
|
|
|
t.Fatalf("Result mismatch (-want +got):\n%s", cmp.Diff(got, tt.want, compareOpts...))
|
2021-11-01 04:53:33 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
pluginErrs := l.PluginErrors()
|
2022-09-23 07:27:01 -05:00
|
|
|
require.Equal(t, len(tt.pluginErrors), len(pluginErrs))
|
2021-11-01 04:53:33 -05:00
|
|
|
for _, pluginErr := range pluginErrs {
|
2022-09-23 07:27:01 -05:00
|
|
|
require.Equal(t, tt.pluginErrors[pluginErr.PluginID], pluginErr)
|
2021-11-01 04:53:33 -05:00
|
|
|
}
|
2022-09-23 07:27:01 -05:00
|
|
|
|
2023-04-20 04:52:59 -05:00
|
|
|
verifyState(t, tt.want, reg, procPrvdr, procMgr)
|
2021-11-01 04:53:33 -05:00
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-04-04 10:01:49 -05:00
|
|
|
func TestLoader_Load_CustomSource(t *testing.T) {
|
|
|
|
t.Run("Load a plugin", func(t *testing.T) {
|
|
|
|
parentDir, err := filepath.Abs("../")
|
|
|
|
if err != nil {
|
|
|
|
t.Errorf("could not construct absolute path of current dir")
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
cfg := &config.Cfg{
|
|
|
|
PluginsCDNURLTemplate: "https://cdn.example.com",
|
|
|
|
PluginSettings: setting.PluginSettings{
|
|
|
|
"grafana-worldmap-panel": {"cdn": "true"},
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
pluginPaths := []string{"../testdata/cdn"}
|
|
|
|
expected := []*plugins.Plugin{{
|
|
|
|
JSONData: plugins.JSONData{
|
|
|
|
ID: "grafana-worldmap-panel",
|
2023-06-08 05:21:19 -05:00
|
|
|
Type: plugins.TypePanel,
|
2023-04-04 10:01:49 -05:00
|
|
|
Name: "Worldmap Panel",
|
|
|
|
Info: plugins.Info{
|
|
|
|
Version: "0.3.3",
|
|
|
|
Links: []plugins.InfoLink{
|
|
|
|
{Name: "Project site", URL: "https://github.com/grafana/worldmap-panel"},
|
|
|
|
{Name: "MIT License", URL: "https://github.com/grafana/worldmap-panel/blob/master/LICENSE"},
|
|
|
|
},
|
|
|
|
Logos: plugins.Logos{
|
|
|
|
// Path substitution
|
|
|
|
Small: "https://cdn.example.com/grafana-worldmap-panel/0.3.3/public/plugins/grafana-worldmap-panel/images/worldmap_logo.svg",
|
|
|
|
Large: "https://cdn.example.com/grafana-worldmap-panel/0.3.3/public/plugins/grafana-worldmap-panel/images/worldmap_logo.svg",
|
|
|
|
},
|
|
|
|
Screenshots: []plugins.Screenshots{
|
|
|
|
{
|
|
|
|
Name: "World",
|
|
|
|
Path: "https://cdn.example.com/grafana-worldmap-panel/0.3.3/public/plugins/grafana-worldmap-panel/images/worldmap-world.png",
|
|
|
|
},
|
|
|
|
{
|
|
|
|
Name: "USA",
|
|
|
|
Path: "https://cdn.example.com/grafana-worldmap-panel/0.3.3/public/plugins/grafana-worldmap-panel/images/worldmap-usa.png",
|
|
|
|
},
|
|
|
|
{
|
|
|
|
Name: "Light Theme",
|
|
|
|
Path: "https://cdn.example.com/grafana-worldmap-panel/0.3.3/public/plugins/grafana-worldmap-panel/images/worldmap-light-theme.png",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
Dependencies: plugins.Dependencies{
|
|
|
|
GrafanaVersion: "3.x.x",
|
|
|
|
Plugins: []plugins.Dependency{},
|
|
|
|
},
|
|
|
|
},
|
2023-04-27 03:26:15 -05:00
|
|
|
FS: mustNewStaticFSForTests(t, filepath.Join(parentDir, "testdata/cdn/plugin")),
|
2023-06-08 05:21:19 -05:00
|
|
|
Class: plugins.ClassBundled,
|
|
|
|
Signature: plugins.SignatureStatusValid,
|
2023-04-04 10:01:49 -05:00
|
|
|
BaseURL: "plugin-cdn/grafana-worldmap-panel/0.3.3/public/plugins/grafana-worldmap-panel",
|
|
|
|
Module: "plugin-cdn/grafana-worldmap-panel/0.3.3/public/plugins/grafana-worldmap-panel/module",
|
|
|
|
}}
|
|
|
|
|
Plugins: Angular detector: Remote patterns fetching (#69843)
* Plugins: Angular detector: Remote patterns fetching
* Renamed PatternType to GCOMPatternType
* Renamed files
* Renamed more files
* Moved files again
* Add type checks, unexport GCOM structs
* Cache failures, update log messages, fix GCOM URL
* Fail silently for unknown pattern types, update docstrings
* Fix tests
* Rename gcomPattern.Value to gcomPattern.Pattern
* Refactoring
* Add FlagPluginsRemoteAngularDetectionPatterns feature flag
* Fix tests
* Re-generate feature flags
* Add TestProvideInspector, renamed TestDefaultStaticDetectorsInspector
* Add TestProvideInspector
* Add TestContainsBytesDetector and TestRegexDetector
* Renamed getter to provider
* More tests
* TestStaticDetectorsProvider, TestSequenceDetectorsProvider
* GCOM tests
* Lint
* Made detector.detect unexported, updated docstrings
* Allow changing grafana.com URL
* Fix API path, add more logs
* Update tryUpdateRemoteDetectors docstring
* Use angulardetector http client
* Return false, nil if module.js does not exist
* Chore: Split angualrdetector into angularinspector and angulardetector packages
Moved files around, changed references and fixed tests:
- Split the old angulardetector package into angular/angulardetector and angular/angularinspector
- angulardetector provides the detection structs/interfaces (Detector, DetectorsProvider...)
- angularinspector provides the actual angular detection service used directly in pluginsintegration
- Exported most of the stuff that was private and now put into angulardetector, as it is not required by angularinspector
* Renamed detector.go -> angulardetector.go and inspector.go -> angularinspector.go
Forgot to rename those two files to match the package's names
* Renamed angularinspector.ProvideInspector to angularinspector.ProvideService
* Renamed "harcoded" to "static" and "remote" to "dynamic"
from PR review, matches the same naming schema used for signing keys fetching
* Fix merge conflict on updated angular patterns
* Removed GCOM cache
* Renamed Detect to DetectAngular and Detector to AngularDetector
* Fix call to NewGCOMDetectorsProvider in newDynamicInspector
* Removed unused test function newError500GCOMScenario
* Added angularinspector service definition in pluginsintegration
* Moved dynamic inspector into pluginsintegration
* Move gcom angulardetectorsprovider into pluginsintegration
* Log errUnknownPatternType at debug level
* re-generate feature flags
* fix error log
2023-06-26 08:33:21 -05:00
|
|
|
l := newLoader(t, cfg)
|
2023-04-04 10:01:49 -05:00
|
|
|
got, err := l.Load(context.Background(), &fakes.FakePluginSource{
|
|
|
|
PluginClassFunc: func(ctx context.Context) plugins.Class {
|
2023-06-08 05:21:19 -05:00
|
|
|
return plugins.ClassBundled
|
2023-04-04 10:01:49 -05:00
|
|
|
},
|
|
|
|
PluginURIsFunc: func(ctx context.Context) []string {
|
|
|
|
return pluginPaths
|
|
|
|
},
|
|
|
|
DefaultSignatureFunc: func(ctx context.Context) (plugins.Signature, bool) {
|
|
|
|
return plugins.Signature{
|
2023-06-08 05:21:19 -05:00
|
|
|
Status: plugins.SignatureStatusValid,
|
2023-04-04 10:01:49 -05:00
|
|
|
}, true
|
|
|
|
},
|
|
|
|
})
|
|
|
|
|
|
|
|
require.NoError(t, err)
|
|
|
|
if !cmp.Equal(got, expected, compareOpts...) {
|
|
|
|
t.Fatalf("Result mismatch (-want +got):\n%s", cmp.Diff(got, expected, compareOpts...))
|
|
|
|
}
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2021-11-01 04:53:33 -05:00
|
|
|
func TestLoader_Load_MultiplePlugins(t *testing.T) {
|
|
|
|
parentDir, err := filepath.Abs("../")
|
|
|
|
if err != nil {
|
|
|
|
t.Errorf("could not construct absolute path of current dir")
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
t.Run("Load multiple", func(t *testing.T) {
|
|
|
|
tests := []struct {
|
|
|
|
name string
|
2022-09-14 08:35:35 -05:00
|
|
|
cfg *config.Cfg
|
2021-11-01 04:53:33 -05:00
|
|
|
pluginPaths []string
|
|
|
|
existingPlugins map[string]struct{}
|
|
|
|
want []*plugins.Plugin
|
|
|
|
pluginErrors map[string]*plugins.Error
|
|
|
|
}{
|
|
|
|
{
|
2023-07-28 08:18:25 -05:00
|
|
|
name: "Load multiple plugins (broken, valid, unsigned)",
|
|
|
|
cfg: &config.Cfg{
|
|
|
|
GrafanaAppURL: "http://localhost:3000",
|
|
|
|
},
|
2021-11-01 04:53:33 -05:00
|
|
|
pluginPaths: []string{
|
|
|
|
"../testdata/invalid-plugin-json", // test-app
|
|
|
|
"../testdata/valid-v2-pvt-signature", // test
|
|
|
|
"../testdata/unsigned-panel", // test-panel
|
|
|
|
},
|
|
|
|
want: []*plugins.Plugin{
|
|
|
|
{
|
|
|
|
JSONData: plugins.JSONData{
|
2022-08-22 11:11:45 -05:00
|
|
|
ID: "test-datasource",
|
2023-06-08 05:21:19 -05:00
|
|
|
Type: plugins.TypeDataSource,
|
2021-11-01 04:53:33 -05:00
|
|
|
Name: "Test",
|
|
|
|
Info: plugins.Info{
|
|
|
|
Author: plugins.InfoLink{
|
|
|
|
Name: "Will Browne",
|
|
|
|
URL: "https://willbrowne.com",
|
|
|
|
},
|
|
|
|
Logos: plugins.Logos{
|
|
|
|
Small: "public/img/icn-datasource.svg",
|
|
|
|
Large: "public/img/icn-datasource.svg",
|
|
|
|
},
|
|
|
|
Description: "Test",
|
|
|
|
Version: "1.0.0",
|
|
|
|
},
|
|
|
|
Dependencies: plugins.Dependencies{
|
|
|
|
GrafanaVersion: "*",
|
|
|
|
Plugins: []plugins.Dependency{},
|
|
|
|
},
|
|
|
|
Backend: true,
|
|
|
|
Executable: "test",
|
2023-06-08 05:21:19 -05:00
|
|
|
State: plugins.ReleaseStateAlpha,
|
2021-11-01 04:53:33 -05:00
|
|
|
},
|
2023-06-08 05:21:19 -05:00
|
|
|
Class: plugins.ClassExternal,
|
2023-04-27 03:26:15 -05:00
|
|
|
Module: "plugins/test-datasource/module",
|
|
|
|
BaseURL: "public/plugins/test-datasource",
|
|
|
|
FS: mustNewStaticFSForTests(t, filepath.Join(parentDir, "testdata/valid-v2-pvt-signature/plugin")),
|
2021-11-01 04:53:33 -05:00
|
|
|
Signature: "valid",
|
2023-06-08 05:21:19 -05:00
|
|
|
SignatureType: plugins.SignatureTypePrivate,
|
2021-11-01 04:53:33 -05:00
|
|
|
SignatureOrg: "Will Browne",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
pluginErrors: map[string]*plugins.Error{
|
2022-07-04 06:03:50 -05:00
|
|
|
"test-panel": {
|
|
|
|
PluginID: "test-panel",
|
2021-11-01 04:53:33 -05:00
|
|
|
ErrorCode: "signatureMissing",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, tt := range tests {
|
2022-09-23 07:27:01 -05:00
|
|
|
reg := fakes.NewFakePluginRegistry()
|
|
|
|
procPrvdr := fakes.NewFakeBackendProcessProvider()
|
|
|
|
procMgr := fakes.NewFakeProcessManager()
|
Plugins: Angular detector: Remote patterns fetching (#69843)
* Plugins: Angular detector: Remote patterns fetching
* Renamed PatternType to GCOMPatternType
* Renamed files
* Renamed more files
* Moved files again
* Add type checks, unexport GCOM structs
* Cache failures, update log messages, fix GCOM URL
* Fail silently for unknown pattern types, update docstrings
* Fix tests
* Rename gcomPattern.Value to gcomPattern.Pattern
* Refactoring
* Add FlagPluginsRemoteAngularDetectionPatterns feature flag
* Fix tests
* Re-generate feature flags
* Add TestProvideInspector, renamed TestDefaultStaticDetectorsInspector
* Add TestProvideInspector
* Add TestContainsBytesDetector and TestRegexDetector
* Renamed getter to provider
* More tests
* TestStaticDetectorsProvider, TestSequenceDetectorsProvider
* GCOM tests
* Lint
* Made detector.detect unexported, updated docstrings
* Allow changing grafana.com URL
* Fix API path, add more logs
* Update tryUpdateRemoteDetectors docstring
* Use angulardetector http client
* Return false, nil if module.js does not exist
* Chore: Split angualrdetector into angularinspector and angulardetector packages
Moved files around, changed references and fixed tests:
- Split the old angulardetector package into angular/angulardetector and angular/angularinspector
- angulardetector provides the detection structs/interfaces (Detector, DetectorsProvider...)
- angularinspector provides the actual angular detection service used directly in pluginsintegration
- Exported most of the stuff that was private and now put into angulardetector, as it is not required by angularinspector
* Renamed detector.go -> angulardetector.go and inspector.go -> angularinspector.go
Forgot to rename those two files to match the package's names
* Renamed angularinspector.ProvideInspector to angularinspector.ProvideService
* Renamed "harcoded" to "static" and "remote" to "dynamic"
from PR review, matches the same naming schema used for signing keys fetching
* Fix merge conflict on updated angular patterns
* Removed GCOM cache
* Renamed Detect to DetectAngular and Detector to AngularDetector
* Fix call to NewGCOMDetectorsProvider in newDynamicInspector
* Removed unused test function newError500GCOMScenario
* Added angularinspector service definition in pluginsintegration
* Moved dynamic inspector into pluginsintegration
* Move gcom angulardetectorsprovider into pluginsintegration
* Log errUnknownPatternType at debug level
* re-generate feature flags
* fix error log
2023-06-26 08:33:21 -05:00
|
|
|
l := newLoader(t, tt.cfg, func(l *Loader) {
|
2022-09-23 07:27:01 -05:00
|
|
|
l.pluginRegistry = reg
|
|
|
|
l.processManager = procMgr
|
|
|
|
l.pluginInitializer = initializer.New(tt.cfg, procPrvdr, fakes.NewFakeLicensingService())
|
|
|
|
})
|
2021-11-01 04:53:33 -05:00
|
|
|
t.Run(tt.name, func(t *testing.T) {
|
2023-03-20 08:35:49 -05:00
|
|
|
got, err := l.Load(context.Background(), &fakes.FakePluginSource{
|
|
|
|
PluginClassFunc: func(ctx context.Context) plugins.Class {
|
2023-06-08 05:21:19 -05:00
|
|
|
return plugins.ClassExternal
|
2023-03-20 08:35:49 -05:00
|
|
|
},
|
|
|
|
PluginURIsFunc: func(ctx context.Context) []string {
|
|
|
|
return tt.pluginPaths
|
|
|
|
},
|
|
|
|
})
|
2021-11-01 04:53:33 -05:00
|
|
|
require.NoError(t, err)
|
|
|
|
sort.SliceStable(got, func(i, j int) bool {
|
|
|
|
return got[i].ID < got[j].ID
|
|
|
|
})
|
2023-03-07 09:47:02 -06:00
|
|
|
if !cmp.Equal(got, tt.want, compareOpts...) {
|
|
|
|
t.Fatalf("Result mismatch (-want +got):\n%s", cmp.Diff(got, tt.want, compareOpts...))
|
2021-11-01 04:53:33 -05:00
|
|
|
}
|
2022-07-04 06:03:50 -05:00
|
|
|
pluginErrs := l.PluginErrors()
|
|
|
|
require.Equal(t, len(tt.pluginErrors), len(pluginErrs))
|
|
|
|
for _, pluginErr := range pluginErrs {
|
|
|
|
require.Equal(t, tt.pluginErrors[pluginErr.PluginID], pluginErr)
|
|
|
|
}
|
2023-04-20 04:52:59 -05:00
|
|
|
verifyState(t, tt.want, reg, procPrvdr, procMgr)
|
2021-11-01 04:53:33 -05:00
|
|
|
})
|
|
|
|
}
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2022-11-07 04:30:45 -06:00
|
|
|
func TestLoader_Load_RBACReady(t *testing.T) {
|
|
|
|
pluginDir, err := filepath.Abs("../testdata/test-app-with-roles")
|
|
|
|
if err != nil {
|
|
|
|
t.Errorf("could not construct absolute path of current dir")
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
tests := []struct {
|
|
|
|
name string
|
|
|
|
cfg *config.Cfg
|
|
|
|
pluginPaths []string
|
|
|
|
existingPlugins map[string]struct{}
|
|
|
|
want []*plugins.Plugin
|
|
|
|
}{
|
|
|
|
{
|
2023-07-28 08:18:25 -05:00
|
|
|
name: "Load plugin defining one RBAC role",
|
|
|
|
cfg: &config.Cfg{
|
|
|
|
GrafanaAppURL: "http://localhost:3000",
|
|
|
|
},
|
2022-11-07 04:30:45 -06:00
|
|
|
pluginPaths: []string{"../testdata/test-app-with-roles"},
|
|
|
|
want: []*plugins.Plugin{
|
|
|
|
{
|
|
|
|
JSONData: plugins.JSONData{
|
|
|
|
ID: "test-app",
|
2023-06-08 05:21:19 -05:00
|
|
|
Type: plugins.TypeApp,
|
2022-11-07 04:30:45 -06:00
|
|
|
Name: "Test App",
|
|
|
|
Info: plugins.Info{
|
|
|
|
Author: plugins.InfoLink{
|
|
|
|
Name: "Test Inc.",
|
|
|
|
URL: "http://test.com",
|
|
|
|
},
|
|
|
|
Description: "Test App",
|
|
|
|
Version: "1.0.0",
|
|
|
|
Links: []plugins.InfoLink{},
|
|
|
|
Logos: plugins.Logos{
|
|
|
|
Small: "public/img/icn-app.svg",
|
|
|
|
Large: "public/img/icn-app.svg",
|
|
|
|
},
|
|
|
|
Updated: "2015-02-10",
|
|
|
|
},
|
|
|
|
Dependencies: plugins.Dependencies{
|
|
|
|
GrafanaVersion: "*",
|
|
|
|
GrafanaDependency: ">=8.0.0",
|
|
|
|
Plugins: []plugins.Dependency{},
|
|
|
|
},
|
|
|
|
Includes: []*plugins.Includes{},
|
|
|
|
Roles: []plugins.RoleRegistration{
|
|
|
|
{
|
|
|
|
Role: plugins.Role{
|
2022-11-15 02:51:40 -06:00
|
|
|
Name: "Reader",
|
2022-11-07 04:30:45 -06:00
|
|
|
Description: "View everything in the test-app plugin",
|
|
|
|
Permissions: []plugins.Permission{
|
|
|
|
{Action: "plugins.app:access", Scope: "plugins.app:id:test-app"},
|
|
|
|
{Action: "test-app.resource:read", Scope: "resources:*"},
|
|
|
|
{Action: "test-app.otherresource:toggle"},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
Grants: []string{"Admin"},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
Backend: false,
|
|
|
|
},
|
2023-04-27 03:26:15 -05:00
|
|
|
FS: mustNewStaticFSForTests(t, pluginDir),
|
2023-06-08 05:21:19 -05:00
|
|
|
Class: plugins.ClassExternal,
|
|
|
|
Signature: plugins.SignatureStatusValid,
|
|
|
|
SignatureType: plugins.SignatureTypePrivate,
|
2022-11-07 04:30:45 -06:00
|
|
|
SignatureOrg: "gabrielmabille",
|
|
|
|
Module: "plugins/test-app/module",
|
|
|
|
BaseURL: "public/plugins/test-app",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, tt := range tests {
|
|
|
|
reg := fakes.NewFakePluginRegistry()
|
|
|
|
procPrvdr := fakes.NewFakeBackendProcessProvider()
|
|
|
|
procMgr := fakes.NewFakeProcessManager()
|
Plugins: Angular detector: Remote patterns fetching (#69843)
* Plugins: Angular detector: Remote patterns fetching
* Renamed PatternType to GCOMPatternType
* Renamed files
* Renamed more files
* Moved files again
* Add type checks, unexport GCOM structs
* Cache failures, update log messages, fix GCOM URL
* Fail silently for unknown pattern types, update docstrings
* Fix tests
* Rename gcomPattern.Value to gcomPattern.Pattern
* Refactoring
* Add FlagPluginsRemoteAngularDetectionPatterns feature flag
* Fix tests
* Re-generate feature flags
* Add TestProvideInspector, renamed TestDefaultStaticDetectorsInspector
* Add TestProvideInspector
* Add TestContainsBytesDetector and TestRegexDetector
* Renamed getter to provider
* More tests
* TestStaticDetectorsProvider, TestSequenceDetectorsProvider
* GCOM tests
* Lint
* Made detector.detect unexported, updated docstrings
* Allow changing grafana.com URL
* Fix API path, add more logs
* Update tryUpdateRemoteDetectors docstring
* Use angulardetector http client
* Return false, nil if module.js does not exist
* Chore: Split angualrdetector into angularinspector and angulardetector packages
Moved files around, changed references and fixed tests:
- Split the old angulardetector package into angular/angulardetector and angular/angularinspector
- angulardetector provides the detection structs/interfaces (Detector, DetectorsProvider...)
- angularinspector provides the actual angular detection service used directly in pluginsintegration
- Exported most of the stuff that was private and now put into angulardetector, as it is not required by angularinspector
* Renamed detector.go -> angulardetector.go and inspector.go -> angularinspector.go
Forgot to rename those two files to match the package's names
* Renamed angularinspector.ProvideInspector to angularinspector.ProvideService
* Renamed "harcoded" to "static" and "remote" to "dynamic"
from PR review, matches the same naming schema used for signing keys fetching
* Fix merge conflict on updated angular patterns
* Removed GCOM cache
* Renamed Detect to DetectAngular and Detector to AngularDetector
* Fix call to NewGCOMDetectorsProvider in newDynamicInspector
* Removed unused test function newError500GCOMScenario
* Added angularinspector service definition in pluginsintegration
* Moved dynamic inspector into pluginsintegration
* Move gcom angulardetectorsprovider into pluginsintegration
* Log errUnknownPatternType at debug level
* re-generate feature flags
* fix error log
2023-06-26 08:33:21 -05:00
|
|
|
l := newLoader(t, tt.cfg, func(l *Loader) {
|
2022-11-07 04:30:45 -06:00
|
|
|
l.pluginRegistry = reg
|
|
|
|
l.processManager = procMgr
|
|
|
|
l.pluginInitializer = initializer.New(tt.cfg, procPrvdr, fakes.NewFakeLicensingService())
|
|
|
|
})
|
|
|
|
|
2023-03-20 08:35:49 -05:00
|
|
|
got, err := l.Load(context.Background(), &fakes.FakePluginSource{
|
|
|
|
PluginClassFunc: func(ctx context.Context) plugins.Class {
|
2023-06-08 05:21:19 -05:00
|
|
|
return plugins.ClassExternal
|
2023-03-20 08:35:49 -05:00
|
|
|
},
|
|
|
|
PluginURIsFunc: func(ctx context.Context) []string {
|
|
|
|
return tt.pluginPaths
|
|
|
|
},
|
|
|
|
})
|
2022-11-07 04:30:45 -06:00
|
|
|
require.NoError(t, err)
|
|
|
|
|
2023-03-07 09:47:02 -06:00
|
|
|
if !cmp.Equal(got, tt.want, compareOpts...) {
|
|
|
|
t.Fatalf("Result mismatch (-want +got):\n%s", cmp.Diff(got, tt.want, compareOpts...))
|
2022-11-07 04:30:45 -06:00
|
|
|
}
|
|
|
|
pluginErrs := l.PluginErrors()
|
|
|
|
require.Len(t, pluginErrs, 0)
|
|
|
|
|
2023-04-20 04:52:59 -05:00
|
|
|
verifyState(t, tt.want, reg, procPrvdr, procMgr)
|
2022-11-07 04:30:45 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-09-23 07:27:01 -05:00
|
|
|
func TestLoader_Load_Signature_RootURL(t *testing.T) {
|
2021-11-01 04:53:33 -05:00
|
|
|
const defaultAppURL = "http://localhost:3000/grafana"
|
|
|
|
|
|
|
|
parentDir, err := filepath.Abs("../")
|
|
|
|
if err != nil {
|
|
|
|
t.Errorf("could not construct absolute path of current dir")
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
t.Run("Private signature verification ignores trailing slash in root URL", func(t *testing.T) {
|
|
|
|
paths := []string{"../testdata/valid-v2-pvt-signature-root-url-uri"}
|
|
|
|
|
|
|
|
expected := []*plugins.Plugin{
|
|
|
|
{
|
|
|
|
JSONData: plugins.JSONData{
|
2022-08-22 11:11:45 -05:00
|
|
|
ID: "test-datasource",
|
2023-06-08 05:21:19 -05:00
|
|
|
Type: plugins.TypeDataSource,
|
2021-11-01 04:53:33 -05:00
|
|
|
Name: "Test",
|
|
|
|
Info: plugins.Info{
|
|
|
|
Author: plugins.InfoLink{Name: "Will Browne", URL: "https://willbrowne.com"},
|
|
|
|
Description: "Test",
|
|
|
|
Logos: plugins.Logos{
|
|
|
|
Small: "public/img/icn-datasource.svg",
|
|
|
|
Large: "public/img/icn-datasource.svg",
|
|
|
|
},
|
|
|
|
Version: "1.0.0",
|
|
|
|
},
|
2023-06-08 05:21:19 -05:00
|
|
|
State: plugins.ReleaseStateAlpha,
|
2021-11-01 04:53:33 -05:00
|
|
|
Dependencies: plugins.Dependencies{GrafanaVersion: "*", Plugins: []plugins.Dependency{}},
|
|
|
|
Backend: true,
|
|
|
|
Executable: "test",
|
|
|
|
},
|
2023-04-27 03:26:15 -05:00
|
|
|
FS: mustNewStaticFSForTests(t, filepath.Join(parentDir, "/testdata/valid-v2-pvt-signature-root-url-uri/plugin")),
|
2023-06-08 05:21:19 -05:00
|
|
|
Class: plugins.ClassExternal,
|
|
|
|
Signature: plugins.SignatureStatusValid,
|
|
|
|
SignatureType: plugins.SignatureTypePrivate,
|
2021-11-01 04:53:33 -05:00
|
|
|
SignatureOrg: "Will Browne",
|
2022-08-22 11:11:45 -05:00
|
|
|
Module: "plugins/test-datasource/module",
|
|
|
|
BaseURL: "public/plugins/test-datasource",
|
2021-11-01 04:53:33 -05:00
|
|
|
},
|
|
|
|
}
|
|
|
|
|
2022-09-23 07:27:01 -05:00
|
|
|
reg := fakes.NewFakePluginRegistry()
|
|
|
|
procPrvdr := fakes.NewFakeBackendProcessProvider()
|
|
|
|
procMgr := fakes.NewFakeProcessManager()
|
2023-07-28 08:18:25 -05:00
|
|
|
l := newLoader(t, &config.Cfg{GrafanaAppURL: defaultAppURL}, func(l *Loader) {
|
2022-09-23 07:27:01 -05:00
|
|
|
l.pluginRegistry = reg
|
|
|
|
l.processManager = procMgr
|
|
|
|
l.pluginInitializer = initializer.New(&config.Cfg{}, procPrvdr, fakes.NewFakeLicensingService())
|
|
|
|
})
|
2023-03-20 08:35:49 -05:00
|
|
|
got, err := l.Load(context.Background(), &fakes.FakePluginSource{
|
|
|
|
PluginClassFunc: func(ctx context.Context) plugins.Class {
|
2023-06-08 05:21:19 -05:00
|
|
|
return plugins.ClassExternal
|
2023-03-20 08:35:49 -05:00
|
|
|
},
|
|
|
|
PluginURIsFunc: func(ctx context.Context) []string {
|
|
|
|
return paths
|
|
|
|
},
|
|
|
|
})
|
2022-09-23 07:27:01 -05:00
|
|
|
require.NoError(t, err)
|
2021-11-01 04:53:33 -05:00
|
|
|
|
2023-03-07 09:47:02 -06:00
|
|
|
if !cmp.Equal(got, expected, compareOpts...) {
|
|
|
|
t.Fatalf("Result mismatch (-want +got):\n%s", cmp.Diff(got, expected, compareOpts...))
|
2021-11-01 04:53:33 -05:00
|
|
|
}
|
2023-04-20 04:52:59 -05:00
|
|
|
verifyState(t, expected, reg, procPrvdr, procMgr)
|
2021-11-01 04:53:33 -05:00
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestLoader_Load_DuplicatePlugins(t *testing.T) {
|
|
|
|
t.Run("Load duplicate plugin folders", func(t *testing.T) {
|
|
|
|
pluginDir, err := filepath.Abs("../testdata/test-app")
|
|
|
|
if err != nil {
|
|
|
|
t.Errorf("could not construct absolute path of plugin dir")
|
|
|
|
return
|
|
|
|
}
|
|
|
|
expected := []*plugins.Plugin{
|
|
|
|
{
|
|
|
|
JSONData: plugins.JSONData{
|
|
|
|
ID: "test-app",
|
2023-06-08 05:21:19 -05:00
|
|
|
Type: plugins.TypeApp,
|
2021-11-01 04:53:33 -05:00
|
|
|
Name: "Test App",
|
|
|
|
Info: plugins.Info{
|
|
|
|
Author: plugins.InfoLink{
|
|
|
|
Name: "Test Inc.",
|
|
|
|
URL: "http://test.com",
|
|
|
|
},
|
|
|
|
Description: "Official Grafana Test App & Dashboard bundle",
|
|
|
|
Version: "1.0.0",
|
|
|
|
Links: []plugins.InfoLink{
|
|
|
|
{Name: "Project site", URL: "http://project.com"},
|
|
|
|
{Name: "License & Terms", URL: "http://license.com"},
|
|
|
|
},
|
|
|
|
Logos: plugins.Logos{
|
|
|
|
Small: "public/plugins/test-app/img/logo_small.png",
|
|
|
|
Large: "public/plugins/test-app/img/logo_large.png",
|
|
|
|
},
|
|
|
|
Screenshots: []plugins.Screenshots{
|
|
|
|
{Path: "public/plugins/test-app/img/screenshot1.png", Name: "img1"},
|
|
|
|
{Path: "public/plugins/test-app/img/screenshot2.png", Name: "img2"},
|
|
|
|
},
|
|
|
|
Updated: "2015-02-10",
|
|
|
|
},
|
|
|
|
Dependencies: plugins.Dependencies{
|
|
|
|
GrafanaVersion: "3.x.x",
|
|
|
|
Plugins: []plugins.Dependency{
|
|
|
|
{Type: "datasource", ID: "graphite", Name: "Graphite", Version: "1.0.0"},
|
|
|
|
{Type: "panel", ID: "graph", Name: "Graph", Version: "1.0.0"},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
Includes: []*plugins.Includes{
|
2023-06-08 05:21:19 -05:00
|
|
|
{Name: "Nginx Connections", Path: "dashboards/connections.json", Type: "dashboard", Role: org.RoleViewer, Slug: "nginx-connections"},
|
|
|
|
{Name: "Nginx Memory", Path: "dashboards/memory.json", Type: "dashboard", Role: org.RoleViewer, Slug: "nginx-memory"},
|
|
|
|
{Name: "Nginx Panel", Type: "panel", Role: org.RoleViewer, Slug: "nginx-panel"},
|
|
|
|
{Name: "Nginx Datasource", Type: "datasource", Role: org.RoleViewer, Slug: "nginx-datasource"},
|
2021-11-01 04:53:33 -05:00
|
|
|
},
|
|
|
|
Backend: false,
|
|
|
|
},
|
2023-04-27 03:26:15 -05:00
|
|
|
FS: mustNewStaticFSForTests(t, pluginDir),
|
2023-06-08 05:21:19 -05:00
|
|
|
Class: plugins.ClassExternal,
|
|
|
|
Signature: plugins.SignatureStatusValid,
|
|
|
|
SignatureType: plugins.SignatureTypeGrafana,
|
2021-11-01 04:53:33 -05:00
|
|
|
SignatureOrg: "Grafana Labs",
|
|
|
|
Module: "plugins/test-app/module",
|
|
|
|
BaseURL: "public/plugins/test-app",
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
2022-09-23 07:27:01 -05:00
|
|
|
reg := fakes.NewFakePluginRegistry()
|
|
|
|
procPrvdr := fakes.NewFakeBackendProcessProvider()
|
|
|
|
procMgr := fakes.NewFakeProcessManager()
|
Plugins: Angular detector: Remote patterns fetching (#69843)
* Plugins: Angular detector: Remote patterns fetching
* Renamed PatternType to GCOMPatternType
* Renamed files
* Renamed more files
* Moved files again
* Add type checks, unexport GCOM structs
* Cache failures, update log messages, fix GCOM URL
* Fail silently for unknown pattern types, update docstrings
* Fix tests
* Rename gcomPattern.Value to gcomPattern.Pattern
* Refactoring
* Add FlagPluginsRemoteAngularDetectionPatterns feature flag
* Fix tests
* Re-generate feature flags
* Add TestProvideInspector, renamed TestDefaultStaticDetectorsInspector
* Add TestProvideInspector
* Add TestContainsBytesDetector and TestRegexDetector
* Renamed getter to provider
* More tests
* TestStaticDetectorsProvider, TestSequenceDetectorsProvider
* GCOM tests
* Lint
* Made detector.detect unexported, updated docstrings
* Allow changing grafana.com URL
* Fix API path, add more logs
* Update tryUpdateRemoteDetectors docstring
* Use angulardetector http client
* Return false, nil if module.js does not exist
* Chore: Split angualrdetector into angularinspector and angulardetector packages
Moved files around, changed references and fixed tests:
- Split the old angulardetector package into angular/angulardetector and angular/angularinspector
- angulardetector provides the detection structs/interfaces (Detector, DetectorsProvider...)
- angularinspector provides the actual angular detection service used directly in pluginsintegration
- Exported most of the stuff that was private and now put into angulardetector, as it is not required by angularinspector
* Renamed detector.go -> angulardetector.go and inspector.go -> angularinspector.go
Forgot to rename those two files to match the package's names
* Renamed angularinspector.ProvideInspector to angularinspector.ProvideService
* Renamed "harcoded" to "static" and "remote" to "dynamic"
from PR review, matches the same naming schema used for signing keys fetching
* Fix merge conflict on updated angular patterns
* Removed GCOM cache
* Renamed Detect to DetectAngular and Detector to AngularDetector
* Fix call to NewGCOMDetectorsProvider in newDynamicInspector
* Removed unused test function newError500GCOMScenario
* Added angularinspector service definition in pluginsintegration
* Moved dynamic inspector into pluginsintegration
* Move gcom angulardetectorsprovider into pluginsintegration
* Log errUnknownPatternType at debug level
* re-generate feature flags
* fix error log
2023-06-26 08:33:21 -05:00
|
|
|
l := newLoader(t, &config.Cfg{}, func(l *Loader) {
|
2022-09-23 07:27:01 -05:00
|
|
|
l.pluginRegistry = reg
|
|
|
|
l.processManager = procMgr
|
|
|
|
l.pluginInitializer = initializer.New(&config.Cfg{}, procPrvdr, fakes.NewFakeLicensingService())
|
|
|
|
})
|
2023-03-20 08:35:49 -05:00
|
|
|
got, err := l.Load(context.Background(), &fakes.FakePluginSource{
|
|
|
|
PluginClassFunc: func(ctx context.Context) plugins.Class {
|
2023-06-08 05:21:19 -05:00
|
|
|
return plugins.ClassExternal
|
2023-03-20 08:35:49 -05:00
|
|
|
},
|
|
|
|
PluginURIsFunc: func(ctx context.Context) []string {
|
|
|
|
return []string{pluginDir, pluginDir}
|
|
|
|
},
|
|
|
|
})
|
2022-09-23 07:27:01 -05:00
|
|
|
require.NoError(t, err)
|
2021-11-01 04:53:33 -05:00
|
|
|
|
2023-03-07 09:47:02 -06:00
|
|
|
if !cmp.Equal(got, expected, compareOpts...) {
|
|
|
|
t.Fatalf("Result mismatch (-want +got):\n%s", cmp.Diff(got, expected, compareOpts...))
|
2021-11-01 04:53:33 -05:00
|
|
|
}
|
2022-09-23 07:27:01 -05:00
|
|
|
|
2023-04-20 04:52:59 -05:00
|
|
|
verifyState(t, expected, reg, procPrvdr, procMgr)
|
2021-11-01 04:53:33 -05:00
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2023-04-12 04:34:16 -05:00
|
|
|
func TestLoader_Load_SkipUninitializedPlugins(t *testing.T) {
|
|
|
|
t.Run("Load duplicate plugin folders", func(t *testing.T) {
|
|
|
|
pluginDir1, err := filepath.Abs("../testdata/test-app")
|
|
|
|
if err != nil {
|
|
|
|
t.Errorf("could not construct absolute path of plugin dir")
|
|
|
|
return
|
|
|
|
}
|
|
|
|
pluginDir2, err := filepath.Abs("../testdata/valid-v2-signature")
|
|
|
|
if err != nil {
|
|
|
|
t.Errorf("could not construct absolute path of plugin dir")
|
|
|
|
return
|
|
|
|
}
|
|
|
|
expected := []*plugins.Plugin{
|
|
|
|
{
|
|
|
|
JSONData: plugins.JSONData{
|
|
|
|
ID: "test-app",
|
2023-06-08 05:21:19 -05:00
|
|
|
Type: plugins.TypeApp,
|
2023-04-12 04:34:16 -05:00
|
|
|
Name: "Test App",
|
|
|
|
Info: plugins.Info{
|
|
|
|
Author: plugins.InfoLink{
|
|
|
|
Name: "Test Inc.",
|
|
|
|
URL: "http://test.com",
|
|
|
|
},
|
|
|
|
Description: "Official Grafana Test App & Dashboard bundle",
|
|
|
|
Version: "1.0.0",
|
|
|
|
Links: []plugins.InfoLink{
|
|
|
|
{Name: "Project site", URL: "http://project.com"},
|
|
|
|
{Name: "License & Terms", URL: "http://license.com"},
|
|
|
|
},
|
|
|
|
Logos: plugins.Logos{
|
|
|
|
Small: "public/plugins/test-app/img/logo_small.png",
|
|
|
|
Large: "public/plugins/test-app/img/logo_large.png",
|
|
|
|
},
|
|
|
|
Screenshots: []plugins.Screenshots{
|
|
|
|
{Path: "public/plugins/test-app/img/screenshot1.png", Name: "img1"},
|
|
|
|
{Path: "public/plugins/test-app/img/screenshot2.png", Name: "img2"},
|
|
|
|
},
|
|
|
|
Updated: "2015-02-10",
|
|
|
|
},
|
|
|
|
Dependencies: plugins.Dependencies{
|
|
|
|
GrafanaVersion: "3.x.x",
|
|
|
|
Plugins: []plugins.Dependency{
|
|
|
|
{Type: "datasource", ID: "graphite", Name: "Graphite", Version: "1.0.0"},
|
|
|
|
{Type: "panel", ID: "graph", Name: "Graph", Version: "1.0.0"},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
Includes: []*plugins.Includes{
|
2023-06-08 05:21:19 -05:00
|
|
|
{Name: "Nginx Connections", Path: "dashboards/connections.json", Type: "dashboard", Role: org.RoleViewer, Slug: "nginx-connections"},
|
|
|
|
{Name: "Nginx Memory", Path: "dashboards/memory.json", Type: "dashboard", Role: org.RoleViewer, Slug: "nginx-memory"},
|
|
|
|
{Name: "Nginx Panel", Type: "panel", Role: org.RoleViewer, Slug: "nginx-panel"},
|
|
|
|
{Name: "Nginx Datasource", Type: "datasource", Role: org.RoleViewer, Slug: "nginx-datasource"},
|
2023-04-12 04:34:16 -05:00
|
|
|
},
|
|
|
|
Backend: false,
|
|
|
|
},
|
2023-04-27 03:26:15 -05:00
|
|
|
FS: mustNewStaticFSForTests(t, pluginDir1),
|
2023-06-08 05:21:19 -05:00
|
|
|
Class: plugins.ClassExternal,
|
|
|
|
Signature: plugins.SignatureStatusValid,
|
|
|
|
SignatureType: plugins.SignatureTypeGrafana,
|
2023-04-12 04:34:16 -05:00
|
|
|
SignatureOrg: "Grafana Labs",
|
|
|
|
Module: "plugins/test-app/module",
|
|
|
|
BaseURL: "public/plugins/test-app",
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
reg := fakes.NewFakePluginRegistry()
|
|
|
|
procPrvdr := fakes.NewFakeBackendProcessProvider()
|
|
|
|
// Cause an initialization error
|
|
|
|
procPrvdr.BackendFactoryFunc = func(ctx context.Context, p *plugins.Plugin) backendplugin.PluginFactoryFunc {
|
|
|
|
return func(pluginID string, _ log.Logger, _ []string) (backendplugin.Plugin, error) {
|
|
|
|
if pluginID == "test-datasource" {
|
2023-06-07 10:22:43 -05:00
|
|
|
return nil, errors.New("failed to initialize")
|
2023-04-12 04:34:16 -05:00
|
|
|
}
|
|
|
|
return &fakes.FakePluginClient{}, nil
|
|
|
|
}
|
|
|
|
}
|
|
|
|
procMgr := fakes.NewFakeProcessManager()
|
Plugins: Angular detector: Remote patterns fetching (#69843)
* Plugins: Angular detector: Remote patterns fetching
* Renamed PatternType to GCOMPatternType
* Renamed files
* Renamed more files
* Moved files again
* Add type checks, unexport GCOM structs
* Cache failures, update log messages, fix GCOM URL
* Fail silently for unknown pattern types, update docstrings
* Fix tests
* Rename gcomPattern.Value to gcomPattern.Pattern
* Refactoring
* Add FlagPluginsRemoteAngularDetectionPatterns feature flag
* Fix tests
* Re-generate feature flags
* Add TestProvideInspector, renamed TestDefaultStaticDetectorsInspector
* Add TestProvideInspector
* Add TestContainsBytesDetector and TestRegexDetector
* Renamed getter to provider
* More tests
* TestStaticDetectorsProvider, TestSequenceDetectorsProvider
* GCOM tests
* Lint
* Made detector.detect unexported, updated docstrings
* Allow changing grafana.com URL
* Fix API path, add more logs
* Update tryUpdateRemoteDetectors docstring
* Use angulardetector http client
* Return false, nil if module.js does not exist
* Chore: Split angualrdetector into angularinspector and angulardetector packages
Moved files around, changed references and fixed tests:
- Split the old angulardetector package into angular/angulardetector and angular/angularinspector
- angulardetector provides the detection structs/interfaces (Detector, DetectorsProvider...)
- angularinspector provides the actual angular detection service used directly in pluginsintegration
- Exported most of the stuff that was private and now put into angulardetector, as it is not required by angularinspector
* Renamed detector.go -> angulardetector.go and inspector.go -> angularinspector.go
Forgot to rename those two files to match the package's names
* Renamed angularinspector.ProvideInspector to angularinspector.ProvideService
* Renamed "harcoded" to "static" and "remote" to "dynamic"
from PR review, matches the same naming schema used for signing keys fetching
* Fix merge conflict on updated angular patterns
* Removed GCOM cache
* Renamed Detect to DetectAngular and Detector to AngularDetector
* Fix call to NewGCOMDetectorsProvider in newDynamicInspector
* Removed unused test function newError500GCOMScenario
* Added angularinspector service definition in pluginsintegration
* Moved dynamic inspector into pluginsintegration
* Move gcom angulardetectorsprovider into pluginsintegration
* Log errUnknownPatternType at debug level
* re-generate feature flags
* fix error log
2023-06-26 08:33:21 -05:00
|
|
|
l := newLoader(t, &config.Cfg{}, func(l *Loader) {
|
2023-04-12 04:34:16 -05:00
|
|
|
l.pluginRegistry = reg
|
|
|
|
l.processManager = procMgr
|
|
|
|
l.pluginInitializer = initializer.New(&config.Cfg{}, procPrvdr, fakes.NewFakeLicensingService())
|
|
|
|
})
|
|
|
|
got, err := l.Load(context.Background(), &fakes.FakePluginSource{
|
|
|
|
PluginClassFunc: func(ctx context.Context) plugins.Class {
|
2023-06-08 05:21:19 -05:00
|
|
|
return plugins.ClassExternal
|
2023-04-12 04:34:16 -05:00
|
|
|
},
|
|
|
|
PluginURIsFunc: func(ctx context.Context) []string {
|
|
|
|
return []string{pluginDir1, pluginDir2}
|
|
|
|
},
|
|
|
|
})
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
if !cmp.Equal(got, expected, compareOpts...) {
|
|
|
|
t.Fatalf("Result mismatch (-want +got):\n%s", cmp.Diff(got, expected, compareOpts...))
|
|
|
|
}
|
|
|
|
|
2023-04-20 04:52:59 -05:00
|
|
|
verifyState(t, expected, reg, procPrvdr, procMgr)
|
2023-04-12 04:34:16 -05:00
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2023-07-04 04:03:10 -05:00
|
|
|
func TestLoader_AngularClass(t *testing.T) {
|
|
|
|
for _, tc := range []struct {
|
|
|
|
name string
|
|
|
|
class plugins.Class
|
|
|
|
expAngularDetectionRun bool
|
|
|
|
}{
|
|
|
|
{
|
|
|
|
name: "core plugin should skip angular detection",
|
|
|
|
class: plugins.ClassCore,
|
|
|
|
expAngularDetectionRun: false,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name: "bundled plugin should skip angular detection",
|
|
|
|
class: plugins.ClassBundled,
|
|
|
|
expAngularDetectionRun: false,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name: "external plugin should run angular detection",
|
|
|
|
class: plugins.ClassExternal,
|
|
|
|
expAngularDetectionRun: true,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name: "other-class plugin should run angular detection",
|
|
|
|
class: "CDN", // (enterprise-only class)
|
|
|
|
expAngularDetectionRun: true,
|
|
|
|
},
|
|
|
|
} {
|
|
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
|
|
fakePluginSource := &fakes.FakePluginSource{
|
|
|
|
PluginClassFunc: func(ctx context.Context) plugins.Class {
|
|
|
|
return tc.class
|
|
|
|
},
|
|
|
|
PluginURIsFunc: func(ctx context.Context) []string {
|
|
|
|
return []string{"../testdata/valid-v2-signature"}
|
|
|
|
},
|
|
|
|
}
|
|
|
|
l := newLoader(t, &config.Cfg{AngularSupportEnabled: true}, func(l *Loader) {
|
|
|
|
// So if angularDetected = true, it means that the detection has run
|
|
|
|
l.angularInspector = angularinspector.AlwaysAngularFakeInspector
|
|
|
|
})
|
|
|
|
p, err := l.Load(context.Background(), fakePluginSource)
|
|
|
|
require.NoError(t, err)
|
|
|
|
require.Len(t, p, 1, "should load 1 plugin")
|
|
|
|
if tc.expAngularDetectionRun {
|
|
|
|
require.True(t, p[0].AngularDetected, "angular detection should run")
|
|
|
|
} else {
|
|
|
|
require.False(t, p[0].AngularDetected, "angular detection should not run")
|
|
|
|
}
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-06-07 04:08:01 -05:00
|
|
|
func TestLoader_Load_Angular(t *testing.T) {
|
|
|
|
fakePluginSource := &fakes.FakePluginSource{
|
|
|
|
PluginClassFunc: func(ctx context.Context) plugins.Class {
|
2023-06-08 05:21:19 -05:00
|
|
|
return plugins.ClassExternal
|
2023-06-07 04:08:01 -05:00
|
|
|
},
|
|
|
|
PluginURIsFunc: func(ctx context.Context) []string {
|
|
|
|
return []string{"../testdata/valid-v2-signature"}
|
|
|
|
},
|
|
|
|
}
|
|
|
|
for _, cfgTc := range []struct {
|
|
|
|
name string
|
|
|
|
cfg *config.Cfg
|
|
|
|
}{
|
|
|
|
{name: "angular support enabled", cfg: &config.Cfg{AngularSupportEnabled: true}},
|
|
|
|
{name: "angular support disabled", cfg: &config.Cfg{AngularSupportEnabled: false}},
|
|
|
|
} {
|
|
|
|
t.Run(cfgTc.name, func(t *testing.T) {
|
|
|
|
for _, tc := range []struct {
|
|
|
|
name string
|
Plugins: Angular detector: Remote patterns fetching (#69843)
* Plugins: Angular detector: Remote patterns fetching
* Renamed PatternType to GCOMPatternType
* Renamed files
* Renamed more files
* Moved files again
* Add type checks, unexport GCOM structs
* Cache failures, update log messages, fix GCOM URL
* Fail silently for unknown pattern types, update docstrings
* Fix tests
* Rename gcomPattern.Value to gcomPattern.Pattern
* Refactoring
* Add FlagPluginsRemoteAngularDetectionPatterns feature flag
* Fix tests
* Re-generate feature flags
* Add TestProvideInspector, renamed TestDefaultStaticDetectorsInspector
* Add TestProvideInspector
* Add TestContainsBytesDetector and TestRegexDetector
* Renamed getter to provider
* More tests
* TestStaticDetectorsProvider, TestSequenceDetectorsProvider
* GCOM tests
* Lint
* Made detector.detect unexported, updated docstrings
* Allow changing grafana.com URL
* Fix API path, add more logs
* Update tryUpdateRemoteDetectors docstring
* Use angulardetector http client
* Return false, nil if module.js does not exist
* Chore: Split angualrdetector into angularinspector and angulardetector packages
Moved files around, changed references and fixed tests:
- Split the old angulardetector package into angular/angulardetector and angular/angularinspector
- angulardetector provides the detection structs/interfaces (Detector, DetectorsProvider...)
- angularinspector provides the actual angular detection service used directly in pluginsintegration
- Exported most of the stuff that was private and now put into angulardetector, as it is not required by angularinspector
* Renamed detector.go -> angulardetector.go and inspector.go -> angularinspector.go
Forgot to rename those two files to match the package's names
* Renamed angularinspector.ProvideInspector to angularinspector.ProvideService
* Renamed "harcoded" to "static" and "remote" to "dynamic"
from PR review, matches the same naming schema used for signing keys fetching
* Fix merge conflict on updated angular patterns
* Removed GCOM cache
* Renamed Detect to DetectAngular and Detector to AngularDetector
* Fix call to NewGCOMDetectorsProvider in newDynamicInspector
* Removed unused test function newError500GCOMScenario
* Added angularinspector service definition in pluginsintegration
* Moved dynamic inspector into pluginsintegration
* Move gcom angulardetectorsprovider into pluginsintegration
* Log errUnknownPatternType at debug level
* re-generate feature flags
* fix error log
2023-06-26 08:33:21 -05:00
|
|
|
angularInspector angularinspector.Inspector
|
2023-06-07 04:08:01 -05:00
|
|
|
shouldLoad bool
|
|
|
|
}{
|
|
|
|
{
|
|
|
|
name: "angular plugin",
|
Plugins: Angular detector: Remote patterns fetching (#69843)
* Plugins: Angular detector: Remote patterns fetching
* Renamed PatternType to GCOMPatternType
* Renamed files
* Renamed more files
* Moved files again
* Add type checks, unexport GCOM structs
* Cache failures, update log messages, fix GCOM URL
* Fail silently for unknown pattern types, update docstrings
* Fix tests
* Rename gcomPattern.Value to gcomPattern.Pattern
* Refactoring
* Add FlagPluginsRemoteAngularDetectionPatterns feature flag
* Fix tests
* Re-generate feature flags
* Add TestProvideInspector, renamed TestDefaultStaticDetectorsInspector
* Add TestProvideInspector
* Add TestContainsBytesDetector and TestRegexDetector
* Renamed getter to provider
* More tests
* TestStaticDetectorsProvider, TestSequenceDetectorsProvider
* GCOM tests
* Lint
* Made detector.detect unexported, updated docstrings
* Allow changing grafana.com URL
* Fix API path, add more logs
* Update tryUpdateRemoteDetectors docstring
* Use angulardetector http client
* Return false, nil if module.js does not exist
* Chore: Split angualrdetector into angularinspector and angulardetector packages
Moved files around, changed references and fixed tests:
- Split the old angulardetector package into angular/angulardetector and angular/angularinspector
- angulardetector provides the detection structs/interfaces (Detector, DetectorsProvider...)
- angularinspector provides the actual angular detection service used directly in pluginsintegration
- Exported most of the stuff that was private and now put into angulardetector, as it is not required by angularinspector
* Renamed detector.go -> angulardetector.go and inspector.go -> angularinspector.go
Forgot to rename those two files to match the package's names
* Renamed angularinspector.ProvideInspector to angularinspector.ProvideService
* Renamed "harcoded" to "static" and "remote" to "dynamic"
from PR review, matches the same naming schema used for signing keys fetching
* Fix merge conflict on updated angular patterns
* Removed GCOM cache
* Renamed Detect to DetectAngular and Detector to AngularDetector
* Fix call to NewGCOMDetectorsProvider in newDynamicInspector
* Removed unused test function newError500GCOMScenario
* Added angularinspector service definition in pluginsintegration
* Moved dynamic inspector into pluginsintegration
* Move gcom angulardetectorsprovider into pluginsintegration
* Log errUnknownPatternType at debug level
* re-generate feature flags
* fix error log
2023-06-26 08:33:21 -05:00
|
|
|
angularInspector: angularinspector.AlwaysAngularFakeInspector,
|
2023-06-07 04:08:01 -05:00
|
|
|
// angular plugins should load only if allowed by the cfg
|
|
|
|
shouldLoad: cfgTc.cfg.AngularSupportEnabled,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name: "non angular plugin",
|
Plugins: Angular detector: Remote patterns fetching (#69843)
* Plugins: Angular detector: Remote patterns fetching
* Renamed PatternType to GCOMPatternType
* Renamed files
* Renamed more files
* Moved files again
* Add type checks, unexport GCOM structs
* Cache failures, update log messages, fix GCOM URL
* Fail silently for unknown pattern types, update docstrings
* Fix tests
* Rename gcomPattern.Value to gcomPattern.Pattern
* Refactoring
* Add FlagPluginsRemoteAngularDetectionPatterns feature flag
* Fix tests
* Re-generate feature flags
* Add TestProvideInspector, renamed TestDefaultStaticDetectorsInspector
* Add TestProvideInspector
* Add TestContainsBytesDetector and TestRegexDetector
* Renamed getter to provider
* More tests
* TestStaticDetectorsProvider, TestSequenceDetectorsProvider
* GCOM tests
* Lint
* Made detector.detect unexported, updated docstrings
* Allow changing grafana.com URL
* Fix API path, add more logs
* Update tryUpdateRemoteDetectors docstring
* Use angulardetector http client
* Return false, nil if module.js does not exist
* Chore: Split angualrdetector into angularinspector and angulardetector packages
Moved files around, changed references and fixed tests:
- Split the old angulardetector package into angular/angulardetector and angular/angularinspector
- angulardetector provides the detection structs/interfaces (Detector, DetectorsProvider...)
- angularinspector provides the actual angular detection service used directly in pluginsintegration
- Exported most of the stuff that was private and now put into angulardetector, as it is not required by angularinspector
* Renamed detector.go -> angulardetector.go and inspector.go -> angularinspector.go
Forgot to rename those two files to match the package's names
* Renamed angularinspector.ProvideInspector to angularinspector.ProvideService
* Renamed "harcoded" to "static" and "remote" to "dynamic"
from PR review, matches the same naming schema used for signing keys fetching
* Fix merge conflict on updated angular patterns
* Removed GCOM cache
* Renamed Detect to DetectAngular and Detector to AngularDetector
* Fix call to NewGCOMDetectorsProvider in newDynamicInspector
* Removed unused test function newError500GCOMScenario
* Added angularinspector service definition in pluginsintegration
* Moved dynamic inspector into pluginsintegration
* Move gcom angulardetectorsprovider into pluginsintegration
* Log errUnknownPatternType at debug level
* re-generate feature flags
* fix error log
2023-06-26 08:33:21 -05:00
|
|
|
angularInspector: angularinspector.NeverAngularFakeInspector,
|
2023-06-07 04:08:01 -05:00
|
|
|
// non-angular plugins should always load
|
|
|
|
shouldLoad: true,
|
|
|
|
},
|
|
|
|
} {
|
|
|
|
t.Run(tc.name, func(t *testing.T) {
|
Plugins: Angular detector: Remote patterns fetching (#69843)
* Plugins: Angular detector: Remote patterns fetching
* Renamed PatternType to GCOMPatternType
* Renamed files
* Renamed more files
* Moved files again
* Add type checks, unexport GCOM structs
* Cache failures, update log messages, fix GCOM URL
* Fail silently for unknown pattern types, update docstrings
* Fix tests
* Rename gcomPattern.Value to gcomPattern.Pattern
* Refactoring
* Add FlagPluginsRemoteAngularDetectionPatterns feature flag
* Fix tests
* Re-generate feature flags
* Add TestProvideInspector, renamed TestDefaultStaticDetectorsInspector
* Add TestProvideInspector
* Add TestContainsBytesDetector and TestRegexDetector
* Renamed getter to provider
* More tests
* TestStaticDetectorsProvider, TestSequenceDetectorsProvider
* GCOM tests
* Lint
* Made detector.detect unexported, updated docstrings
* Allow changing grafana.com URL
* Fix API path, add more logs
* Update tryUpdateRemoteDetectors docstring
* Use angulardetector http client
* Return false, nil if module.js does not exist
* Chore: Split angualrdetector into angularinspector and angulardetector packages
Moved files around, changed references and fixed tests:
- Split the old angulardetector package into angular/angulardetector and angular/angularinspector
- angulardetector provides the detection structs/interfaces (Detector, DetectorsProvider...)
- angularinspector provides the actual angular detection service used directly in pluginsintegration
- Exported most of the stuff that was private and now put into angulardetector, as it is not required by angularinspector
* Renamed detector.go -> angulardetector.go and inspector.go -> angularinspector.go
Forgot to rename those two files to match the package's names
* Renamed angularinspector.ProvideInspector to angularinspector.ProvideService
* Renamed "harcoded" to "static" and "remote" to "dynamic"
from PR review, matches the same naming schema used for signing keys fetching
* Fix merge conflict on updated angular patterns
* Removed GCOM cache
* Renamed Detect to DetectAngular and Detector to AngularDetector
* Fix call to NewGCOMDetectorsProvider in newDynamicInspector
* Removed unused test function newError500GCOMScenario
* Added angularinspector service definition in pluginsintegration
* Moved dynamic inspector into pluginsintegration
* Move gcom angulardetectorsprovider into pluginsintegration
* Log errUnknownPatternType at debug level
* re-generate feature flags
* fix error log
2023-06-26 08:33:21 -05:00
|
|
|
l := newLoader(t, cfgTc.cfg, func(l *Loader) {
|
2023-06-07 04:08:01 -05:00
|
|
|
l.angularInspector = tc.angularInspector
|
|
|
|
})
|
|
|
|
p, err := l.Load(context.Background(), fakePluginSource)
|
|
|
|
require.NoError(t, err)
|
|
|
|
if tc.shouldLoad {
|
|
|
|
require.Len(t, p, 1, "plugin should have been loaded")
|
|
|
|
} else {
|
|
|
|
require.Empty(t, p, "plugin shouldn't have been loaded")
|
|
|
|
}
|
|
|
|
})
|
|
|
|
}
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-09-23 07:27:01 -05:00
|
|
|
func TestLoader_Load_NestedPlugins(t *testing.T) {
|
2022-01-25 09:05:12 -06:00
|
|
|
rootDir, err := filepath.Abs("../")
|
2021-11-01 04:53:33 -05:00
|
|
|
if err != nil {
|
|
|
|
t.Errorf("could not construct absolute path of root dir")
|
|
|
|
return
|
|
|
|
}
|
|
|
|
parent := &plugins.Plugin{
|
|
|
|
JSONData: plugins.JSONData{
|
2022-08-22 11:11:45 -05:00
|
|
|
ID: "test-datasource",
|
2023-06-08 05:21:19 -05:00
|
|
|
Type: plugins.TypeDataSource,
|
2021-11-01 04:53:33 -05:00
|
|
|
Name: "Parent",
|
|
|
|
Info: plugins.Info{
|
|
|
|
Author: plugins.InfoLink{
|
|
|
|
Name: "Grafana Labs",
|
|
|
|
URL: "http://grafana.com",
|
|
|
|
},
|
|
|
|
Logos: plugins.Logos{
|
|
|
|
Small: "public/img/icn-datasource.svg",
|
|
|
|
Large: "public/img/icn-datasource.svg",
|
|
|
|
},
|
|
|
|
Description: "Parent plugin",
|
|
|
|
Version: "1.0.0",
|
|
|
|
Updated: "2020-10-20",
|
|
|
|
},
|
|
|
|
Dependencies: plugins.Dependencies{
|
|
|
|
GrafanaVersion: "*",
|
|
|
|
Plugins: []plugins.Dependency{},
|
|
|
|
},
|
|
|
|
Backend: true,
|
|
|
|
},
|
2023-04-27 03:26:15 -05:00
|
|
|
Module: "plugins/test-datasource/module",
|
|
|
|
BaseURL: "public/plugins/test-datasource",
|
|
|
|
FS: mustNewStaticFSForTests(t, filepath.Join(rootDir, "testdata/nested-plugins/parent")),
|
2023-06-08 05:21:19 -05:00
|
|
|
Signature: plugins.SignatureStatusValid,
|
|
|
|
SignatureType: plugins.SignatureTypeGrafana,
|
2021-11-01 04:53:33 -05:00
|
|
|
SignatureOrg: "Grafana Labs",
|
2023-06-08 05:21:19 -05:00
|
|
|
Class: plugins.ClassExternal,
|
2021-11-01 04:53:33 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
child := &plugins.Plugin{
|
|
|
|
JSONData: plugins.JSONData{
|
|
|
|
ID: "test-panel",
|
2023-06-08 05:21:19 -05:00
|
|
|
Type: plugins.TypePanel,
|
2021-11-01 04:53:33 -05:00
|
|
|
Name: "Child",
|
|
|
|
Info: plugins.Info{
|
|
|
|
Author: plugins.InfoLink{
|
|
|
|
Name: "Grafana Labs",
|
|
|
|
URL: "http://grafana.com",
|
|
|
|
},
|
|
|
|
Logos: plugins.Logos{
|
|
|
|
Small: "public/img/icn-panel.svg",
|
|
|
|
Large: "public/img/icn-panel.svg",
|
|
|
|
},
|
|
|
|
Description: "Child plugin",
|
|
|
|
Version: "1.0.1",
|
|
|
|
Updated: "2020-10-30",
|
|
|
|
},
|
|
|
|
Dependencies: plugins.Dependencies{
|
|
|
|
GrafanaVersion: "*",
|
|
|
|
Plugins: []plugins.Dependency{},
|
|
|
|
},
|
|
|
|
},
|
2023-04-27 03:26:15 -05:00
|
|
|
Module: "plugins/test-panel/module",
|
|
|
|
BaseURL: "public/plugins/test-panel",
|
|
|
|
FS: mustNewStaticFSForTests(t, filepath.Join(rootDir, "testdata/nested-plugins/parent/nested")),
|
2023-06-08 05:21:19 -05:00
|
|
|
Signature: plugins.SignatureStatusValid,
|
|
|
|
SignatureType: plugins.SignatureTypeGrafana,
|
2021-11-01 04:53:33 -05:00
|
|
|
SignatureOrg: "Grafana Labs",
|
2023-06-08 05:21:19 -05:00
|
|
|
Class: plugins.ClassExternal,
|
2021-11-01 04:53:33 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
parent.Children = []*plugins.Plugin{child}
|
|
|
|
child.Parent = parent
|
|
|
|
|
|
|
|
t.Run("Load nested External plugins", func(t *testing.T) {
|
2022-09-23 07:27:01 -05:00
|
|
|
procPrvdr := fakes.NewFakeBackendProcessProvider()
|
|
|
|
procMgr := fakes.NewFakeProcessManager()
|
Plugins: Angular detector: Remote patterns fetching (#69843)
* Plugins: Angular detector: Remote patterns fetching
* Renamed PatternType to GCOMPatternType
* Renamed files
* Renamed more files
* Moved files again
* Add type checks, unexport GCOM structs
* Cache failures, update log messages, fix GCOM URL
* Fail silently for unknown pattern types, update docstrings
* Fix tests
* Rename gcomPattern.Value to gcomPattern.Pattern
* Refactoring
* Add FlagPluginsRemoteAngularDetectionPatterns feature flag
* Fix tests
* Re-generate feature flags
* Add TestProvideInspector, renamed TestDefaultStaticDetectorsInspector
* Add TestProvideInspector
* Add TestContainsBytesDetector and TestRegexDetector
* Renamed getter to provider
* More tests
* TestStaticDetectorsProvider, TestSequenceDetectorsProvider
* GCOM tests
* Lint
* Made detector.detect unexported, updated docstrings
* Allow changing grafana.com URL
* Fix API path, add more logs
* Update tryUpdateRemoteDetectors docstring
* Use angulardetector http client
* Return false, nil if module.js does not exist
* Chore: Split angualrdetector into angularinspector and angulardetector packages
Moved files around, changed references and fixed tests:
- Split the old angulardetector package into angular/angulardetector and angular/angularinspector
- angulardetector provides the detection structs/interfaces (Detector, DetectorsProvider...)
- angularinspector provides the actual angular detection service used directly in pluginsintegration
- Exported most of the stuff that was private and now put into angulardetector, as it is not required by angularinspector
* Renamed detector.go -> angulardetector.go and inspector.go -> angularinspector.go
Forgot to rename those two files to match the package's names
* Renamed angularinspector.ProvideInspector to angularinspector.ProvideService
* Renamed "harcoded" to "static" and "remote" to "dynamic"
from PR review, matches the same naming schema used for signing keys fetching
* Fix merge conflict on updated angular patterns
* Removed GCOM cache
* Renamed Detect to DetectAngular and Detector to AngularDetector
* Fix call to NewGCOMDetectorsProvider in newDynamicInspector
* Removed unused test function newError500GCOMScenario
* Added angularinspector service definition in pluginsintegration
* Moved dynamic inspector into pluginsintegration
* Move gcom angulardetectorsprovider into pluginsintegration
* Log errUnknownPatternType at debug level
* re-generate feature flags
* fix error log
2023-06-26 08:33:21 -05:00
|
|
|
l := newLoader(t, &config.Cfg{}, func(l *Loader) {
|
2022-09-23 07:27:01 -05:00
|
|
|
l.processManager = procMgr
|
|
|
|
l.pluginInitializer = initializer.New(&config.Cfg{}, procPrvdr, fakes.NewFakeLicensingService())
|
2023-07-27 08:29:13 -05:00
|
|
|
l.discovery = discovery.New(l.cfg, discovery.Opts{
|
|
|
|
FindFilterFuncs: []discovery.FindFilterFunc{
|
|
|
|
func(ctx context.Context, class plugins.Class, bundles []*plugins.FoundBundle) ([]*plugins.FoundBundle, error) {
|
|
|
|
return discovery.NewDuplicatePluginFilterStep(l.pluginRegistry).Filter(ctx, bundles)
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
)
|
2022-09-23 07:27:01 -05:00
|
|
|
})
|
2021-11-01 04:53:33 -05:00
|
|
|
|
2023-03-20 08:35:49 -05:00
|
|
|
got, err := l.Load(context.Background(), &fakes.FakePluginSource{
|
|
|
|
PluginClassFunc: func(ctx context.Context) plugins.Class {
|
2023-06-08 05:21:19 -05:00
|
|
|
return plugins.ClassExternal
|
2023-03-20 08:35:49 -05:00
|
|
|
},
|
|
|
|
PluginURIsFunc: func(ctx context.Context) []string {
|
|
|
|
return []string{"../testdata/nested-plugins"}
|
|
|
|
},
|
|
|
|
})
|
2022-09-23 07:27:01 -05:00
|
|
|
require.NoError(t, err)
|
2021-11-01 04:53:33 -05:00
|
|
|
|
|
|
|
// to ensure we can compare with expected
|
|
|
|
sort.SliceStable(got, func(i, j int) bool {
|
|
|
|
return got[i].ID < got[j].ID
|
|
|
|
})
|
|
|
|
|
2022-09-23 07:27:01 -05:00
|
|
|
expected := []*plugins.Plugin{parent, child}
|
2023-03-07 09:47:02 -06:00
|
|
|
if !cmp.Equal(got, expected, compareOpts...) {
|
|
|
|
t.Fatalf("Result mismatch (-want +got):\n%s", cmp.Diff(got, expected, compareOpts...))
|
2021-11-01 04:53:33 -05:00
|
|
|
}
|
|
|
|
|
2023-07-27 08:29:13 -05:00
|
|
|
verifyState(t, expected, l.pluginRegistry, procPrvdr, procMgr)
|
2021-11-01 04:53:33 -05:00
|
|
|
|
2022-09-23 07:27:01 -05:00
|
|
|
t.Run("Load will exclude plugins that already exist", func(t *testing.T) {
|
2023-03-20 08:35:49 -05:00
|
|
|
got, err := l.Load(context.Background(), &fakes.FakePluginSource{
|
|
|
|
PluginClassFunc: func(ctx context.Context) plugins.Class {
|
2023-06-08 05:21:19 -05:00
|
|
|
return plugins.ClassExternal
|
2023-03-20 08:35:49 -05:00
|
|
|
},
|
|
|
|
PluginURIsFunc: func(ctx context.Context) []string {
|
|
|
|
return []string{"../testdata/nested-plugins"}
|
|
|
|
},
|
|
|
|
})
|
2022-09-23 07:27:01 -05:00
|
|
|
require.NoError(t, err)
|
2021-11-01 04:53:33 -05:00
|
|
|
|
2022-09-23 07:27:01 -05:00
|
|
|
// to ensure we can compare with expected
|
|
|
|
sort.SliceStable(got, func(i, j int) bool {
|
|
|
|
return got[i].ID < got[j].ID
|
|
|
|
})
|
2021-11-01 04:53:33 -05:00
|
|
|
|
2023-03-07 09:47:02 -06:00
|
|
|
if !cmp.Equal(got, []*plugins.Plugin{}, compareOpts...) {
|
|
|
|
t.Fatalf("Result mismatch (-want +got):\n%s", cmp.Diff(got, expected, compareOpts...))
|
2022-09-23 07:27:01 -05:00
|
|
|
}
|
2021-11-01 04:53:33 -05:00
|
|
|
|
2023-07-27 08:29:13 -05:00
|
|
|
verifyState(t, expected, l.pluginRegistry, procPrvdr, procMgr)
|
2022-09-23 07:27:01 -05:00
|
|
|
})
|
2021-11-01 04:53:33 -05:00
|
|
|
})
|
2022-01-21 04:00:20 -06:00
|
|
|
|
|
|
|
t.Run("Plugin child field `IncludedInAppID` is set to parent app's plugin ID", func(t *testing.T) {
|
|
|
|
parent := &plugins.Plugin{
|
|
|
|
JSONData: plugins.JSONData{
|
|
|
|
ID: "myorgid-simple-app",
|
2023-06-08 05:21:19 -05:00
|
|
|
Type: plugins.TypeApp,
|
2022-01-21 04:00:20 -06:00
|
|
|
Name: "Simple App",
|
|
|
|
Info: plugins.Info{
|
|
|
|
Author: plugins.InfoLink{
|
|
|
|
Name: "Your Name",
|
|
|
|
},
|
|
|
|
Links: []plugins.InfoLink{
|
|
|
|
{Name: "Website", URL: "https://github.com/grafana/grafana-starter-app"},
|
|
|
|
{Name: "License", URL: "https://github.com/grafana/grafana-starter-app/blob/master/LICENSE"},
|
|
|
|
},
|
|
|
|
Logos: plugins.Logos{
|
|
|
|
Small: "public/plugins/myorgid-simple-app/img/logo.svg",
|
|
|
|
Large: "public/plugins/myorgid-simple-app/img/logo.svg",
|
|
|
|
},
|
|
|
|
Screenshots: []plugins.Screenshots{},
|
|
|
|
Description: "Grafana App Plugin Template",
|
|
|
|
Version: "%VERSION%",
|
|
|
|
Updated: "%TODAY%",
|
|
|
|
},
|
|
|
|
Dependencies: plugins.Dependencies{
|
|
|
|
GrafanaVersion: "7.0.0",
|
|
|
|
GrafanaDependency: ">=7.0.0",
|
|
|
|
Plugins: []plugins.Dependency{},
|
|
|
|
},
|
|
|
|
Includes: []*plugins.Includes{
|
|
|
|
{
|
|
|
|
Name: "Root Page (react)",
|
|
|
|
Path: "/a/myorgid-simple-app",
|
|
|
|
Type: "page",
|
2023-06-08 05:21:19 -05:00
|
|
|
Role: org.RoleViewer,
|
2022-01-21 04:00:20 -06:00
|
|
|
AddToNav: true,
|
|
|
|
DefaultNav: true,
|
|
|
|
Slug: "root-page-react",
|
|
|
|
},
|
|
|
|
{
|
|
|
|
Name: "Root Page (Tab B)",
|
|
|
|
Path: "/a/myorgid-simple-app/?tab=b",
|
|
|
|
Type: "page",
|
2023-06-08 05:21:19 -05:00
|
|
|
Role: org.RoleViewer,
|
2022-01-21 04:00:20 -06:00
|
|
|
AddToNav: true,
|
|
|
|
Slug: "root-page-tab-b",
|
|
|
|
},
|
|
|
|
{
|
|
|
|
Name: "React Config",
|
|
|
|
Path: "/plugins/myorgid-simple-app/?page=page2",
|
|
|
|
Type: "page",
|
2023-06-08 05:21:19 -05:00
|
|
|
Role: org.RoleAdmin,
|
2022-01-21 04:00:20 -06:00
|
|
|
AddToNav: true,
|
|
|
|
Slug: "react-config",
|
|
|
|
},
|
|
|
|
{
|
|
|
|
Name: "Streaming Example",
|
|
|
|
Path: "dashboards/streaming.json",
|
|
|
|
Type: "dashboard",
|
2023-06-08 05:21:19 -05:00
|
|
|
Role: org.RoleViewer,
|
2022-01-21 04:00:20 -06:00
|
|
|
Slug: "streaming-example",
|
|
|
|
},
|
|
|
|
{
|
|
|
|
Name: "Lots of Stats",
|
|
|
|
Path: "dashboards/stats.json",
|
|
|
|
Type: "dashboard",
|
2023-06-08 05:21:19 -05:00
|
|
|
Role: org.RoleViewer,
|
2022-01-21 04:00:20 -06:00
|
|
|
Slug: "lots-of-stats",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
Backend: false,
|
|
|
|
},
|
2023-04-27 03:26:15 -05:00
|
|
|
Module: "plugins/myorgid-simple-app/module",
|
|
|
|
BaseURL: "public/plugins/myorgid-simple-app",
|
|
|
|
FS: mustNewStaticFSForTests(t, filepath.Join(rootDir, "testdata/app-with-child/dist")),
|
2022-01-21 04:00:20 -06:00
|
|
|
DefaultNavURL: "/plugins/myorgid-simple-app/page/root-page-react",
|
2023-06-08 05:21:19 -05:00
|
|
|
Signature: plugins.SignatureStatusValid,
|
|
|
|
SignatureType: plugins.SignatureTypeGrafana,
|
2022-01-21 04:00:20 -06:00
|
|
|
SignatureOrg: "Grafana Labs",
|
2023-06-08 05:21:19 -05:00
|
|
|
Class: plugins.ClassExternal,
|
2022-01-21 04:00:20 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
child := &plugins.Plugin{
|
|
|
|
JSONData: plugins.JSONData{
|
|
|
|
ID: "myorgid-simple-panel",
|
2023-06-08 05:21:19 -05:00
|
|
|
Type: plugins.TypePanel,
|
2022-01-21 04:00:20 -06:00
|
|
|
Name: "Grafana Panel Plugin Template",
|
|
|
|
Info: plugins.Info{
|
|
|
|
Author: plugins.InfoLink{
|
|
|
|
Name: "Your Name",
|
|
|
|
},
|
|
|
|
Links: []plugins.InfoLink{
|
|
|
|
{Name: "Website", URL: "https://github.com/grafana/grafana-starter-panel"},
|
|
|
|
{Name: "License", URL: "https://github.com/grafana/grafana-starter-panel/blob/master/LICENSE"},
|
|
|
|
},
|
|
|
|
Logos: plugins.Logos{
|
|
|
|
Small: "public/plugins/myorgid-simple-panel/img/logo.svg",
|
|
|
|
Large: "public/plugins/myorgid-simple-panel/img/logo.svg",
|
|
|
|
},
|
|
|
|
Screenshots: []plugins.Screenshots{},
|
|
|
|
Description: "Grafana Panel Plugin Template",
|
|
|
|
Version: "%VERSION%",
|
|
|
|
Updated: "%TODAY%",
|
|
|
|
},
|
|
|
|
Dependencies: plugins.Dependencies{
|
|
|
|
GrafanaDependency: ">=7.0.0",
|
|
|
|
GrafanaVersion: "*",
|
|
|
|
Plugins: []plugins.Dependency{},
|
|
|
|
},
|
|
|
|
},
|
2023-04-27 03:26:15 -05:00
|
|
|
Module: "plugins/myorgid-simple-app/child/module",
|
|
|
|
BaseURL: "public/plugins/myorgid-simple-app",
|
|
|
|
FS: mustNewStaticFSForTests(t, filepath.Join(rootDir, "testdata/app-with-child/dist/child")),
|
2022-01-21 04:00:20 -06:00
|
|
|
IncludedInAppID: parent.ID,
|
2023-06-08 05:21:19 -05:00
|
|
|
Signature: plugins.SignatureStatusValid,
|
|
|
|
SignatureType: plugins.SignatureTypeGrafana,
|
2022-01-21 04:00:20 -06:00
|
|
|
SignatureOrg: "Grafana Labs",
|
2023-06-08 05:21:19 -05:00
|
|
|
Class: plugins.ClassExternal,
|
2022-01-21 04:00:20 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
parent.Children = []*plugins.Plugin{child}
|
|
|
|
child.Parent = parent
|
|
|
|
expected := []*plugins.Plugin{parent, child}
|
|
|
|
|
2022-09-23 07:27:01 -05:00
|
|
|
reg := fakes.NewFakePluginRegistry()
|
|
|
|
procPrvdr := fakes.NewFakeBackendProcessProvider()
|
|
|
|
procMgr := fakes.NewFakeProcessManager()
|
Plugins: Angular detector: Remote patterns fetching (#69843)
* Plugins: Angular detector: Remote patterns fetching
* Renamed PatternType to GCOMPatternType
* Renamed files
* Renamed more files
* Moved files again
* Add type checks, unexport GCOM structs
* Cache failures, update log messages, fix GCOM URL
* Fail silently for unknown pattern types, update docstrings
* Fix tests
* Rename gcomPattern.Value to gcomPattern.Pattern
* Refactoring
* Add FlagPluginsRemoteAngularDetectionPatterns feature flag
* Fix tests
* Re-generate feature flags
* Add TestProvideInspector, renamed TestDefaultStaticDetectorsInspector
* Add TestProvideInspector
* Add TestContainsBytesDetector and TestRegexDetector
* Renamed getter to provider
* More tests
* TestStaticDetectorsProvider, TestSequenceDetectorsProvider
* GCOM tests
* Lint
* Made detector.detect unexported, updated docstrings
* Allow changing grafana.com URL
* Fix API path, add more logs
* Update tryUpdateRemoteDetectors docstring
* Use angulardetector http client
* Return false, nil if module.js does not exist
* Chore: Split angualrdetector into angularinspector and angulardetector packages
Moved files around, changed references and fixed tests:
- Split the old angulardetector package into angular/angulardetector and angular/angularinspector
- angulardetector provides the detection structs/interfaces (Detector, DetectorsProvider...)
- angularinspector provides the actual angular detection service used directly in pluginsintegration
- Exported most of the stuff that was private and now put into angulardetector, as it is not required by angularinspector
* Renamed detector.go -> angulardetector.go and inspector.go -> angularinspector.go
Forgot to rename those two files to match the package's names
* Renamed angularinspector.ProvideInspector to angularinspector.ProvideService
* Renamed "harcoded" to "static" and "remote" to "dynamic"
from PR review, matches the same naming schema used for signing keys fetching
* Fix merge conflict on updated angular patterns
* Removed GCOM cache
* Renamed Detect to DetectAngular and Detector to AngularDetector
* Fix call to NewGCOMDetectorsProvider in newDynamicInspector
* Removed unused test function newError500GCOMScenario
* Added angularinspector service definition in pluginsintegration
* Moved dynamic inspector into pluginsintegration
* Move gcom angulardetectorsprovider into pluginsintegration
* Log errUnknownPatternType at debug level
* re-generate feature flags
* fix error log
2023-06-26 08:33:21 -05:00
|
|
|
l := newLoader(t, &config.Cfg{}, func(l *Loader) {
|
2022-09-23 07:27:01 -05:00
|
|
|
l.pluginRegistry = reg
|
|
|
|
l.processManager = procMgr
|
|
|
|
l.pluginInitializer = initializer.New(&config.Cfg{}, procPrvdr, fakes.NewFakeLicensingService())
|
|
|
|
})
|
2023-03-20 08:35:49 -05:00
|
|
|
got, err := l.Load(context.Background(), &fakes.FakePluginSource{
|
|
|
|
PluginClassFunc: func(ctx context.Context) plugins.Class {
|
2023-06-08 05:21:19 -05:00
|
|
|
return plugins.ClassExternal
|
2023-03-20 08:35:49 -05:00
|
|
|
},
|
|
|
|
PluginURIsFunc: func(ctx context.Context) []string {
|
|
|
|
return []string{"../testdata/app-with-child"}
|
|
|
|
},
|
|
|
|
})
|
2022-09-23 07:27:01 -05:00
|
|
|
require.NoError(t, err)
|
2022-01-21 04:00:20 -06:00
|
|
|
|
|
|
|
// to ensure we can compare with expected
|
|
|
|
sort.SliceStable(got, func(i, j int) bool {
|
|
|
|
return got[i].ID < got[j].ID
|
|
|
|
})
|
|
|
|
|
2023-03-07 09:47:02 -06:00
|
|
|
if !cmp.Equal(got, expected, compareOpts...) {
|
|
|
|
t.Fatalf("Result mismatch (-want +got):\n%s", cmp.Diff(got, expected, compareOpts...))
|
2022-01-21 04:00:20 -06:00
|
|
|
}
|
2022-01-25 09:05:12 -06:00
|
|
|
|
2023-04-20 04:52:59 -05:00
|
|
|
verifyState(t, expected, reg, procPrvdr, procMgr)
|
2022-01-21 04:00:20 -06:00
|
|
|
})
|
2021-11-01 04:53:33 -05:00
|
|
|
}
|
|
|
|
|
Plugins: Angular detector: Remote patterns fetching (#69843)
* Plugins: Angular detector: Remote patterns fetching
* Renamed PatternType to GCOMPatternType
* Renamed files
* Renamed more files
* Moved files again
* Add type checks, unexport GCOM structs
* Cache failures, update log messages, fix GCOM URL
* Fail silently for unknown pattern types, update docstrings
* Fix tests
* Rename gcomPattern.Value to gcomPattern.Pattern
* Refactoring
* Add FlagPluginsRemoteAngularDetectionPatterns feature flag
* Fix tests
* Re-generate feature flags
* Add TestProvideInspector, renamed TestDefaultStaticDetectorsInspector
* Add TestProvideInspector
* Add TestContainsBytesDetector and TestRegexDetector
* Renamed getter to provider
* More tests
* TestStaticDetectorsProvider, TestSequenceDetectorsProvider
* GCOM tests
* Lint
* Made detector.detect unexported, updated docstrings
* Allow changing grafana.com URL
* Fix API path, add more logs
* Update tryUpdateRemoteDetectors docstring
* Use angulardetector http client
* Return false, nil if module.js does not exist
* Chore: Split angualrdetector into angularinspector and angulardetector packages
Moved files around, changed references and fixed tests:
- Split the old angulardetector package into angular/angulardetector and angular/angularinspector
- angulardetector provides the detection structs/interfaces (Detector, DetectorsProvider...)
- angularinspector provides the actual angular detection service used directly in pluginsintegration
- Exported most of the stuff that was private and now put into angulardetector, as it is not required by angularinspector
* Renamed detector.go -> angulardetector.go and inspector.go -> angularinspector.go
Forgot to rename those two files to match the package's names
* Renamed angularinspector.ProvideInspector to angularinspector.ProvideService
* Renamed "harcoded" to "static" and "remote" to "dynamic"
from PR review, matches the same naming schema used for signing keys fetching
* Fix merge conflict on updated angular patterns
* Removed GCOM cache
* Renamed Detect to DetectAngular and Detector to AngularDetector
* Fix call to NewGCOMDetectorsProvider in newDynamicInspector
* Removed unused test function newError500GCOMScenario
* Added angularinspector service definition in pluginsintegration
* Moved dynamic inspector into pluginsintegration
* Move gcom angulardetectorsprovider into pluginsintegration
* Log errUnknownPatternType at debug level
* re-generate feature flags
* fix error log
2023-06-26 08:33:21 -05:00
|
|
|
func newLoader(t *testing.T, cfg *config.Cfg, cbs ...func(loader *Loader)) *Loader {
|
|
|
|
angularInspector, err := angularinspector.NewStaticInspector()
|
2023-07-27 08:29:13 -05:00
|
|
|
reg := fakes.NewFakePluginRegistry()
|
|
|
|
assets := assetpath.ProvideService(pluginscdn.ProvideService(cfg))
|
Plugins: Angular detector: Remote patterns fetching (#69843)
* Plugins: Angular detector: Remote patterns fetching
* Renamed PatternType to GCOMPatternType
* Renamed files
* Renamed more files
* Moved files again
* Add type checks, unexport GCOM structs
* Cache failures, update log messages, fix GCOM URL
* Fail silently for unknown pattern types, update docstrings
* Fix tests
* Rename gcomPattern.Value to gcomPattern.Pattern
* Refactoring
* Add FlagPluginsRemoteAngularDetectionPatterns feature flag
* Fix tests
* Re-generate feature flags
* Add TestProvideInspector, renamed TestDefaultStaticDetectorsInspector
* Add TestProvideInspector
* Add TestContainsBytesDetector and TestRegexDetector
* Renamed getter to provider
* More tests
* TestStaticDetectorsProvider, TestSequenceDetectorsProvider
* GCOM tests
* Lint
* Made detector.detect unexported, updated docstrings
* Allow changing grafana.com URL
* Fix API path, add more logs
* Update tryUpdateRemoteDetectors docstring
* Use angulardetector http client
* Return false, nil if module.js does not exist
* Chore: Split angualrdetector into angularinspector and angulardetector packages
Moved files around, changed references and fixed tests:
- Split the old angulardetector package into angular/angulardetector and angular/angularinspector
- angulardetector provides the detection structs/interfaces (Detector, DetectorsProvider...)
- angularinspector provides the actual angular detection service used directly in pluginsintegration
- Exported most of the stuff that was private and now put into angulardetector, as it is not required by angularinspector
* Renamed detector.go -> angulardetector.go and inspector.go -> angularinspector.go
Forgot to rename those two files to match the package's names
* Renamed angularinspector.ProvideInspector to angularinspector.ProvideService
* Renamed "harcoded" to "static" and "remote" to "dynamic"
from PR review, matches the same naming schema used for signing keys fetching
* Fix merge conflict on updated angular patterns
* Removed GCOM cache
* Renamed Detect to DetectAngular and Detector to AngularDetector
* Fix call to NewGCOMDetectorsProvider in newDynamicInspector
* Removed unused test function newError500GCOMScenario
* Added angularinspector service definition in pluginsintegration
* Moved dynamic inspector into pluginsintegration
* Move gcom angulardetectorsprovider into pluginsintegration
* Log errUnknownPatternType at debug level
* re-generate feature flags
* fix error log
2023-06-26 08:33:21 -05:00
|
|
|
require.NoError(t, err)
|
2023-07-27 08:29:13 -05:00
|
|
|
l := New(cfg, &fakes.FakeLicensingService{}, signature.NewUnsignedAuthorizer(cfg), reg,
|
2023-04-20 04:52:59 -05:00
|
|
|
fakes.NewFakeBackendProcessProvider(), fakes.NewFakeProcessManager(), fakes.NewFakeRoleRegistry(),
|
2023-07-27 08:29:13 -05:00
|
|
|
assets, angularInspector, &fakes.FakeOauthService{},
|
|
|
|
discovery.New(cfg, discovery.Opts{}), bootstrap.New(cfg, bootstrap.Opts{}))
|
2021-11-01 04:53:33 -05:00
|
|
|
|
2022-09-23 07:27:01 -05:00
|
|
|
for _, cb := range cbs {
|
|
|
|
cb(l)
|
|
|
|
}
|
2021-11-01 04:53:33 -05:00
|
|
|
|
2022-09-23 07:27:01 -05:00
|
|
|
return l
|
2021-11-01 04:53:33 -05:00
|
|
|
}
|
|
|
|
|
2023-07-27 08:29:13 -05:00
|
|
|
func verifyState(t *testing.T, ps []*plugins.Plugin, reg registry.Service,
|
2023-04-20 04:52:59 -05:00
|
|
|
procPrvdr *fakes.FakeBackendProcessProvider, procMngr *fakes.FakeProcessManager) {
|
2022-09-23 07:27:01 -05:00
|
|
|
t.Helper()
|
2021-11-01 04:53:33 -05:00
|
|
|
|
2022-09-23 07:27:01 -05:00
|
|
|
for _, p := range ps {
|
2023-07-27 08:29:13 -05:00
|
|
|
regP, exists := reg.Plugin(context.Background(), p.ID)
|
|
|
|
require.True(t, exists)
|
|
|
|
if !cmp.Equal(p, regP, compareOpts...) {
|
|
|
|
t.Fatalf("Result mismatch (-want +got):\n%s", cmp.Diff(p, regP, compareOpts...))
|
2022-09-23 07:27:01 -05:00
|
|
|
}
|
2021-11-01 04:53:33 -05:00
|
|
|
|
2022-09-23 07:27:01 -05:00
|
|
|
if p.Backend {
|
|
|
|
require.Equal(t, 1, procPrvdr.Requested[p.ID])
|
|
|
|
require.Equal(t, 1, procPrvdr.Invoked[p.ID])
|
|
|
|
} else {
|
|
|
|
require.Zero(t, procPrvdr.Requested[p.ID])
|
|
|
|
require.Zero(t, procPrvdr.Invoked[p.ID])
|
|
|
|
}
|
2021-11-23 10:09:52 -06:00
|
|
|
|
2022-09-23 07:27:01 -05:00
|
|
|
require.Equal(t, 1, procMngr.Started[p.ID])
|
|
|
|
require.Zero(t, procMngr.Stopped[p.ID])
|
|
|
|
}
|
2022-01-07 14:11:23 -06:00
|
|
|
}
|
2023-03-07 09:47:02 -06:00
|
|
|
|
2023-04-27 03:26:15 -05:00
|
|
|
func mustNewStaticFSForTests(t *testing.T, dir string) plugins.FS {
|
|
|
|
sfs, err := plugins.NewStaticFS(plugins.NewLocalFS(dir))
|
|
|
|
require.NoError(t, err)
|
|
|
|
return sfs
|
2023-03-07 09:47:02 -06:00
|
|
|
}
|