-
Notifications
You must be signed in to change notification settings - Fork 0
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
Test config
#71
base: main
Are you sure you want to change the base?
Test config
#71
Conversation
f232daa
to
2d3bad2
Compare
config/config_test.go
Outdated
t.Run("Nil pointer argument", func(t *testing.T) { | ||
var flags interface{} | ||
|
||
err := ParseFlags(flags) | ||
require.ErrorIs(t, err, ErrInvalidArgument) | ||
}) | ||
|
||
t.Run("Nil argument", func(t *testing.T) { | ||
err := ParseFlags(nil) | ||
require.ErrorIs(t, err, ErrInvalidArgument) | ||
}) | ||
} |
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.
These two test cases seem to be identical. Furthermore, the first one does not check a nil
pointer, but nil
.
If, however, one changes it to use a real nil pointer by setting ParseFlags(&flags)
, it panics.
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.
Yep, I forgot to add *
, i.e. var flags *any
.
config/config_test.go
Outdated
}) | ||
} | ||
|
||
// simpleConfig is an always valid test configuration struct with only one key. |
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.
This is just my personal taste, but I would expect the used types to be on the top of the file. When reading the tests top to bottom, I first asked myself where the used types are being declared.
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.
I just always put the exported stuff first. But you're right that it's better for tests to have them first.
defer func(name string) { | ||
_ = os.Remove(name) | ||
}(yamlFile.Name()) |
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.
Is there a reason to introduce the name
variable for the deferred function? yamlFile.Name()
is also used on all other places.
defer func(name string) { | |
_ = os.Remove(name) | |
}(yamlFile.Name()) | |
defer func() { _ = os.Remove(yamlFile.Name()) }() |
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.
In such scenarios, I would always capture the argument values at the time the defer is set up, as opposed to relying on the value not having changed by the time the defer is executed.
config/config_test.go
Outdated
t.Run("Nil pointer argument", func(t *testing.T) { | ||
var config Validator | ||
|
||
err := FromYAMLFile("", config) | ||
require.ErrorIs(t, err, ErrInvalidArgument) | ||
}) | ||
|
||
t.Run("Nil argument", func(t *testing.T) { | ||
err := FromYAMLFile("", nil) | ||
require.ErrorIs(t, err, ErrInvalidArgument) | ||
}) |
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.
Again, both these tests boil down to perform the same FromYAMLFile
call.
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.
True, and it's a bit more difficult here. But I think something like var config *struct{ Validator }
could work.
var config struct{ validateValid } | ||
var pathError *fs.PathError | ||
|
||
err := FromYAMLFile("nonexistent.yaml", &config) |
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.
One should enforce that nonexistent.yaml
does not suddenly exists. Maybe create another new temporary file, delete it afterwards and use its file path? I mean, technically this could be raced, but it should be fine for tests.
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.
I will add require.ErrorIs(t, pathError.Err, fs.ErrNotExist)
. If nonexistent.yaml
really gets created, the test fails.
defer func(name string) { | ||
_ = os.Remove(name) | ||
}(yamlFile.Name()) |
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.
Again, why are you wrapping the file name?
Btw, I have verified that the os.Remove
works. First, I was a bit uncertain due to the 000
permissions.
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.
Btw, I have verified that the
os.Remove
works. First, I was a bit uncertain due to the000
permissions.
Yes, the ability to delete a file is determined by the permissions of the directory containing the file.
Key: "value", | ||
}, | ||
invalid: true, | ||
}, |
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.
A test case for failed defaults is missing. Maybe create some test type with faulty default struct types.
icinga-go-library/config/config.go
Lines 37 to 38 in d8bd22a
if err := defaults.Set(v); err != nil { | |
return errors.Wrap(err, "can't set config defaults") |
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.
Sounds good.
err := ParseFlags(nil) | ||
require.ErrorIs(t, err, ErrInvalidArgument) | ||
}) | ||
} |
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.
There are no tests for a parser.Parse()
error. However, this may require some code changes as otherwise one has to recover from os.Exit()
.
icinga-go-library/config/config.go
Lines 70 to 78 in d8bd22a
if _, err := parser.Parse(); err != nil { | |
var flagErr *flags.Error | |
if errors.As(err, &flagErr) && flagErr.Type == flags.ErrHelp { | |
fmt.Fprintln(os.Stdout, flagErr) | |
os.Exit(0) | |
} | |
return errors.Wrap(err, "can't parse CLI flags") | |
} |
However, covering this is not completely necessary, imo.
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.
Recover from os.Exit()
is impossible using the stdlib, at least to my knowledge. But we could test that using a subprocess. I'll give it a try.
config/tls_test.go
Outdated
var issuerKey crypto.PrivateKey | ||
if options.issuer != nil { | ||
if options.issuerKey == nil { | ||
panic("issuerKey required if issuer set") |
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.
This helper function returns an error in most cases, but panics here. When generateCert
is called, the error must always be empty. Thus, to have a nicer test output, maybe return an error here as well.
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.
Yeah, why not.
config/tls_test.go
Outdated
issuerKey = privateKey | ||
} | ||
|
||
derBytes, err := x509.CreateCertificate(rand.Reader, template, issuer, privateKey.Public(), issuerKey) |
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.
der Bytes?
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.
Well, x509.CreateCertificate()
returns the DER encoded certificate as bytes -> derBytes 😆.
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.
I would rename it to der
as x509.ParseCertificate()
uses that as argument name.
2d3bad2
to
d7eae21
Compare
d7eae21
to
b93c892
Compare
@oxzi I have adjusted the code based on your preview. Please take another look at it. I have already moved code unfortunately, so the comments are no longer aligned correctly. |
This PR introduces tests for the
ParseFlags()
,FromYAMLFile()
andTLS.MakeConfig()
functions:ParseFlags
FromYAMLFile
TLS.MakeConfig()
Basic Configuration
nil
when TLS is disabled.InsecureSkipVerify
is set totrue
when specified.x509 Certificate Handling