Skip to content

Commit

Permalink
feat(config-cache): possibility to list hosts of given cluster
Browse files Browse the repository at this point in the history
  • Loading branch information
karol-kokoszka committed May 16, 2024
1 parent 15c87ca commit bd9ae32
Show file tree
Hide file tree
Showing 2 changed files with 96 additions and 0 deletions.
26 changes: 26 additions & 0 deletions pkg/service/configcache/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@ type ConfigCacher interface {
// or ErrNoHostConfig if config of the particular host doesn't exist.
Read(clusterID uuid.UUID, host string) (NodeConfig, error)

// AvailableHosts returns list of hosts of given cluster that keep their configuration in cache.
AvailableHosts(ctx context.Context, clusterID uuid.UUID) ([]string, error)

// ForceUpdateCluster updates single cluster config in cache and does it outside the background process.
ForceUpdateCluster(ctx context.Context, clusterID uuid.UUID) bool

Expand Down Expand Up @@ -123,6 +126,29 @@ func (svc *Service) ForceUpdateCluster(ctx context.Context, clusterID uuid.UUID)
return svc.updateSingle(ctx, c)
}

// AvailableHosts returns list of hosts of given cluster that keep their configuration in cache.
func (svc *Service) AvailableHosts(ctx context.Context, clusterID uuid.UUID) ([]string, error) {
logger := svc.logger.Named("Listing available hosts").With("cluster", clusterID)

clusterConfig, err := svc.readClusterConfig(clusterID)
if err != nil {
return nil, err
}

var availableHosts []string
clusterConfig.Range(func(key, value any) bool {
host, ok := key.(string)
if !ok {
logger.Error(ctx, "Cannot cast to string", "host", key, "error", err)
return false
}
availableHosts = append(availableHosts, host)
return true
})

return availableHosts, nil
}

func (svc *Service) updateSingle(ctx context.Context, c *cluster.Cluster) bool {
logger := svc.logger.Named("Cluster config update").With("cluster", c.ID)

Expand Down
70 changes: 70 additions & 0 deletions pkg/service/configcache/service_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,76 @@ func TestService_Read(t *testing.T) {
}
}

func TestService_AvailableHosts(t *testing.T) {
host1NodeConfig := NodeConfig{
NodeInfo: &scyllaclient.NodeInfo{
AgentVersion: "expectedVersion",
},
}

cluster1UUID := uuid.MustRandom()
host1ID := "host1"
initialState := convertMapToSyncMap(
map[any]any{
cluster1UUID.String(): convertMapToSyncMap(
map[any]any{
host1ID: host1NodeConfig,
},
),
},
)

for _, tc := range []struct {
name string
cluster uuid.UUID
state *sync.Map
expectedError error
expectedResult []string
}{
{
name: "get all available hosts",
cluster: cluster1UUID,
state: initialState,
expectedError: nil,
expectedResult: []string{host1ID},
},
{
name: "get all available hosts of non-existing cluster",
cluster: uuid.MustRandom(),
state: initialState,
expectedError: ErrNoClusterConfig,
expectedResult: nil,
},
} {
t.Run(tc.name, func(t *testing.T) {
// Given
svc := Service{
svcConfig: DefaultConfig(),
clusterSvc: &mockClusterServicer{},
scyllaClient: mockProviderFunc,
secretsStore: &mockStore{},
configs: tc.state,
}

// When
hosts, err := svc.AvailableHosts(context.Background(), tc.cluster)
if err != tc.expectedError {
t.Fatalf("expected {%v}, but got {%v}", tc.expectedError, err)
}

// Then
if len(hosts) != len(tc.expectedResult) {
t.Fatalf("expected hosts size = {%v}, but got {%v}", len(tc.expectedResult), len(hosts))
}
for i := 0; i < len(tc.expectedResult); i++ {
if hosts[i] != tc.expectedResult[i] {
t.Fatalf("expected host {%v}, but got {%v}", host1ID, hosts[0])
}
}
})
}
}

func TestService_Run(t *testing.T) {
t.Run("validate context cancellation handling", func(t *testing.T) {
svc := Service{
Expand Down

0 comments on commit bd9ae32

Please sign in to comment.