-
Notifications
You must be signed in to change notification settings - Fork 1
add mockability, make tests work #111
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
04676cd
aa49688
c158163
49e098b
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -28,6 +28,9 @@ type ConnectionType struct { | |
Name string | ||
ConfigFields []CollectorConfigFragment | ||
Type string | ||
|
||
configFolderPath string | ||
getConfig func() *viper.Viper | ||
} | ||
|
||
func GetConfigFolderPath() string { | ||
|
@@ -48,24 +51,24 @@ func GetConfigFolderPath() string { | |
} | ||
|
||
func (c *ConnectionType) GetTemplateFilepath(tplFilename string) string { | ||
return filepath.Join(GetConfigFolderPath(), c.Name, tplFilename) | ||
return filepath.Join(c.configFolderPath, c.Name, tplFilename) | ||
} | ||
|
||
func (c *ConnectionType) RenderConfigTemplate(ctx context.Context, tmpDir string, tplFilename string, confValues any) (string, error) { | ||
tplPath := c.GetTemplateFilepath(tplFilename) | ||
tmpl, err := template.ParseFiles(tplPath) | ||
tmpl, err := template.New("").Funcs(GetTemplateFuncMap()).ParseFiles(tplPath) | ||
if err != nil { | ||
logger.FromCtx(ctx).Error("failed to parse config fragment template", zap.String("file", tplPath), zap.Error(err)) | ||
return "", err | ||
} | ||
f, err := os.CreateTemp(tmpDir, fmt.Sprintf("*-%s", tplFilename)) | ||
if err != nil { | ||
logger.FromCtx(ctx).Error("failed to create temporary config fragment file", zap.Error(err)) | ||
logger.FromCtx(ctx).Error("failed to create temporary config fragment file", zap.String("file", tplPath), zap.Error(err)) | ||
return "", err | ||
} | ||
err = tmpl.Execute(f, confValues) | ||
err = tmpl.ExecuteTemplate(f, tplFilename, confValues) | ||
if err != nil { | ||
logger.FromCtx(ctx).Error("failed to execute config fragment template", zap.Error(err)) | ||
logger.FromCtx(ctx).Error("failed to execute config fragment template", zap.String("file", tplPath), zap.Error(err)) | ||
return "", err | ||
} | ||
return f.Name(), nil | ||
|
@@ -76,40 +79,82 @@ func (c *ConnectionType) ProcessConfigFields(ctx context.Context, tmpDir string, | |
for _, field := range c.ConfigFields { | ||
val := rawConnConfig.GetBool(field.configYAMLPath) | ||
if val && field.colConfigFilePath != "" { | ||
configPath, _ := c.RenderConfigTemplate(ctx, tmpDir, field.colConfigFilePath, confValues) | ||
configPath, err := c.RenderConfigTemplate(ctx, tmpDir, field.colConfigFilePath, confValues) | ||
if err != nil { | ||
return nil, err | ||
} | ||
paths = append(paths, configPath) | ||
} | ||
} | ||
return paths, nil | ||
} | ||
|
||
func (c *ConnectionType) GetConfigFilePaths(ctx context.Context, tmpDir string) []string { | ||
var rawConnConfig = viper.Sub(c.Name) | ||
func (c *ConnectionType) GetConfigFilePaths(ctx context.Context, tmpDir string) ([]string, error) { | ||
var rawConnConfig = c.getConfig() | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. why do we pass the whole config into each fragment? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is still just the sub config by default, but having a dynamic function to retrieve it allows for mocks in the test. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ah i see, you've moved the function onto the struct |
||
var configPaths []string | ||
if rawConnConfig == nil || !rawConnConfig.GetBool("enabled") { | ||
return configPaths | ||
return configPaths, nil | ||
} | ||
switch c.Type { | ||
case SelfMonitoringConnectionTypeName: | ||
conf := &SelfMonitoringConfig{} | ||
err := rawConnConfig.Unmarshal(conf) | ||
if err != nil { | ||
logger.FromCtx(ctx).Error("failed to unmarshal config", zap.String("connection", c.Name)) | ||
return nil, err | ||
} | ||
configPaths, err = c.ProcessConfigFields(ctx, tmpDir, rawConnConfig, conf) | ||
if err != nil { | ||
return nil, err | ||
} | ||
configPaths, _ = c.ProcessConfigFields(ctx, tmpDir, rawConnConfig, conf) | ||
case HostMonitoringConnectionTypeName: | ||
conf := &HostMonitoringConfig{} | ||
err := rawConnConfig.Unmarshal(conf) | ||
if err != nil { | ||
logger.FromCtx(ctx).Error("failed to unmarshal config", zap.String("connection", c.Name)) | ||
return nil, err | ||
} | ||
configPaths, err = c.ProcessConfigFields(ctx, tmpDir, rawConnConfig, conf) | ||
if err != nil { | ||
return nil, err | ||
} | ||
configPaths, _ = c.ProcessConfigFields(ctx, tmpDir, rawConnConfig, conf) | ||
default: | ||
logger.FromCtx(ctx).Error("unknown connection type", zap.String("type", c.Type)) | ||
return nil, fmt.Errorf("unknown connection type %s", c.Type) | ||
} | ||
return configPaths, nil | ||
} | ||
|
||
type ConnectionTypeOption func(*ConnectionType) | ||
|
||
func MakeConnectionType(Name string, ConfigFields []CollectorConfigFragment, Type string, opts ...ConnectionTypeOption) *ConnectionType { | ||
var c = &ConnectionType{Name: Name, ConfigFields: ConfigFields, Type: Type} | ||
c.getConfig = func() *viper.Viper { | ||
return viper.Sub(c.Name) | ||
} | ||
c.configFolderPath = GetConfigFolderPath() | ||
|
||
// Apply provided options | ||
for _, opt := range opts { | ||
opt(c) | ||
} | ||
|
||
return configPaths | ||
return c | ||
} | ||
|
||
func WithConfigFolderPath(configFolderPath string) ConnectionTypeOption { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. are these just test helper functions? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, this was recommended to me as a way to allow tests to override the defaults. |
||
return func(c *ConnectionType) { | ||
c.configFolderPath = configFolderPath | ||
} | ||
} | ||
|
||
func WithGetConfig(getConfig func() *viper.Viper) ConnectionTypeOption { | ||
return func(c *ConnectionType) { | ||
c.getConfig = getConfig | ||
} | ||
} | ||
|
||
var AllConnectionTypes = []*ConnectionType{ | ||
&HostMonitoringConnectionType, | ||
&SelfMonitoringConnectionType, | ||
HostMonitoringConnectionType, | ||
SelfMonitoringConnectionType, | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if we fail to render a fragment, should we still start the agent?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good question; I think it's better to exit. I'll change this