| 
									
										
										
										
											2023-02-28 22:27:11 +08:00
										 |  |  | package sources | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | import ( | 
					
						
							|  |  |  | 	"context" | 
					
						
							| 
									
										
										
										
											2023-12-19 18:01:48 +08:00
										 |  |  | 	"path/filepath" | 
					
						
							| 
									
										
										
										
											2023-02-28 22:27:11 +08:00
										 |  |  | 	"testing" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	"github.com/stretchr/testify/require" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	"github.com/grafana/grafana/pkg/plugins" | 
					
						
							| 
									
										
										
										
											2025-06-19 17:28:23 +08:00
										 |  |  | 	"github.com/grafana/grafana/pkg/plugins/config" | 
					
						
							| 
									
										
										
										
											2023-02-28 22:27:11 +08:00
										 |  |  | 	"github.com/grafana/grafana/pkg/setting" | 
					
						
							|  |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func TestSources_List(t *testing.T) { | 
					
						
							| 
									
										
										
										
											2023-03-20 21:35:49 +08:00
										 |  |  | 	t.Run("Plugin sources are populated by default and listed in specific order", func(t *testing.T) { | 
					
						
							| 
									
										
										
										
											2024-01-08 18:45:03 +08:00
										 |  |  | 		testdata, err := filepath.Abs("../testdata") | 
					
						
							|  |  |  | 		require.NoError(t, err) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-02-28 22:27:11 +08:00
										 |  |  | 		cfg := &setting.Cfg{ | 
					
						
							| 
									
										
										
										
											2025-01-14 20:04:01 +08:00
										 |  |  | 			StaticRootPath: testdata, | 
					
						
							| 
									
										
										
										
											2025-06-19 17:28:23 +08:00
										 |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		pCfg := &config.PluginManagementCfg{ | 
					
						
							|  |  |  | 			PluginsPath: filepath.Join(testdata, "pluginRootWithDist"), | 
					
						
							| 
									
										
										
										
											2023-02-28 22:27:11 +08:00
										 |  |  | 			PluginSettings: setting.PluginSettings{ | 
					
						
							|  |  |  | 				"foo": map[string]string{ | 
					
						
							| 
									
										
										
										
											2024-01-08 18:45:03 +08:00
										 |  |  | 					"path": filepath.Join(testdata, "test-app"), | 
					
						
							| 
									
										
										
										
											2023-02-28 22:27:11 +08:00
										 |  |  | 				}, | 
					
						
							|  |  |  | 				"bar": map[string]string{ | 
					
						
							|  |  |  | 					"url": "https://grafana.plugin", | 
					
						
							|  |  |  | 				}, | 
					
						
							|  |  |  | 			}, | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-06-19 17:28:23 +08:00
										 |  |  | 		s := ProvideService(cfg, pCfg) | 
					
						
							| 
									
										
										
										
											2023-02-28 22:27:11 +08:00
										 |  |  | 		srcs := s.List(context.Background()) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-03-20 21:35:49 +08:00
										 |  |  | 		ctx := context.Background() | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-01-14 20:04:01 +08:00
										 |  |  | 		require.Len(t, srcs, 5) | 
					
						
							| 
									
										
										
										
											2023-03-20 21:35:49 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-06-08 18:21:19 +08:00
										 |  |  | 		require.Equal(t, srcs[0].PluginClass(ctx), plugins.ClassCore) | 
					
						
							| 
									
										
										
										
											2025-06-19 17:28:23 +08:00
										 |  |  | 		if localSrc, ok := srcs[0].(*LocalSource); ok { | 
					
						
							|  |  |  | 			require.Equal(t, localSrc.Paths(), []string{ | 
					
						
							|  |  |  | 				filepath.Join(testdata, "app", "plugins", "datasource"), | 
					
						
							|  |  |  | 				filepath.Join(testdata, "app", "plugins", "panel"), | 
					
						
							|  |  |  | 			}) | 
					
						
							|  |  |  | 		} else { | 
					
						
							|  |  |  | 			t.Fatalf("Expected LocalSource, got %T", srcs[0]) | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2025-02-19 19:19:45 +08:00
										 |  |  | 		sig, exists := srcs[0].DefaultSignature(ctx, "") | 
					
						
							| 
									
										
										
										
											2023-03-20 21:35:49 +08:00
										 |  |  | 		require.True(t, exists) | 
					
						
							| 
									
										
										
										
											2023-06-08 18:21:19 +08:00
										 |  |  | 		require.Equal(t, plugins.SignatureStatusInternal, sig.Status) | 
					
						
							| 
									
										
										
										
											2023-03-20 21:35:49 +08:00
										 |  |  | 		require.Equal(t, plugins.SignatureType(""), sig.Type) | 
					
						
							|  |  |  | 		require.Equal(t, "", sig.SigningOrg) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-01-14 20:04:01 +08:00
										 |  |  | 		require.Equal(t, srcs[1].PluginClass(ctx), plugins.ClassExternal) | 
					
						
							| 
									
										
										
										
											2025-06-19 17:28:23 +08:00
										 |  |  | 		if localSrc, ok := srcs[1].(*LocalSource); ok { | 
					
						
							|  |  |  | 			require.Equal(t, localSrc.Paths(), []string{ | 
					
						
							|  |  |  | 				filepath.Join(testdata, "pluginRootWithDist", "datasource"), | 
					
						
							|  |  |  | 			}) | 
					
						
							|  |  |  | 		} else { | 
					
						
							|  |  |  | 			t.Fatalf("Expected LocalSource, got %T", srcs[1]) | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2025-02-19 19:19:45 +08:00
										 |  |  | 		sig, exists = srcs[1].DefaultSignature(ctx, "") | 
					
						
							| 
									
										
										
										
											2023-03-20 21:35:49 +08:00
										 |  |  | 		require.False(t, exists) | 
					
						
							|  |  |  | 		require.Equal(t, plugins.Signature{}, sig) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-06-08 18:21:19 +08:00
										 |  |  | 		require.Equal(t, srcs[2].PluginClass(ctx), plugins.ClassExternal) | 
					
						
							| 
									
										
										
										
											2025-06-19 17:28:23 +08:00
										 |  |  | 		if localSrc, ok := srcs[2].(*LocalSource); ok { | 
					
						
							|  |  |  | 			require.Equal(t, localSrc.Paths(), []string{ | 
					
						
							|  |  |  | 				filepath.Join(testdata, "pluginRootWithDist", "dist"), | 
					
						
							|  |  |  | 			}) | 
					
						
							|  |  |  | 		} else { | 
					
						
							|  |  |  | 			t.Fatalf("Expected LocalSource, got %T", srcs[2]) | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2025-02-19 19:19:45 +08:00
										 |  |  | 		sig, exists = srcs[2].DefaultSignature(ctx, "") | 
					
						
							| 
									
										
										
										
											2023-03-20 21:35:49 +08:00
										 |  |  | 		require.False(t, exists) | 
					
						
							|  |  |  | 		require.Equal(t, plugins.Signature{}, sig) | 
					
						
							| 
									
										
										
										
											2024-01-08 18:45:03 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		require.Equal(t, srcs[3].PluginClass(ctx), plugins.ClassExternal) | 
					
						
							| 
									
										
										
										
											2025-06-19 17:28:23 +08:00
										 |  |  | 		if localSrc, ok := srcs[3].(*LocalSource); ok { | 
					
						
							|  |  |  | 			require.Equal(t, localSrc.Paths(), []string{ | 
					
						
							|  |  |  | 				filepath.Join(testdata, "pluginRootWithDist", "panel"), | 
					
						
							|  |  |  | 			}) | 
					
						
							|  |  |  | 		} else { | 
					
						
							|  |  |  | 			t.Fatalf("Expected LocalSource, got %T", srcs[3]) | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2025-02-19 19:19:45 +08:00
										 |  |  | 		sig, exists = srcs[3].DefaultSignature(ctx, "") | 
					
						
							| 
									
										
										
										
											2024-01-08 18:45:03 +08:00
										 |  |  | 		require.False(t, exists) | 
					
						
							|  |  |  | 		require.Equal(t, plugins.Signature{}, sig) | 
					
						
							| 
									
										
										
										
											2023-02-28 22:27:11 +08:00
										 |  |  | 	}) | 
					
						
							| 
									
										
										
										
											2024-01-09 21:23:03 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	t.Run("Plugin sources are populated with symbolic links", func(t *testing.T) { | 
					
						
							|  |  |  | 		testdata, err := filepath.Abs("../testdata") | 
					
						
							|  |  |  | 		require.NoError(t, err) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		cfg := &setting.Cfg{ | 
					
						
							| 
									
										
										
										
											2025-01-14 20:04:01 +08:00
										 |  |  | 			StaticRootPath: testdata, | 
					
						
							| 
									
										
										
										
											2024-01-09 21:23:03 +08:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2025-06-19 17:28:23 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		pCfg := &config.PluginManagementCfg{ | 
					
						
							|  |  |  | 			PluginsPath: filepath.Join(testdata, "symbolic-plugin-dirs"), | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		s := ProvideService(cfg, pCfg) | 
					
						
							| 
									
										
										
										
											2024-01-09 21:23:03 +08:00
										 |  |  | 		ctx := context.Background() | 
					
						
							|  |  |  | 		srcs := s.List(ctx) | 
					
						
							|  |  |  | 		uris := map[plugins.Class]map[string]struct{}{} | 
					
						
							| 
									
										
										
										
											2025-06-19 17:28:23 +08:00
										 |  |  | 		for _, src := range srcs { | 
					
						
							|  |  |  | 			class := src.PluginClass(ctx) | 
					
						
							| 
									
										
										
										
											2024-01-09 21:23:03 +08:00
										 |  |  | 			if _, exists := uris[class]; !exists { | 
					
						
							|  |  |  | 				uris[class] = map[string]struct{}{} | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2025-06-19 17:28:23 +08:00
										 |  |  | 			if localSrc, ok := src.(*LocalSource); ok { | 
					
						
							|  |  |  | 				for _, path := range localSrc.Paths() { | 
					
						
							|  |  |  | 					uris[class][path] = struct{}{} | 
					
						
							|  |  |  | 				} | 
					
						
							| 
									
										
										
										
											2024-01-09 21:23:03 +08:00
										 |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		require.Equal(t, uris[plugins.ClassCore], map[string]struct{}{ | 
					
						
							|  |  |  | 			filepath.Join(testdata, "app", "plugins", "datasource"): {}, | 
					
						
							|  |  |  | 			filepath.Join(testdata, "app", "plugins", "panel"):      {}, | 
					
						
							|  |  |  | 		}, "should include core plugins") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		require.Equal(t, uris[plugins.ClassExternal], map[string]struct{}{ | 
					
						
							|  |  |  | 			filepath.Join(testdata, "symbolic-plugin-dirs", "plugin"): {}, | 
					
						
							|  |  |  | 		}, "should include external symlinked plugin") | 
					
						
							|  |  |  | 	}) | 
					
						
							| 
									
										
										
										
											2023-02-28 22:27:11 +08:00
										 |  |  | } |