-
Notifications
You must be signed in to change notification settings - Fork 163
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
SIG: Egress worker test #2944
SIG: Egress worker test #2944
Conversation
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.
Reviewed 5 of 5 files at r1.
Reviewable status: all files reviewed, 8 unresolved discussions (waiting on @sustrik)
go/sig/egress/session/session.go, line 103 at r1 (raw file):
go func() { defer log.LogPanicAndExit() worker.NewWorker(s, s.conn, false, s.Logger).Run()
Binding to s.conn
at the start introduces a subtle side-effect. Changes in a session's underlying connection (such changes are allowed by the session.Session
interface) are no longer seen by the egress code. See my comment below for more information.
go/sig/egress/worker/worker.go, line 69 at r1 (raw file):
sess egress.Session writer SCIONWriter ignoreAddress bool
Add a docstring mentioning this is for test support for legacy code, and that implementations should always have it set to false
.
I would also move it to the bottom of the struct, since it's not really related to the normal operation of the object.
go/sig/egress/worker/worker.go, line 79 at r1 (raw file):
} func NewWorker(sess egress.Session, writer SCIONWriter, ignoreAddress bool,
Add a docstring stating that ignoreAddress
should be false
for implementations and true
only for tests.
go/sig/egress/worker/worker.go, line 203 at r1 (raw file):
w.seq = 0 } bytesWritten, err := w.writer.WriteToSCION(f.raw(), snetAddr)
This can no longer take into account a Conn
change in session internals, i.e., two different calls to sess.Conn()
might yield different connection.
I don't know if sess.Conn()
ever changes, but now it must not. Therefore, I would add it to the godoc
of egress.Session.Conn
that it must return the same value over the lifetime of the object.
go/sig/egress/worker/worker_test.go, line 1 at r1 (raw file):
// Copyright 2019 Anapaya Systems
Add a TestMain
function to black hole logging s.t. it no longer clobbers normal test output.
Example:
scion/go/lib/infra/messenger/messenger_test.go
Lines 24 to 27 in 0e7e10e
func TestMain(m *testing.M) { | |
log.Root().SetHandler(log.DiscardHandler()) | |
os.Exit(m.Run()) | |
} |
go/sig/egress/worker/worker_test.go, line 41 at r1 (raw file):
} type MockSession struct {
This mock implementation is pretty big; use gomock
instead.
There are many examples of gomock
usage in our codebase. Also, see https://github.com/scionproto/scion/wiki/FAQ:-Bazel-for-Go-devs#how-do-i-add-a-mock for details.
go/sig/egress/worker/worker_test.go, line 108 at r1 (raw file):
} func (self *MockWriter) AssertFrame(t *testing.T, expected []byte) {
Once this migrates to gomock
, you can use a custom-definedgomock
matcher directly within the WriteToSCION
expected call, which will get rid of the manual state management in the current mock WriteToSCION
/AssertFrame
implementations.
The nice thing about managing less ring buffer/buffer state in this test via gomock
is that when application code gets refactored, the test stays the same, because it consists only of checking what should go on the network.
go/sig/egress/worker/worker_test.go, line 126 at r1 (raw file):
}() // Simple packet.
The shared state in these tests means that if one breaks the state of the session
framer, it will corrupt all future tests.
They should be made independent using Go subtests. Each subtest should consist of the init at the start of this function, and the cleanup at the end. Something like:
func TestParsing(t *testing.T) {
t.Run("simple packet", func() {
startTestWorker()
sesssion.SendPacket()
writer.AssertFrame()
stopTestWorker()
})
t.Run("two packets single frame", func() {
// etc
})
}
(also, you can use a table-driven approach to get rid of repeated setup/teardown calls, if you prefer)
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.
Reviewable status: 2 of 11 files reviewed, 8 unresolved discussions (waiting on @scrye)
go/sig/egress/session/session.go, line 103 at r1 (raw file):
Previously, scrye (Sergiu Costea) wrote…
Binding to
s.conn
at the start introduces a subtle side-effect. Changes in a session's underlying connection (such changes are allowed by thesession.Session
interface) are no longer seen by the egress code. See my comment below for more information.
Done.
go/sig/egress/worker/worker.go, line 69 at r1 (raw file):
Previously, scrye (Sergiu Costea) wrote…
Add a docstring mentioning this is for test support for legacy code, and that implementations should always have it set to
false
.I would also move it to the bottom of the struct, since it's not really related to the normal operation of the object.
Done.
go/sig/egress/worker/worker.go, line 79 at r1 (raw file):
Previously, scrye (Sergiu Costea) wrote…
Add a docstring stating that
ignoreAddress
should befalse
for implementations andtrue
only for tests.
Done.
go/sig/egress/worker/worker.go, line 203 at r1 (raw file):
Previously, scrye (Sergiu Costea) wrote…
This can no longer take into account a
Conn
change in session internals, i.e., two different calls tosess.Conn()
might yield different connection.I don't know if
sess.Conn()
ever changes, but now it must not. Therefore, I would add it to thegodoc
ofegress.Session.Conn
that it must return the same value over the lifetime of the object.
Done.
go/sig/egress/worker/worker_test.go, line 1 at r1 (raw file):
Previously, scrye (Sergiu Costea) wrote…
Add a
TestMain
function to black hole logging s.t. it no longer clobbers normal test output.Example:
scion/go/lib/infra/messenger/messenger_test.go
Lines 24 to 27 in 0e7e10e
func TestMain(m *testing.M) { log.Root().SetHandler(log.DiscardHandler()) os.Exit(m.Run()) }
Done.
go/sig/egress/worker/worker_test.go, line 41 at r1 (raw file):
Previously, scrye (Sergiu Costea) wrote…
This mock implementation is pretty big; use
gomock
instead.There are many examples of
gomock
usage in our codebase. Also, see https://github.com/scionproto/scion/wiki/FAQ:-Bazel-for-Go-devs#how-do-i-add-a-mock for details.
Done.
go/sig/egress/worker/worker_test.go, line 108 at r1 (raw file):
Previously, scrye (Sergiu Costea) wrote…
Once this migrates to
gomock
, you can use a custom-definedgomock
matcher directly within theWriteToSCION
expected call, which will get rid of the manual state management in the current mockWriteToSCION
/AssertFrame
implementations.The nice thing about managing less ring buffer/buffer state in this test via
gomock
is that when application code gets refactored, the test stays the same, because it consists only of checking what should go on the network.
Done.
go/sig/egress/worker/worker_test.go, line 126 at r1 (raw file):
Previously, scrye (Sergiu Costea) wrote…
The shared state in these tests means that if one breaks the state of the
session
framer, it will corrupt all future tests.They should be made independent using Go subtests. Each subtest should consist of the init at the start of this function, and the cleanup at the end. Something like:
func TestParsing(t *testing.T) { t.Run("simple packet", func() { startTestWorker() sesssion.SendPacket() writer.AssertFrame() stopTestWorker() }) t.Run("two packets single frame", func() { // etc }) }
(also, you can use a table-driven approach to get rid of repeated setup/teardown calls, if you prefer)
Done.
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.
Reviewed 9 of 9 files at r2.
Reviewable status:complete! all files reviewed, all discussions resolved
go/sig/egress/interface.go, line 59 at r2 (raw file):
ID() mgmt.SessionType // Conn returns the session's outbound snet Conn. // The returned value must be the same for the enire lifetime of the object.
nit: s/enire/entire
go/sig/egress/worker/worker_test.go, line 51 at r2 (raw file):
} func (self *FrameMatcher) Matches(x interface{}) bool {
Nit: Didn't point this out earlier because I thought the type might be going away, but we avoid self
as a receiver name in the code base (we adhere to the point made here https://github.com/golang/go/wiki/CodeReviewComments#receiver-names). We're not 100% strict on it, but it's probably better to be consistent.
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.
Reviewed 3 of 3 files at r3.
Reviewable status:complete! all files reviewed, all discussions resolved
go/sig/egress/worker/worker_test.go, line 51 at r3 (raw file):
} func (self *FrameMatcher) Matches(x interface{}) bool {
If you rebase again, you can also fix this receiver name.
go/sig/egress/worker/worker_test.go, line 68 at r3 (raw file):
} func (self *FrameMatcher) String() string {
Also this one.
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.
Reviewed 1 of 1 files at r4.
Reviewable status:complete! all files reviewed, all discussions resolved
This change is![Reviewable](https://camo.githubusercontent.com/1541c4039185914e83657d3683ec25920c672c6c5c7ab4240ee7bff601adec0b/68747470733a2f2f72657669657761626c652e696f2f7265766965775f627574746f6e2e737667)