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
Add tests for runtime manager #1555
base: main
Are you sure you want to change the base?
Conversation
ec34013
to
99997c4
Compare
@zedGGs To answer your question about mocking, one of the goals of this work is to test out the ManagerImpl functions in |
@sjberman sounds good, |
@sjberman apologies for not being on time with an update, current test cases for thank you in advance ! if you want you can take current changes and I can add separated pr for good test cases, issue happens to be:
with |
b84583c
to
b36adc6
Compare
@zedGGs Thanks for the update. The issue you're seeing is that the nginx client is attempting to reach a real server, and fails. For unit tests we obviously do not want to use a real server. This means we probably need to create interfaces in https://github.com/nginxinc/nginx-plus-go-client, so we can provide a mock client in our own unit tests that won't try to contact a real server. |
@sjberman here's an update, I have added thanks |
4663750
to
0b42d66
Compare
It would be nice if we could also find a way to test the |
@kate-osborn sure, I am going to try add tests for that too |
f7e7508
to
6532721
Compare
6532721
to
06c586f
Compare
f027f15
to
dd4a219
Compare
dd4a219
to
724f615
Compare
err := manager.Reload(context.Background(), 1) | ||
Expect(err).To(BeNil()) |
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.
err := manager.Reload(context.Background(), 1) | |
Expect(err).To(BeNil()) | |
Expect(manager.Reload(context.Background(), 1)).To(Succeed()) |
I would also verify that each of the other interface functions were called (WaitForCorrectVersionCallCount, SyscallKillCallCount, etc)
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.
will do, thats good idea
internal/mode/static/manager.go
Outdated
nil, | ||
nil, |
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 need to be initialized for the real thing.
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.
@sjberman btw to update this properly I think I need for ProcessHandler interface, add ProcessHandlerImpl, if this is even good approach,
thank you !
type processHandler interface { | ||
FindMainProcess(ctx context.Context, checkFile CheckFileFunc, readFile ReadFileFunc, timeout time.Duration) (int, error) | ||
ReadFile(file string) ([]byte, error) | ||
SysCallKill(pid int, signum syscall.Signal) error |
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 just call this Kill
.
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
logger logr.Logger | ||
process processHandler |
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'd call the variable processHandler
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.
sure will do that
"github.com/nginxinc/nginx-gateway-fabric/internal/mode/static/nginx/runtime" | ||
"github.com/nginxinc/nginx-gateway-fabric/internal/mode/static/nginx/runtime/runtimefakes" |
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.
Separate these internal imports into a third category below the third-party imports.
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.
will do
) | ||
|
||
var _ = Describe("NGINX Runtime Manager", func() { | ||
var _ = Describe("NGINX Runtime Manager", Ordered, func() { |
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 don't believe these tests need to be Ordered, do they?
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.
when I have used BeforeAll, I was required to use Ordered, but if I use BeforeEach, then its not required, if you agree on that I can make updates
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.
BeforeEach is fine in this case
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.
awesome, going to proceed accordingly
upstreamServer = ngxclient.UpstreamServer{ | ||
ID: 1, | ||
Server: "10.0.0.1:80", | ||
MaxConns: &MaxConnsMock, | ||
MaxFails: &MaxFailsMock, | ||
FailTimeout: "test", | ||
SlowStart: "test", | ||
Route: "test", | ||
Backup: &BackupMock, | ||
Down: &DownMock, | ||
Drain: false, | ||
Weight: &WeightMock, | ||
Service: "test", | ||
} |
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.
Are these fields actually necessary to fill out for the test? I'm assuming we could just use an empty list of servers when calling the API function
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.
seems to be good without all of this stuff, so I will not fill these fields
err := manager.UpdateHTTPServers("test", upstreamServers) | ||
|
||
Expect(err).To(BeNil()) |
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.
err := manager.UpdateHTTPServers("test", upstreamServers) | |
Expect(err).To(BeNil()) | |
Expect(manager.UpdateHTTPServers("test", upstreamServers)).To(Succeed()) |
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.
thanks for suggestion Im going to add an update
|
||
//go:generate go run github.com/maxbrunsfeld/counterfeiter/v6 . processHandler | ||
|
||
type processHandler interface { |
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.
gentle ping @sjberman do you want me to add processHandlerImpl ? so I can use that outside, but then
func(p *ProcessHandlerImpl) FindMainProcess gets also updated, if this is even good approach, the goal is to cover these nil, nil that I used for real implementation
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.
Yes, that would be necessary to create an implementation.
This PR is stale because it has been open 14 days with no activity. Remove stale label or comment or this will be closed in 14 days. |
internal/mode/static/manager.go
Outdated
@@ -212,6 +213,8 @@ func StartManager(cfg config.Config) error { | |||
ngxPlusClient, | |||
ngxruntimeCollector, | |||
cfg.Logger.WithName("nginxRuntimeManager"), | |||
&ngxruntime.ProcessHandlerImpl{}, | |||
ngxruntime.NewVerifyClient(1*time.Second), |
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 timeout should be the same as nginxReloadTimeout
in the runtime manager. Let's export and use it.
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.
sure
@@ -133,7 +133,7 @@ func StartManager(cfg config.Config) error { | |||
} | |||
|
|||
// Ensure NGINX is running before registering metrics & starting the manager. | |||
if err := ngxruntime.EnsureNginxRunning(ctx); err != nil { | |||
if err := ngxruntime.EnsureNginxRunning(ctx, &ngxruntime.ProcessHandlerImpl{}); err != nil { |
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 think I'd rather initialize a single processHandler, make the EnsureNginxRunning
function a method for that object, and then reuse the processHandler in the runtime manager initialization.
internal/mode/static/manager.go
Outdated
@@ -144,6 +144,7 @@ func StartManager(cfg config.Config) error { | |||
|
|||
var ngxPlusClient *ngxclient.NginxClient | |||
var usageSecret *usage.Secret | |||
//var processHandler *ngxruntime.ProcessHandler |
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.
unneeded line
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.
sure, will add an update
This PR is stale because it has been open 14 days with no activity. Remove stale label or comment or this will be closed in 14 days. |
This PR was closed because it has been stalled for 14 days with no activity. |
Reopening after discussion with Zedd! |
Proposed changes
Problem: Missing tests on runtime manager
Im adding this init pr with few tests, if this goes well I can add another pr with more tests
gentle ping for @sjberman
Solution: Added tests and tested locally
Testing: running go test locally
optional: additional questions to clarify mocking and provide more details
Is practice for mocking runtime manager, more to use current usage with:
mgr = NewManagerImpl(&ngxclient.NginxClient{}, nil, logr.New(GinkgoLogr.GetSink()))
or I can use already created mock from
runtimefakes
:runtimefakes.FakeManager
as mocked struct, even tho its mocked interface ?or its required to actually mock
MetricsCollector
inruntimefakes
by creatingruntimefakes.FakeMetricsCollector
with counterfeiter and then use that one, inNewManagerImpl(&ngxclient.NginxClient{}, &runtmefakes.FakeMetricCollector{}, logr.New(GinkgoLogr.GetSink()))
or in
mockedManager := &runtimefakes.FakeManager{}
any advice on this is appreciated a lot, thank you in advance
Closes #1498
Checklist
Before creating a PR, run through this checklist and mark each as complete.