Plugins: Removed feature toggle pluginsDynamicAngularDetectionPatterns (#85956)

* Plugins: Removed feature toggle pluginsDynamicAngularDetectionPatterns

* re-generate feature toggles
This commit is contained in:
Giuseppe Guerra
2024-04-15 10:37:28 +02:00
committed by GitHub
parent 41e4b95b51
commit eec9d3dbc4
10 changed files with 58 additions and 128 deletions

View File

@@ -19,49 +19,48 @@ This page contains a list of available feature toggles. To learn how to turn on
Some features are enabled by default. You can disable these feature by setting the feature flag to "false" in the configuration. Some features are enabled by default. You can disable these feature by setting the feature flag to "false" in the configuration.
| Feature toggle name | Description | Enabled by default | | Feature toggle name | Description | Enabled by default |
| ---------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------ | | ------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------ |
| `disableEnvelopeEncryption` | Disable envelope encryption (emergency only) | | | `disableEnvelopeEncryption` | Disable envelope encryption (emergency only) | |
| `publicDashboards` | [Deprecated] Public dashboards are now enabled by default; to disable them, use the configuration setting. This feature toggle will be removed in the next major version. | Yes | | `publicDashboards` | [Deprecated] Public dashboards are now enabled by default; to disable them, use the configuration setting. This feature toggle will be removed in the next major version. | Yes |
| `featureHighlights` | Highlight Grafana Enterprise features | | | `featureHighlights` | Highlight Grafana Enterprise features | |
| `correlations` | Correlations page | | | `correlations` | Correlations page | |
| `exploreContentOutline` | Content outline sidebar | Yes | | `exploreContentOutline` | Content outline sidebar | Yes |
| `cloudWatchCrossAccountQuerying` | Enables cross-account querying in CloudWatch datasources | Yes | | `cloudWatchCrossAccountQuerying` | Enables cross-account querying in CloudWatch datasources | Yes |
| `nestedFolders` | Enable folder nesting | Yes | | `nestedFolders` | Enable folder nesting | Yes |
| `nestedFolderPicker` | Enables the new folder picker to work with nested folders. Requires the nestedFolders feature toggle | Yes | | `nestedFolderPicker` | Enables the new folder picker to work with nested folders. Requires the nestedFolders feature toggle | Yes |
| `logsContextDatasourceUi` | Allow datasource to provide custom UI for context view | Yes | | `logsContextDatasourceUi` | Allow datasource to provide custom UI for context view | Yes |
| `lokiQuerySplitting` | Split large interval queries into subqueries with smaller time intervals | Yes | | `lokiQuerySplitting` | Split large interval queries into subqueries with smaller time intervals | Yes |
| `prometheusMetricEncyclopedia` | Adds the metrics explorer component to the Prometheus query builder as an option in metric select | Yes | | `prometheusMetricEncyclopedia` | Adds the metrics explorer component to the Prometheus query builder as an option in metric select | Yes |
| `influxdbBackendMigration` | Query InfluxDB InfluxQL without the proxy | Yes | | `influxdbBackendMigration` | Query InfluxDB InfluxQL without the proxy | Yes |
| `prometheusDataplane` | Changes responses to from Prometheus to be compliant with the dataplane specification. In particular, when this feature toggle is active, the numeric `Field.Name` is set from 'Value' to the value of the `__name__` label. | Yes | | `prometheusDataplane` | Changes responses to from Prometheus to be compliant with the dataplane specification. In particular, when this feature toggle is active, the numeric `Field.Name` is set from 'Value' to the value of the `__name__` label. | Yes |
| `lokiMetricDataplane` | Changes metric responses from Loki to be compliant with the dataplane specification. | Yes | | `lokiMetricDataplane` | Changes metric responses from Loki to be compliant with the dataplane specification. | Yes |
| `dataplaneFrontendFallback` | Support dataplane contract field name change for transformations and field name matchers where the name is different | Yes | | `dataplaneFrontendFallback` | Support dataplane contract field name change for transformations and field name matchers where the name is different | Yes |
| `enableElasticsearchBackendQuerying` | Enable the processing of queries and responses in the Elasticsearch data source through backend | Yes | | `enableElasticsearchBackendQuerying` | Enable the processing of queries and responses in the Elasticsearch data source through backend | Yes |
| `recordedQueriesMulti` | Enables writing multiple items from a single query within Recorded Queries | Yes | | `recordedQueriesMulti` | Enables writing multiple items from a single query within Recorded Queries | Yes |
| `pluginsDynamicAngularDetectionPatterns` | Enables fetching Angular detection patterns for plugins from GCOM and fallback to hardcoded ones | Yes | | `logsExploreTableVisualisation` | A table visualisation for logs in Explore | Yes |
| `logsExploreTableVisualisation` | A table visualisation for logs in Explore | Yes | | `transformationsRedesign` | Enables the transformations redesign | Yes |
| `transformationsRedesign` | Enables the transformations redesign | Yes | | `traceQLStreaming` | Enables response streaming of TraceQL queries of the Tempo data source | |
| `traceQLStreaming` | Enables response streaming of TraceQL queries of the Tempo data source | | | `awsAsyncQueryCaching` | Enable caching for async queries for Redshift and Athena. Requires that the datasource has caching and async query support enabled | Yes |
| `awsAsyncQueryCaching` | Enable caching for async queries for Redshift and Athena. Requires that the datasource has caching and async query support enabled | Yes | | `prometheusConfigOverhaulAuth` | Update the Prometheus configuration page with the new auth component | Yes |
| `prometheusConfigOverhaulAuth` | Update the Prometheus configuration page with the new auth component | Yes | | `influxdbSqlSupport` | Enable InfluxDB SQL query language support with new querying UI | Yes |
| `influxdbSqlSupport` | Enable InfluxDB SQL query language support with new querying UI | Yes | | `alertingNoDataErrorExecution` | Changes how Alerting state manager handles execution of NoData/Error | Yes |
| `alertingNoDataErrorExecution` | Changes how Alerting state manager handles execution of NoData/Error | Yes | | `angularDeprecationUI` | Display Angular warnings in dashboards and panels | Yes |
| `angularDeprecationUI` | Display Angular warnings in dashboards and panels | Yes | | `dashgpt` | Enable AI powered features in dashboards | Yes |
| `dashgpt` | Enable AI powered features in dashboards | Yes | | `alertingInsights` | Show the new alerting insights landing page | Yes |
| `alertingInsights` | Show the new alerting insights landing page | Yes | | `panelMonitoring` | Enables panel monitoring through logs and measurements | Yes |
| `panelMonitoring` | Enables panel monitoring through logs and measurements | Yes | | `recoveryThreshold` | Enables feature recovery threshold (aka hysteresis) for threshold server-side expression | Yes |
| `recoveryThreshold` | Enables feature recovery threshold (aka hysteresis) for threshold server-side expression | Yes | | `lokiStructuredMetadata` | Enables the loki data source to request structured metadata from the Loki server | Yes |
| `lokiStructuredMetadata` | Enables the loki data source to request structured metadata from the Loki server | Yes | | `managedPluginsInstall` | Install managed plugins directly from plugins catalog | Yes |
| `managedPluginsInstall` | Install managed plugins directly from plugins catalog | Yes | | `annotationPermissionUpdate` | Change the way annotation permissions work by scoping them to folders and dashboards. | Yes |
| `annotationPermissionUpdate` | Change the way annotation permissions work by scoping them to folders and dashboards. | Yes | | `exploreMetrics` | Enables the new Explore Metrics core app | Yes |
| `exploreMetrics` | Enables the new Explore Metrics core app | Yes | | `alertingSimplifiedRouting` | Enables users to easily configure alert notifications by specifying a contact point directly when editing or creating an alert rule | Yes |
| `alertingSimplifiedRouting` | Enables users to easily configure alert notifications by specifying a contact point directly when editing or creating an alert rule | Yes | | `logRowsPopoverMenu` | Enable filtering menu displayed when text of a log line is selected | Yes |
| `logRowsPopoverMenu` | Enable filtering menu displayed when text of a log line is selected | Yes | | `lokiQueryHints` | Enables query hints for Loki | Yes |
| `lokiQueryHints` | Enables query hints for Loki | Yes | | `alertingQueryOptimization` | Optimizes eligible queries in order to reduce load on datasources | |
| `alertingQueryOptimization` | Optimizes eligible queries in order to reduce load on datasources | | | `betterPageScrolling` | Removes CustomScrollbar from the UI, relying on native browser scrollbars | Yes |
| `betterPageScrolling` | Removes CustomScrollbar from the UI, relying on native browser scrollbars | Yes | | `usePrometheusFrontendPackage` | Use the @grafana/prometheus frontend package in core Prometheus. | |
| `usePrometheusFrontendPackage` | Use the @grafana/prometheus frontend package in core Prometheus. | | | `cloudWatchNewLabelParsing` | Updates CloudWatch label parsing to be more accurate | Yes |
| `cloudWatchNewLabelParsing` | Updates CloudWatch label parsing to be more accurate | Yes |
## Preview feature toggles ## Preview feature toggles

View File

@@ -86,7 +86,6 @@ export interface FeatureToggles {
sqlDatasourceDatabaseSelection?: boolean; sqlDatasourceDatabaseSelection?: boolean;
lokiFormatQuery?: boolean; lokiFormatQuery?: boolean;
recordedQueriesMulti?: boolean; recordedQueriesMulti?: boolean;
pluginsDynamicAngularDetectionPatterns?: boolean;
vizAndWidgetSplit?: boolean; vizAndWidgetSplit?: boolean;
prometheusIncrementalQueryInstrumentation?: boolean; prometheusIncrementalQueryInstrumentation?: boolean;
logsExploreTableVisualisation?: boolean; logsExploreTableVisualisation?: boolean;

View File

@@ -508,14 +508,6 @@ var (
Owner: grafanaObservabilityMetricsSquad, Owner: grafanaObservabilityMetricsSquad,
AllowSelfServe: false, AllowSelfServe: false,
}, },
{
Name: "pluginsDynamicAngularDetectionPatterns",
Description: "Enables fetching Angular detection patterns for plugins from GCOM and fallback to hardcoded ones",
Stage: FeatureStageGeneralAvailability,
FrontendOnly: false,
Owner: grafanaPluginsPlatformSquad,
Expression: "true", // enabled by default
},
{ {
Name: "vizAndWidgetSplit", Name: "vizAndWidgetSplit",
Description: "Split panels between visualizations and widgets", Description: "Split panels between visualizations and widgets",

View File

@@ -67,7 +67,6 @@ frontendSandboxMonitorOnly,experimental,@grafana/plugins-platform-backend,false,
sqlDatasourceDatabaseSelection,preview,@grafana/dataviz-squad,false,false,true sqlDatasourceDatabaseSelection,preview,@grafana/dataviz-squad,false,false,true
lokiFormatQuery,experimental,@grafana/observability-logs,false,false,true lokiFormatQuery,experimental,@grafana/observability-logs,false,false,true
recordedQueriesMulti,GA,@grafana/observability-metrics,false,false,false recordedQueriesMulti,GA,@grafana/observability-metrics,false,false,false
pluginsDynamicAngularDetectionPatterns,GA,@grafana/plugins-platform-backend,false,false,false
vizAndWidgetSplit,experimental,@grafana/dashboards-squad,false,false,true vizAndWidgetSplit,experimental,@grafana/dashboards-squad,false,false,true
prometheusIncrementalQueryInstrumentation,experimental,@grafana/observability-metrics,false,false,true prometheusIncrementalQueryInstrumentation,experimental,@grafana/observability-metrics,false,false,true
logsExploreTableVisualisation,GA,@grafana/observability-logs,false,false,true logsExploreTableVisualisation,GA,@grafana/observability-logs,false,false,true
1 Name Stage Owner requiresDevMode RequiresRestart FrontendOnly
67 sqlDatasourceDatabaseSelection preview @grafana/dataviz-squad false false true
68 lokiFormatQuery experimental @grafana/observability-logs false false true
69 recordedQueriesMulti GA @grafana/observability-metrics false false false
pluginsDynamicAngularDetectionPatterns GA @grafana/plugins-platform-backend false false false
70 vizAndWidgetSplit experimental @grafana/dashboards-squad false false true
71 prometheusIncrementalQueryInstrumentation experimental @grafana/observability-metrics false false true
72 logsExploreTableVisualisation GA @grafana/observability-logs false false true

View File

@@ -279,10 +279,6 @@ const (
// Enables writing multiple items from a single query within Recorded Queries // Enables writing multiple items from a single query within Recorded Queries
FlagRecordedQueriesMulti = "recordedQueriesMulti" FlagRecordedQueriesMulti = "recordedQueriesMulti"
// FlagPluginsDynamicAngularDetectionPatterns
// Enables fetching Angular detection patterns for plugins from GCOM and fallback to hardcoded ones
FlagPluginsDynamicAngularDetectionPatterns = "pluginsDynamicAngularDetectionPatterns"
// FlagVizAndWidgetSplit // FlagVizAndWidgetSplit
// Split panels between visualizations and widgets // Split panels between visualizations and widgets
FlagVizAndWidgetSplit = "vizAndWidgetSplit" FlagVizAndWidgetSplit = "vizAndWidgetSplit"

View File

@@ -1120,7 +1120,8 @@
"metadata": { "metadata": {
"name": "pluginsDynamicAngularDetectionPatterns", "name": "pluginsDynamicAngularDetectionPatterns",
"resourceVersion": "1712639261786", "resourceVersion": "1712639261786",
"creationTimestamp": "2024-04-09T05:07:41Z" "creationTimestamp": "2024-04-09T05:07:41Z",
"deletionTimestamp": "2024-04-11T13:53:48Z"
}, },
"spec": { "spec": {
"description": "Enables fetching Angular detection patterns for plugins from GCOM and fallback to hardcoded ones", "description": "Enables fetching Angular detection patterns for plugins from GCOM and fallback to hardcoded ones",

View File

@@ -14,7 +14,6 @@ import (
"github.com/grafana/grafana/pkg/plugins/log" "github.com/grafana/grafana/pkg/plugins/log"
"github.com/grafana/grafana/pkg/plugins/manager/loader/angular/angulardetector" "github.com/grafana/grafana/pkg/plugins/manager/loader/angular/angulardetector"
"github.com/grafana/grafana/pkg/services/featuremgmt"
"github.com/grafana/grafana/pkg/services/pluginsintegration/angularpatternsstore" "github.com/grafana/grafana/pkg/services/pluginsintegration/angularpatternsstore"
"github.com/grafana/grafana/pkg/setting" "github.com/grafana/grafana/pkg/setting"
) )
@@ -31,10 +30,8 @@ var (
// Dynamic is an angulardetector.DetectorsProvider that calls GCOM to get Angular detection patterns, // Dynamic is an angulardetector.DetectorsProvider that calls GCOM to get Angular detection patterns,
// converts them to detectors and caches them for all future calls. // converts them to detectors and caches them for all future calls.
// It also provides a background service that will periodically refresh the patterns from GCOM. // It also provides a background service that will periodically refresh the patterns from GCOM.
// If the feature flag FlagPluginsDynamicAngularDetectionPatterns is disabled, the background service is disabled.
type Dynamic struct { type Dynamic struct {
log log.Logger log log.Logger
features featuremgmt.FeatureToggles
httpClient http.Client httpClient http.Client
baseURL string baseURL string
@@ -53,7 +50,7 @@ type Dynamic struct {
backgroundJobInterval time.Duration backgroundJobInterval time.Duration
} }
func ProvideDynamic(cfg *setting.Cfg, store angularpatternsstore.Service, features featuremgmt.FeatureToggles) (*Dynamic, error) { func ProvideDynamic(cfg *setting.Cfg, store angularpatternsstore.Service) (*Dynamic, error) {
backgroundJobInterval := backgroundJobIntervalOnPrem backgroundJobInterval := backgroundJobIntervalOnPrem
if cfg.StackID != "" { if cfg.StackID != "" {
// Use a shorter interval for cloud. // Use a shorter interval for cloud.
@@ -63,16 +60,11 @@ func ProvideDynamic(cfg *setting.Cfg, store angularpatternsstore.Service, featur
d := &Dynamic{ d := &Dynamic{
log: log.New("plugin.angulardetectorsprovider.dynamic"), log: log.New("plugin.angulardetectorsprovider.dynamic"),
features: features,
store: store, store: store,
httpClient: makeHttpClient(), httpClient: makeHttpClient(),
baseURL: cfg.GrafanaComURL, baseURL: cfg.GrafanaComURL,
backgroundJobInterval: backgroundJobInterval, backgroundJobInterval: backgroundJobInterval,
} }
if d.IsDisabled() {
// Do not attempt to restore if the background service is disabled (no feature flag)
return d, nil
}
d.log.Debug("Providing dynamic angular detection patterns", "baseURL", d.baseURL, "interval", d.backgroundJobInterval) d.log.Debug("Providing dynamic angular detection patterns", "baseURL", d.baseURL, "interval", d.backgroundJobInterval)
// Perform the initial restore from db // Perform the initial restore from db
@@ -233,11 +225,6 @@ func (d *Dynamic) setDetectorsFromCache(ctx context.Context) error {
return nil return nil
} }
// IsDisabled returns true if FlagPluginsDynamicAngularDetectionPatterns is not enabled.
func (d *Dynamic) IsDisabled() bool {
return !d.features.IsEnabledGlobally(featuremgmt.FlagPluginsDynamicAngularDetectionPatterns)
}
// randomSkew returns a random time.Duration between 0 and maxSkew. // randomSkew returns a random time.Duration between 0 and maxSkew.
// This can be added to d.backgroundJobInterval to skew it by a random amount. // This can be added to d.backgroundJobInterval to skew it by a random amount.
func (d *Dynamic) randomSkew(maxSkew time.Duration) time.Duration { func (d *Dynamic) randomSkew(maxSkew time.Duration) time.Duration {

View File

@@ -15,7 +15,6 @@ import (
"github.com/grafana/grafana/pkg/infra/kvstore" "github.com/grafana/grafana/pkg/infra/kvstore"
"github.com/grafana/grafana/pkg/plugins/manager/loader/angular/angulardetector" "github.com/grafana/grafana/pkg/plugins/manager/loader/angular/angulardetector"
"github.com/grafana/grafana/pkg/services/featuremgmt"
"github.com/grafana/grafana/pkg/services/pluginsintegration/angularpatternsstore" "github.com/grafana/grafana/pkg/services/pluginsintegration/angularpatternsstore"
"github.com/grafana/grafana/pkg/setting" "github.com/grafana/grafana/pkg/setting"
) )
@@ -343,18 +342,6 @@ func TestDynamicAngularDetectorsProviderBackgroundService(t *testing.T) {
backgroundJobIntervalOnPrem = oldBackgroundJobInterval backgroundJobIntervalOnPrem = oldBackgroundJobInterval
}) })
t.Run("is disabled if feature flag is not present", func(t *testing.T) {
svc := provideDynamic(t, srv.URL)
svc.features = featuremgmt.WithFeatures()
require.True(t, svc.IsDisabled(), "background service should be disabled")
})
t.Run("is enabled if feature flag is present", func(t *testing.T) {
svc := provideDynamic(t, srv.URL)
svc.features = featuremgmt.WithFeatures(featuremgmt.FlagPluginsDynamicAngularDetectionPatterns)
require.False(t, svc.IsDisabled(), "background service should be enabled")
})
t.Run("fetches value from gcom on start if too much time has passed", func(t *testing.T) { t.Run("fetches value from gcom on start if too much time has passed", func(t *testing.T) {
gcomCallback := make(chan struct{}) gcomCallback := make(chan struct{})
gcom := newDefaultGCOMScenario(func(_ http.ResponseWriter, _ *http.Request) { gcom := newDefaultGCOMScenario(func(_ http.ResponseWriter, _ *http.Request) {
@@ -594,11 +581,7 @@ func provideDynamic(t *testing.T, gcomURL string, opts ...provideDynamicOpts) *D
opt.cfg = setting.NewCfg() opt.cfg = setting.NewCfg()
} }
opt.cfg.GrafanaComURL = gcomURL opt.cfg.GrafanaComURL = gcomURL
d, err := ProvideDynamic( d, err := ProvideDynamic(opt.cfg, opt.store)
opt.cfg,
opt.store,
featuremgmt.WithFeatures(featuremgmt.FlagPluginsDynamicAngularDetectionPatterns),
)
require.NoError(t, err) require.NoError(t, err)
return d return d
} }

View File

@@ -3,7 +3,6 @@ package angularinspector
import ( import (
"github.com/grafana/grafana/pkg/plugins/manager/loader/angular/angulardetector" "github.com/grafana/grafana/pkg/plugins/manager/loader/angular/angulardetector"
"github.com/grafana/grafana/pkg/plugins/manager/loader/angular/angularinspector" "github.com/grafana/grafana/pkg/plugins/manager/loader/angular/angularinspector"
"github.com/grafana/grafana/pkg/services/featuremgmt"
"github.com/grafana/grafana/pkg/services/pluginsintegration/angulardetectorsprovider" "github.com/grafana/grafana/pkg/services/pluginsintegration/angulardetectorsprovider"
) )
@@ -11,17 +10,13 @@ type Service struct {
angularinspector.Inspector angularinspector.Inspector
} }
func ProvideService(features featuremgmt.FeatureToggles, dynamic *angulardetectorsprovider.Dynamic) (*Service, error) { func ProvideService(dynamic *angulardetectorsprovider.Dynamic) (*Service, error) {
var detectorsProvider angulardetector.DetectorsProvider return &Service{
var err error Inspector: angularinspector.NewPatternListInspector(
static := angularinspector.NewDefaultStaticDetectorsProvider() angulardetector.SequenceDetectorsProvider{
if features.IsEnabledGlobally(featuremgmt.FlagPluginsDynamicAngularDetectionPatterns) { dynamic,
detectorsProvider = angulardetector.SequenceDetectorsProvider{dynamic, static} angularinspector.NewDefaultStaticDetectorsProvider(),
} else { },
detectorsProvider = static ),
} }, nil
if err != nil {
return nil, err
}
return &Service{Inspector: angularinspector.NewPatternListInspector(detectorsProvider)}, nil
} }

View File

@@ -9,40 +9,19 @@ import (
"github.com/grafana/grafana/pkg/infra/kvstore" "github.com/grafana/grafana/pkg/infra/kvstore"
"github.com/grafana/grafana/pkg/plugins/manager/loader/angular/angulardetector" "github.com/grafana/grafana/pkg/plugins/manager/loader/angular/angulardetector"
"github.com/grafana/grafana/pkg/plugins/manager/loader/angular/angularinspector" "github.com/grafana/grafana/pkg/plugins/manager/loader/angular/angularinspector"
"github.com/grafana/grafana/pkg/services/featuremgmt"
"github.com/grafana/grafana/pkg/services/pluginsintegration/angulardetectorsprovider" "github.com/grafana/grafana/pkg/services/pluginsintegration/angulardetectorsprovider"
"github.com/grafana/grafana/pkg/services/pluginsintegration/angularpatternsstore" "github.com/grafana/grafana/pkg/services/pluginsintegration/angularpatternsstore"
"github.com/grafana/grafana/pkg/setting" "github.com/grafana/grafana/pkg/setting"
) )
func TestProvideService(t *testing.T) { func TestProvideService(t *testing.T) {
t.Run("uses hardcoded inspector if feature flag is not present", func(t *testing.T) { t.Run("uses dynamic inspector with hardcoded fallback", func(t *testing.T) {
features := featuremgmt.WithFeatures()
dynamic, err := angulardetectorsprovider.ProvideDynamic( dynamic, err := angulardetectorsprovider.ProvideDynamic(
setting.NewCfg(), setting.NewCfg(),
angularpatternsstore.ProvideService(kvstore.NewFakeKVStore()), angularpatternsstore.ProvideService(kvstore.NewFakeKVStore()),
features,
) )
require.NoError(t, err) require.NoError(t, err)
inspector, err := ProvideService(features, dynamic) inspector, err := ProvideService(dynamic)
require.NoError(t, err)
require.IsType(t, inspector.Inspector, &angularinspector.PatternsListInspector{})
patternsListInspector := inspector.Inspector.(*angularinspector.PatternsListInspector)
detectors := patternsListInspector.DetectorsProvider.ProvideDetectors(context.Background())
require.NotEmpty(t, detectors, "provided detectors should not be empty")
})
t.Run("uses dynamic inspector with hardcoded fallback if feature flag is present", func(t *testing.T) {
features := featuremgmt.WithFeatures(
featuremgmt.FlagPluginsDynamicAngularDetectionPatterns,
)
dynamic, err := angulardetectorsprovider.ProvideDynamic(
setting.NewCfg(),
angularpatternsstore.ProvideService(kvstore.NewFakeKVStore()),
features,
)
require.NoError(t, err)
inspector, err := ProvideService(features, dynamic)
require.NoError(t, err) require.NoError(t, err)
require.IsType(t, inspector.Inspector, &angularinspector.PatternsListInspector{}) require.IsType(t, inspector.Inspector, &angularinspector.PatternsListInspector{})
require.IsType(t, inspector.Inspector.(*angularinspector.PatternsListInspector).DetectorsProvider, angulardetector.SequenceDetectorsProvider{}) require.IsType(t, inspector.Inspector.(*angularinspector.PatternsListInspector).DetectorsProvider, angulardetector.SequenceDetectorsProvider{})