| 
									
										
										
										
											2024-01-18 18:06:33 +08:00
										 |  |  | package renderer | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | import ( | 
					
						
							|  |  |  | 	"context" | 
					
						
							|  |  |  | 	"path/filepath" | 
					
						
							|  |  |  | 	"strings" | 
					
						
							|  |  |  | 	"testing" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	"github.com/stretchr/testify/require" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	"github.com/grafana/grafana/pkg/plugins" | 
					
						
							| 
									
										
										
										
											2024-03-11 23:28:46 +08:00
										 |  |  | 	"github.com/grafana/grafana/pkg/plugins/config" | 
					
						
							| 
									
										
										
										
											2024-01-18 18:06:33 +08:00
										 |  |  | 	"github.com/grafana/grafana/pkg/plugins/manager/fakes" | 
					
						
							| 
									
										
										
										
											2025-06-19 17:28:23 +08:00
										 |  |  | 	"github.com/grafana/grafana/pkg/plugins/manager/sources" | 
					
						
							| 
									
										
										
										
											2024-01-18 18:06:33 +08:00
										 |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func TestRenderer(t *testing.T) { | 
					
						
							|  |  |  | 	t.Run("Test Renderer will treat directories under plugins path as individual sources", func(t *testing.T) { | 
					
						
							|  |  |  | 		testdataDir := filepath.Join("testdata", "plugins") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		numLoaded := 0 | 
					
						
							|  |  |  | 		numUnloaded := 0 | 
					
						
							|  |  |  | 		loader := &fakes.FakeLoader{ | 
					
						
							|  |  |  | 			LoadFunc: func(ctx context.Context, src plugins.PluginSource) ([]*plugins.Plugin, error) { | 
					
						
							|  |  |  | 				require.True(t, src.PluginClass(ctx) == plugins.ClassExternal) | 
					
						
							| 
									
										
										
										
											2025-06-19 17:28:23 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 				if localSrc, ok := src.(*sources.LocalSource); ok { | 
					
						
							|  |  |  | 					paths := localSrc.Paths() | 
					
						
							|  |  |  | 					require.Len(t, paths, 1) | 
					
						
							|  |  |  | 					require.True(t, strings.HasPrefix(paths[0], testdataDir)) | 
					
						
							|  |  |  | 				} else { | 
					
						
							|  |  |  | 					t.Fatalf("Expected LocalSource, got %T", src) | 
					
						
							|  |  |  | 				} | 
					
						
							| 
									
										
										
										
											2024-01-18 18:06:33 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 				numLoaded++ | 
					
						
							|  |  |  | 				return []*plugins.Plugin{}, nil | 
					
						
							|  |  |  | 			}, | 
					
						
							|  |  |  | 			UnloadFunc: func(_ context.Context, _ *plugins.Plugin) (*plugins.Plugin, error) { | 
					
						
							|  |  |  | 				numUnloaded++ | 
					
						
							|  |  |  | 				return nil, nil | 
					
						
							|  |  |  | 			}, | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2024-03-11 23:28:46 +08:00
										 |  |  | 		cfg := &config.PluginManagementCfg{PluginsPath: filepath.Join(testdataDir)} | 
					
						
							| 
									
										
										
										
											2024-01-18 18:06:33 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		m := NewManager(cfg, loader) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		r, exists := m.Renderer(context.Background()) | 
					
						
							|  |  |  | 		require.False(t, exists) | 
					
						
							| 
									
										
										
										
											2025-03-20 18:00:59 +08:00
										 |  |  | 		require.Equal(t, 3, numLoaded) | 
					
						
							| 
									
										
										
										
											2024-01-18 18:06:33 +08:00
										 |  |  | 		require.Equal(t, 0, numUnloaded) | 
					
						
							|  |  |  | 		require.Nil(t, r) | 
					
						
							|  |  |  | 	}) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	t.Run("Test Renderer load all directories until a plugin is returned", func(t *testing.T) { | 
					
						
							|  |  |  | 		testdataDir := filepath.Join("testdata", "plugins") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		numLoaded := 0 | 
					
						
							|  |  |  | 		numUnloaded := 0 | 
					
						
							|  |  |  | 		p := &plugins.Plugin{ | 
					
						
							|  |  |  | 			JSONData: plugins.JSONData{ID: "test"}, | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		loader := &fakes.FakeLoader{ | 
					
						
							|  |  |  | 			LoadFunc: func(ctx context.Context, src plugins.PluginSource) ([]*plugins.Plugin, error) { | 
					
						
							|  |  |  | 				numLoaded++ | 
					
						
							| 
									
										
										
										
											2025-06-19 17:28:23 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 				if localSrc, ok := src.(*sources.LocalSource); ok { | 
					
						
							|  |  |  | 					paths := localSrc.Paths() | 
					
						
							|  |  |  | 					if strings.HasPrefix(paths[0], filepath.Join(testdataDir, "renderer")) { | 
					
						
							|  |  |  | 						return []*plugins.Plugin{p}, nil | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 				} else { | 
					
						
							|  |  |  | 					t.Fatalf("Expected LocalSource, got %T", src) | 
					
						
							| 
									
										
										
										
											2024-01-18 18:06:33 +08:00
										 |  |  | 				} | 
					
						
							| 
									
										
										
										
											2025-06-19 17:28:23 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-01-18 18:06:33 +08:00
										 |  |  | 				return []*plugins.Plugin{}, nil | 
					
						
							|  |  |  | 			}, | 
					
						
							|  |  |  | 			UnloadFunc: func(_ context.Context, _ *plugins.Plugin) (*plugins.Plugin, error) { | 
					
						
							|  |  |  | 				numUnloaded++ | 
					
						
							|  |  |  | 				return nil, nil | 
					
						
							|  |  |  | 			}, | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2024-03-11 23:28:46 +08:00
										 |  |  | 		cfg := &config.PluginManagementCfg{PluginsPath: filepath.Join(testdataDir)} | 
					
						
							| 
									
										
										
										
											2024-01-18 18:06:33 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		m := NewManager(cfg, loader) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		r, exists := m.Renderer(context.Background()) | 
					
						
							|  |  |  | 		require.True(t, exists) | 
					
						
							|  |  |  | 		require.Equal(t, 3, numLoaded) | 
					
						
							|  |  |  | 		require.Equal(t, 0, numUnloaded) | 
					
						
							|  |  |  | 		require.NotNil(t, r) | 
					
						
							|  |  |  | 	}) | 
					
						
							|  |  |  | } |