provisioning_test.go 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  1. package provisioning
  2. import (
  3. "context"
  4. "errors"
  5. "testing"
  6. "time"
  7. "github.com/grafana/grafana/pkg/services/provisioning/dashboards"
  8. "github.com/grafana/grafana/pkg/setting"
  9. "github.com/stretchr/testify/assert"
  10. )
  11. func TestProvisioningServiceImpl(t *testing.T) {
  12. t.Run("Restart dashboard provisioning and stop service", func(t *testing.T) {
  13. serviceTest := setup()
  14. err := serviceTest.service.ProvisionDashboards()
  15. assert.Nil(t, err)
  16. serviceTest.startService()
  17. serviceTest.waitForPollChanges()
  18. assert.Equal(t, 1, len(serviceTest.mock.Calls.PollChanges), "PollChanges should have been called")
  19. err = serviceTest.service.ProvisionDashboards()
  20. assert.Nil(t, err)
  21. serviceTest.waitForPollChanges()
  22. assert.Equal(t, 2, len(serviceTest.mock.Calls.PollChanges), "PollChanges should have been called 2 times")
  23. pollingCtx := serviceTest.mock.Calls.PollChanges[0].(context.Context)
  24. assert.Equal(t, context.Canceled, pollingCtx.Err(), "Polling context from first call should have been cancelled")
  25. assert.True(t, serviceTest.serviceRunning, "Service should be still running")
  26. // Cancelling the root context and stopping the service
  27. serviceTest.cancel()
  28. serviceTest.waitForStop()
  29. assert.False(t, serviceTest.serviceRunning, "Service should not be running")
  30. assert.Equal(t, context.Canceled, serviceTest.serviceError, "Service should have returned canceled error")
  31. })
  32. t.Run("Failed reloading does not stop polling with old provisioned", func(t *testing.T) {
  33. serviceTest := setup()
  34. err := serviceTest.service.ProvisionDashboards()
  35. assert.Nil(t, err)
  36. serviceTest.startService()
  37. serviceTest.waitForPollChanges()
  38. assert.Equal(t, 1, len(serviceTest.mock.Calls.PollChanges), "PollChanges should have been called")
  39. serviceTest.mock.ProvisionFunc = func() error {
  40. return errors.New("Test error")
  41. }
  42. err = serviceTest.service.ProvisionDashboards()
  43. assert.NotNil(t, err)
  44. serviceTest.waitForPollChanges()
  45. // This should have been called with the old provisioner, after the last one failed.
  46. assert.Equal(t, 2, len(serviceTest.mock.Calls.PollChanges), "PollChanges should have been called 2 times")
  47. assert.True(t, serviceTest.serviceRunning, "Service should be still running")
  48. // Cancelling the root context and stopping the service
  49. serviceTest.cancel()
  50. })
  51. }
  52. type serviceTestStruct struct {
  53. waitForPollChanges func()
  54. waitForStop func()
  55. waitTimeout time.Duration
  56. serviceRunning bool
  57. serviceError error
  58. startService func()
  59. cancel func()
  60. mock *dashboards.DashboardProvisionerMock
  61. service *provisioningServiceImpl
  62. }
  63. func setup() *serviceTestStruct {
  64. serviceTest := &serviceTestStruct{}
  65. serviceTest.waitTimeout = time.Second
  66. pollChangesChannel := make(chan context.Context)
  67. serviceStopped := make(chan interface{})
  68. serviceTest.mock = dashboards.NewDashboardProvisionerMock()
  69. serviceTest.mock.PollChangesFunc = func(ctx context.Context) {
  70. pollChangesChannel <- ctx
  71. }
  72. serviceTest.service = NewProvisioningServiceImpl(
  73. func(path string) (DashboardProvisioner, error) {
  74. return serviceTest.mock, nil
  75. },
  76. nil,
  77. nil,
  78. )
  79. serviceTest.service.Cfg = setting.NewCfg()
  80. ctx, cancel := context.WithCancel(context.Background())
  81. serviceTest.cancel = cancel
  82. serviceTest.startService = func() {
  83. go func() {
  84. serviceTest.serviceRunning = true
  85. serviceTest.serviceError = serviceTest.service.Run(ctx)
  86. serviceTest.serviceRunning = false
  87. serviceStopped <- true
  88. }()
  89. }
  90. serviceTest.waitForPollChanges = func() {
  91. timeoutChan := time.After(serviceTest.waitTimeout)
  92. select {
  93. case <-pollChangesChannel:
  94. case <-timeoutChan:
  95. }
  96. }
  97. serviceTest.waitForStop = func() {
  98. timeoutChan := time.After(serviceTest.waitTimeout)
  99. select {
  100. case <-serviceStopped:
  101. case <-timeoutChan:
  102. }
  103. }
  104. return serviceTest
  105. }