add ability to mock zcashd rpc calls for testing, add tests#164
add ability to mock zcashd rpc calls for testing, add tests#164LarryRuane merged 1 commit intomasterfrom
Conversation
a260134 to
3083d45
Compare
3083d45 to
aeadd48
Compare
LarryRuane
left a comment
There was a problem hiding this comment.
The main changes here are to allow calls to zcashd RPCs to be stubbed out. There are a few more instances to do, but this is a start.
| defer output.Close() | ||
| logger.SetOutput(output) | ||
| logger.SetFormatter(&logrus.JSONFormatter{}) | ||
| } |
There was a problem hiding this comment.
This is moved, makes sense to open the log file as soon as possible. Slight change (improvement) in behavior -- if you specify -log-file '', the process will log to stdout. (Without these changes, it's not possible to log to stdout.)
common/cache.go
Outdated
|
|
||
| // Detect reorg, ingestor needs to handle it | ||
| if height > c.firstBlock && !bytes.Equal(block.PrevHash, c.m[height-1].hash) { | ||
| if block != nil && height > c.firstBlock && !bytes.Equal(block.PrevHash, c.m[height-1].hash) { |
There was a problem hiding this comment.
The new nil check allows the unit test to force an error below, on the call to proto.Marshal(). I don't love modifying production code just for testing, but I think in this case it's okay, it really is caught below. (This is the only instance of that.)
There was a problem hiding this comment.
It's worth adding a comment in the code to explain this.
| retryCount := 0 | ||
| for { | ||
| block, err := getBlockFromRPC(rpcClient, height) | ||
| for i := 0; rep == 0 || i < rep; i++ { |
There was a problem hiding this comment.
The rep variable prevents this function from infinite-looping during unit testing (it will, correctly, infinite loop during production).
aeadd48 to
1dbec79
Compare
1dbec79 to
59170d4
Compare
|
Interesting, github says this PR was closed but it was actually merged. I guess it does that when the branch gets merged differently to how GitHub expects? |
|
I closed this by mistake, reopening |
| # Lint golang files | ||
| lint: | ||
| @golint -set_exit_status | ||
| golint -set_exit_status |
There was a problem hiding this comment.
I find it much more helpful to see what's actually happening
| # Run unittests | ||
| test: | ||
| @go test -v -coverprofile=coverage.txt -covermode=atomic ./... | ||
| go test -v ./... |
There was a problem hiding this comment.
there is no need for atomic, and there's a separate make target for coverage
| coverage: | ||
| @go test -coverprofile=coverage.out -covermode=atomic ./... | ||
| go test -coverprofile=coverage.out ./... | ||
| sed -i '/\.pb\.go/d' coverage.out |
There was a problem hiding this comment.
the .pb. files are generated (protobuf), and their code coverage is not relevant
| } | ||
|
|
||
| log = logger.WithFields(logrus.Fields{ | ||
| common.Log = logger.WithFields(logrus.Fields{ |
There was a problem hiding this comment.
There is no reason the logging object can't be a global variable, and doing that simplifies many of the function signatures, and makes unit tests easier to write.
| type blockCacheEntry struct { | ||
| data []byte | ||
| hash []byte | ||
| } |
There was a problem hiding this comment.
Identifiers that start with a capital letter are exported, but this type definition can remain private.
| # apt-get update && apt-get install -y openssl | ||
|
|
||
| openssl req -x509 -nodes -newkey rsa:2048 -keyout ./cert.key -out ./cert.pem -days 3650 -subj "/C=US/ST=CA/O=MyOrg, Inc./CN=lightwalletd.testnet.local" -reqexts SAN -config <(cat /etc/ssl/openssl.cnf <(printf "\n[SAN]\nsubjectAltName=DNS:lightwalletd.testnet.local,DNS:127.0.0.1,DNS:localhost")) No newline at end of file | ||
| openssl req -x509 -nodes -newkey rsa:2048 -keyout ./cert.key -out ./cert.pem -days 3650 -subj "/C=US/ST=CA/O=MyOrg, Inc./CN=lightwalletd.testnet.local" -reqexts SAN -config <(cat /etc/ssl/openssl.cnf <(printf "\n[SAN]\nsubjectAltName=DNS:lightwalletd.testnet.local,DNS:127.0.0.1,DNS:localhost")) |
There was a problem hiding this comment.
missing newline (confuses some tools)
frontend/frontend_test.go
Outdated
| "t123456789012345678901234567890123*", // invalid "*" | ||
| "s1234567890123456789012345678901234", // doesn't start with "t" | ||
| " t1234567890123456789012345678901234", // extra stuff before | ||
| "t1234567890123456789012345678901234 ", // extra stuff after |
There was a problem hiding this comment.
A test case for the newline thing would be "\nt1234567890123456789012345678901234".
| rpcaddr := cfg.Section("").Key("rpcbind").String() | ||
| if rpcaddr == "" { | ||
| rpcaddr = "127.0.0.1" | ||
| } |
There was a problem hiding this comment.
Should not be in this PR, but I ran into this while testing, so...
| s.log.Errorf("Got error: %s", rpcErr.Error()) | ||
| return nil | ||
| common.Log.Errorf("Got error: %s", rpcErr.Error()) | ||
| return err |
There was a problem hiding this comment.
This (and a few similar cases below) was just broken, nil means no error by convention.
There was a problem hiding this comment.
Were these maybe intentional for some reason, like to hide the specific error message from the client or something? (I don't think so, it looks like it was just broken)
|
|
||
| rawTxData[count] = txData | ||
| count++ | ||
| rawTxData = append(rawTxData, txData) |
There was a problem hiding this comment.
This is just a slight simplification, no functional change
LarryRuane
left a comment
There was a problem hiding this comment.
Interesting, github says this PR was closed but it was actually merged. I guess it does that when the branch gets merged differently to how GitHub expects?
I think GitHub noticed that the tip of this branch was equal to the tip of the target branch (master), so it concluded that the changes were merged... when in reality, there were no changes (because of my mistake of force-pushing my branch when it exactly matched master). And because the changes were "merged", it figured that the PR can be closed! Anyway, it's back in the correct state now.
defuse
left a comment
There was a problem hiding this comment.
Tested ACK. This is some awesome testing!! I left some comments, but none of them are blocking.
common/cache.go
Outdated
|
|
||
| // Detect reorg, ingestor needs to handle it | ||
| if height > c.firstBlock && !bytes.Equal(block.PrevHash, c.m[height-1].hash) { | ||
| if block != nil && height > c.firstBlock && !bytes.Equal(block.PrevHash, c.m[height-1].hash) { |
There was a problem hiding this comment.
It's worth adding a comment in the code to explain this.
| s.log.Errorf("Got error: %s", rpcErr.Error()) | ||
| return nil | ||
| common.Log.Errorf("Got error: %s", rpcErr.Error()) | ||
| return err |
There was a problem hiding this comment.
Were these maybe intentional for some reason, like to hide the specific error message from the client or something? (I don't think so, it looks like it was just broken)
frontend/frontend_test.go
Outdated
| "t123456789012345678901234567890123*", // invalid "*" | ||
| "s1234567890123456789012345678901234", // doesn't start with "t" | ||
| " t1234567890123456789012345678901234", // extra stuff before | ||
| "t1234567890123456789012345678901234 ", // extra stuff after |
There was a problem hiding this comment.
A test case for the newline thing would be "\nt1234567890123456789012345678901234".
| func TestGenerateCerts(t *testing.T) { | ||
| if GenerateCerts() == nil { | ||
| t.Fatal("GenerateCerts returned nil") | ||
| } |
There was a problem hiding this comment.
I opened #181 so that we're less likely to mistakenly think GenerateCerts is fully tested when we look at the coverage (it'd be obvious if this code was broken because the certs wouldn't work so this is fine for now).
3fab586 to
eca8f66
Compare
|
Force-pushed @defuse's review comment fixes (thanks!), merging now. |
Fixes #146. Small block caching test improvement, but also make the zcashd RPC calls mockable, so tests can generate fake replies, to increase test coverage.