github.com/juju/juju@v0.0.0-20240430160146-1752b71fcf00/worker/agentconfigupdater/worker_test.go (about)

     1  // Copyright 2019 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package agentconfigupdater_test
     5  
     6  import (
     7  	"time"
     8  
     9  	"github.com/juju/errors"
    10  	"github.com/juju/loggo"
    11  	"github.com/juju/pubsub/v2"
    12  	"github.com/juju/testing"
    13  	jc "github.com/juju/testing/checkers"
    14  	"github.com/juju/worker/v3/workertest"
    15  	gc "gopkg.in/check.v1"
    16  
    17  	"github.com/juju/juju/controller"
    18  	controllermsg "github.com/juju/juju/pubsub/controller"
    19  	jworker "github.com/juju/juju/worker"
    20  	"github.com/juju/juju/worker/agentconfigupdater"
    21  )
    22  
    23  type WorkerSuite struct {
    24  	testing.IsolationSuite
    25  	logger loggo.Logger
    26  	agent  *mockAgent
    27  	hub    *pubsub.StructuredHub
    28  	config agentconfigupdater.WorkerConfig
    29  
    30  	initialConfigMsg controllermsg.ConfigChangedMessage
    31  }
    32  
    33  var _ = gc.Suite(&WorkerSuite{})
    34  
    35  func (s *WorkerSuite) SetUpTest(c *gc.C) {
    36  	s.IsolationSuite.SetUpTest(c)
    37  	s.logger = loggo.GetLogger("test")
    38  	s.hub = pubsub.NewStructuredHub(&pubsub.StructuredHubConfig{
    39  		Logger: s.logger,
    40  	})
    41  	s.agent = &mockAgent{
    42  		conf: mockConfig{
    43  			profile:               controller.DefaultMongoMemoryProfile,
    44  			snapChannel:           controller.DefaultJujuDBSnapChannel,
    45  			queryTracingEnabled:   controller.DefaultQueryTracingEnabled,
    46  			queryTracingThreshold: controller.DefaultQueryTracingThreshold,
    47  		},
    48  	}
    49  	s.config = agentconfigupdater.WorkerConfig{
    50  		Agent:                 s.agent,
    51  		Hub:                   s.hub,
    52  		MongoProfile:          controller.DefaultMongoMemoryProfile,
    53  		JujuDBSnapChannel:     controller.DefaultJujuDBSnapChannel,
    54  		QueryTracingEnabled:   controller.DefaultQueryTracingEnabled,
    55  		QueryTracingThreshold: controller.DefaultQueryTracingThreshold,
    56  		Logger:                s.logger,
    57  	}
    58  	s.initialConfigMsg = controllermsg.ConfigChangedMessage{
    59  		Config: controller.Config{
    60  			controller.MongoMemoryProfile:    controller.DefaultMongoMemoryProfile,
    61  			controller.JujuDBSnapChannel:     controller.DefaultJujuDBSnapChannel,
    62  			controller.QueryTracingEnabled:   controller.DefaultQueryTracingEnabled,
    63  			controller.QueryTracingThreshold: controller.DefaultQueryTracingThreshold,
    64  		},
    65  	}
    66  }
    67  
    68  func (s *WorkerSuite) TestWorkerConfig(c *gc.C) {
    69  	for i, test := range []struct {
    70  		name      string
    71  		config    func() agentconfigupdater.WorkerConfig
    72  		expectErr string
    73  	}{
    74  		{
    75  			name:   "valid config",
    76  			config: func() agentconfigupdater.WorkerConfig { return s.config },
    77  		}, {
    78  			name: "missing agent",
    79  			config: func() agentconfigupdater.WorkerConfig {
    80  				result := s.config
    81  				result.Agent = nil
    82  				return result
    83  			},
    84  			expectErr: "missing agent not valid",
    85  		}, {
    86  			name: "missing hub",
    87  			config: func() agentconfigupdater.WorkerConfig {
    88  				result := s.config
    89  				result.Hub = nil
    90  				return result
    91  			},
    92  			expectErr: "missing hub not valid",
    93  		}, {
    94  			name: "missing logger",
    95  			config: func() agentconfigupdater.WorkerConfig {
    96  				result := s.config
    97  				result.Logger = nil
    98  				return result
    99  			},
   100  			expectErr: "missing logger not valid",
   101  		},
   102  	} {
   103  		s.logger.Infof("%d: %s", i, test.name)
   104  		config := test.config()
   105  		err := config.Validate()
   106  		if test.expectErr == "" {
   107  			c.Check(err, jc.ErrorIsNil)
   108  		} else {
   109  			c.Check(err, jc.Satisfies, errors.IsNotValid)
   110  			c.Check(err, gc.ErrorMatches, test.expectErr)
   111  		}
   112  	}
   113  }
   114  
   115  func (s *WorkerSuite) TestNewWorkerValidatesConfig(c *gc.C) {
   116  	config := s.config
   117  	config.Agent = nil
   118  	w, err := agentconfigupdater.NewWorker(config)
   119  	c.Assert(w, gc.IsNil)
   120  	c.Check(err, jc.Satisfies, errors.IsNotValid)
   121  }
   122  
   123  func (s *WorkerSuite) TestNormalStart(c *gc.C) {
   124  	w, err := agentconfigupdater.NewWorker(s.config)
   125  	c.Assert(w, gc.NotNil)
   126  	c.Check(err, jc.ErrorIsNil)
   127  	workertest.CleanKill(c, w)
   128  }
   129  
   130  func (s *WorkerSuite) TestUpdateMongoProfile(c *gc.C) {
   131  	w, err := agentconfigupdater.NewWorker(s.config)
   132  	c.Assert(w, gc.NotNil)
   133  	c.Check(err, jc.ErrorIsNil)
   134  
   135  	newConfig := s.initialConfigMsg
   136  	handled, err := s.hub.Publish(controllermsg.ConfigChanged, newConfig)
   137  	c.Assert(err, jc.ErrorIsNil)
   138  	select {
   139  	case <-pubsub.Wait(handled):
   140  	case <-time.After(testing.LongWait):
   141  		c.Fatalf("event not handled")
   142  	}
   143  
   144  	// Profile the same, worker still alive.
   145  	workertest.CheckAlive(c, w)
   146  
   147  	newConfig.Config[controller.MongoMemoryProfile] = "new-value"
   148  	handled, err = s.hub.Publish(controllermsg.ConfigChanged, newConfig)
   149  	c.Assert(err, jc.ErrorIsNil)
   150  	select {
   151  	case <-pubsub.Wait(handled):
   152  	case <-time.After(testing.LongWait):
   153  		c.Fatalf("event not handled")
   154  	}
   155  
   156  	err = workertest.CheckKilled(c, w)
   157  
   158  	c.Assert(err, gc.Equals, jworker.ErrRestartAgent)
   159  }
   160  
   161  func (s *WorkerSuite) TestUpdateJujuDBSnapChannel(c *gc.C) {
   162  	w, err := agentconfigupdater.NewWorker(s.config)
   163  	c.Assert(w, gc.NotNil)
   164  	c.Check(err, jc.ErrorIsNil)
   165  
   166  	newConfig := s.initialConfigMsg
   167  	handled, err := s.hub.Publish(controllermsg.ConfigChanged, newConfig)
   168  	c.Assert(err, jc.ErrorIsNil)
   169  	select {
   170  	case <-pubsub.Wait(handled):
   171  	case <-time.After(testing.LongWait):
   172  		c.Fatalf("event not handled")
   173  	}
   174  
   175  	// Snap channel is the same, worker still alive.
   176  	workertest.CheckAlive(c, w)
   177  
   178  	newConfig.Config[controller.JujuDBSnapChannel] = "latest/candidate"
   179  	handled, err = s.hub.Publish(controllermsg.ConfigChanged, newConfig)
   180  	c.Assert(err, jc.ErrorIsNil)
   181  	select {
   182  	case <-pubsub.Wait(handled):
   183  	case <-time.After(testing.LongWait):
   184  		c.Fatalf("event not handled")
   185  	}
   186  
   187  	err = workertest.CheckKilled(c, w)
   188  
   189  	c.Assert(err, gc.Equals, jworker.ErrRestartAgent)
   190  }
   191  
   192  func (s *WorkerSuite) TestUpdateQueryTracingEnabled(c *gc.C) {
   193  	w, err := agentconfigupdater.NewWorker(s.config)
   194  	c.Assert(w, gc.NotNil)
   195  	c.Check(err, jc.ErrorIsNil)
   196  
   197  	newConfig := s.initialConfigMsg
   198  	handled, err := s.hub.Publish(controllermsg.ConfigChanged, newConfig)
   199  	c.Assert(err, jc.ErrorIsNil)
   200  	select {
   201  	case <-pubsub.Wait(handled):
   202  	case <-time.After(testing.LongWait):
   203  		c.Fatalf("event not handled")
   204  	}
   205  
   206  	// Query tracing enabled is the same, worker still alive.
   207  	workertest.CheckAlive(c, w)
   208  
   209  	newConfig.Config[controller.QueryTracingEnabled] = true
   210  	handled, err = s.hub.Publish(controllermsg.ConfigChanged, newConfig)
   211  	c.Assert(err, jc.ErrorIsNil)
   212  	select {
   213  	case <-pubsub.Wait(handled):
   214  	case <-time.After(testing.LongWait):
   215  		c.Fatalf("event not handled")
   216  	}
   217  
   218  	err = workertest.CheckKilled(c, w)
   219  
   220  	c.Assert(err, gc.Equals, jworker.ErrRestartAgent)
   221  }
   222  
   223  func (s *WorkerSuite) TestUpdateQueryTracingThreshold(c *gc.C) {
   224  	w, err := agentconfigupdater.NewWorker(s.config)
   225  	c.Assert(w, gc.NotNil)
   226  	c.Check(err, jc.ErrorIsNil)
   227  
   228  	newConfig := s.initialConfigMsg
   229  	handled, err := s.hub.Publish(controllermsg.ConfigChanged, newConfig)
   230  	c.Assert(err, jc.ErrorIsNil)
   231  	select {
   232  	case <-pubsub.Wait(handled):
   233  	case <-time.After(testing.LongWait):
   234  		c.Fatalf("event not handled")
   235  	}
   236  
   237  	// Query tracing threshold is the same, worker still alive.
   238  	workertest.CheckAlive(c, w)
   239  
   240  	d := time.Second * 2
   241  	newConfig.Config[controller.QueryTracingThreshold] = d.String()
   242  	handled, err = s.hub.Publish(controllermsg.ConfigChanged, newConfig)
   243  	c.Assert(err, jc.ErrorIsNil)
   244  	select {
   245  	case <-pubsub.Wait(handled):
   246  	case <-time.After(testing.LongWait):
   247  		c.Fatalf("event not handled")
   248  	}
   249  
   250  	err = workertest.CheckKilled(c, w)
   251  
   252  	c.Assert(err, gc.Equals, jworker.ErrRestartAgent)
   253  }