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

Added a unit test for the BlobStoreWriter. #5472

Merged
merged 11 commits into from
Dec 11, 2023
Merged

Conversation

agautam478
Copy link
Contributor

@agautam478 agautam478 commented Dec 7, 2023

What changed?
Added a test for the BlobstoreWriter since it didn't have any.

Why?
It's an attempt at improving our code coverage and introduce better testing practices. Tried the table test for the first time here. This is something that will simplify tedious and repetitive unit tests in Go (Golang) when testing functions with multiple scenarios and data.

How did you test it?
Yes ran locally.

Potential risks
NA

Release notes
NA

Documentation Changes
NA

@agautam478 agautam478 changed the title Add test Added a unit test for the BlobStoreWriter. Dec 7, 2023
common/reconciliation/store/blobstorewriter_test.go Outdated Show resolved Hide resolved
err := blobstoreWriter.Add(tc.input)
if tc.expectedErr {
assert.Error(t, err)
} else {
Copy link
Contributor

Choose a reason for hiding this comment

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

avoid extra indentation by handling special case and returning.

if tc.expectedErr {
  assert.Error(t, err)
  return
}

// rest of the code goes here without an else { } wrapper

Copy link
Contributor

Choose a reason for hiding this comment

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

this would be an ideal case for require.NoError(t, err) fwiw. that'll stop the test immediately.

(this is also one of the reasons why embedding Assertions is problematic. it hides whether things are asserts or requires, and that's a VERY important detail for this reason and for concurrency-safety reasons (you cannot safely require on a background thread))


// Retrieve the keys of flushed data
flushedKeys := blobstoreWriter.FlushedKeys()
assert.NotNil(t, flushedKeys)
Copy link
Contributor

Choose a reason for hiding this comment

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

do these assert calls include a message to pinpoint where it failed? more simple way to write assertions in native go is

if flushedKeys == nil {
  t.Error("Expected flushedKeys to be not nil")
}

what does assert.NotNil show in test output when flushedKeys is nil?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It will show a test failure like this:

--- FAIL: TestBlobstoreWriter (0.00s)
Error Trace: xyz
Error: Expected value not to be nil.

Copy link
Contributor

@Groxx Groxx Dec 8, 2023

Choose a reason for hiding this comment

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

assert and t.* calls do print the line and a partial trace that failed, yeah.

generally we prefer assert/require because it's a safer habit and almost always less code - they produce more useful output if you don't spend extra time making custom messages for every assertion.

Comment on lines 81 to 83
if flushedKeys == nil {
t.Error("Expected flushedKeys to be not nil")
}
Copy link
Contributor

Choose a reason for hiding this comment

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

same as assert.NotNil though in this case you probably want require.NotNil since it'll crash and fail to produce that error message if it runs line 86

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@taylanisikdemir any opinions?

Copy link
Contributor

Choose a reason for hiding this comment

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

Not only this line but all the validations could just be written using t.Error/t.Fatal which forces us to write explicit error message. On the other hand the message is optional in assert/require packages. e.g.

// require.NotNil signature
NotNil(t TestingT, object interface{}, msgAndArgs ...interface{})

Regarding the termination when flushedKeys is nil, yes let's fix that by changing this to t.Fatal instead of t.Error

Comment on lines 93 to 96
var result string
err = json.Unmarshal(resp.Blob.Body, &result)
require.NoError(t, err)
assert.Equal(t, tc.input, result)
Copy link
Contributor

@Groxx Groxx Dec 8, 2023

Choose a reason for hiding this comment

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

hmmm. tbh this feels kinda misleading to me - this same Unmarshal won't work if you .Add twice because of how it's serializing in getBlobstoreWriteFn(...), but "multiple Add()s" is the normal, expected use here.

to be more accurate it'd probably need to use blobstoreiterator to deserialize. though that'd require using a reconciliation/entity.Entity which does a fair amount of irrelevant things here...


since using an Entity seems mostly unrelated and overkill, maybe something like this would make it clear that the format is decided by the writer, and it's not intended to be valid JSON on its own?

// add 2 things since that's common in practice + makes it no longer a single valid json thing
blobstoreWriter.Add("one")
blobstoreWriter.Add("two")

// verify the bytes are as expected
assert.Equal(t, resp.Blob.Body, []byte(`"one"\r\n"two"`)

Copy link
Contributor Author

@agautam478 agautam478 Dec 8, 2023

Choose a reason for hiding this comment

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

this one was failing with some mismatch in bytes error.

Expected :[]byte{0x22, 0x74, 0x65, 0x73, 0x74, 0x2d, 0x64, 0x61, 0x74, 0x61, 0x22, 0xd, 0xa}
Actual :[]byte{0x74, 0x65, 0x73, 0x74, 0x2d, 0x64, 0x61, 0x74, 0x61}

Copy link
Contributor

Choose a reason for hiding this comment

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

that'd depend on what you're comparing / where you got those bytes. the 0x22 one looks like what I expect in body though

Copy link
Contributor

@Groxx Groxx left a comment

Choose a reason for hiding this comment

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

Minor assert-vs-request-vs-t.Error fuzziness to clean up and I do think it's worth not implying "produces valid json" (because this writer does not). but otherwise looks good, should be an easy 👍

assert.NoError(t, err)

// Verify the contents
assert.Equal(t, string(resp.Blob.Body), "\"one\"\r\n\"two\"\r\n")
Copy link
Contributor

Choose a reason for hiding this comment

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

for a table-test you'd probably put this in the table (as it's likely to change with each test), but eh. the test is reasonably simple, will be easy to adjust when we change it for future stuff.

@agautam478 agautam478 merged commit fa02c41 into uber:master Dec 11, 2023
16 checks passed
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.

4 participants