Skip to content
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

Merged
merged 1 commit into from
Aug 6, 2019
Merged

SIG: Egress worker test #2944

merged 1 commit into from
Aug 6, 2019

Conversation

sustrik
Copy link
Contributor

@sustrik sustrik commented Jul 31, 2019

This change is Reviewable

@sustrik sustrik requested a review from scrye July 31, 2019 08:59
Copy link
Contributor

@scrye scrye left a 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:

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)

Copy link
Contributor Author

@sustrik sustrik left a 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 the session.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 be false for implementations and true 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 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.

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:

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 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.

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.

Copy link
Contributor

@scrye scrye left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

:lgtm:

Reviewed 9 of 9 files at r2.
Reviewable status: :shipit: 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.

Copy link
Contributor

@scrye scrye left a 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: :shipit: 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.

Copy link
Contributor

@scrye scrye left a 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: :shipit: complete! all files reviewed, all discussions resolved

@sustrik sustrik merged commit b0d3c1f into scionproto:master Aug 6, 2019
@sustrik sustrik deleted the egress-test2 branch August 6, 2019 11:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants