gcpug / zagane Goto Github PK
View Code? Open in Web Editor NEWzagane is a static analysis tool which can find bugs in spanner's code
License: MIT License
zagane is a static analysis tool which can find bugs in spanner's code
License: MIT License
I think current name of Analyzer is not straightforward with users.
So I'd like to change the name such as below.
unstopiter
and unclosetx
will merge into sessionleak
wraperr
will be changed to retryless
repro
git clone https://github.com/gcpug/zagane.git
cd zagane
diff --git a/passes/unstopiter/testdata/src/a/a.go b/passes/unstopiter/testdata/src/a/a.go
index 0ad4cf5..c78dd04 100644
--- a/passes/unstopiter/testdata/src/a/a.go
+++ b/passes/unstopiter/testdata/src/a/a.go
@@ -8,7 +8,8 @@ import (
func f1(ctx context.Context, client *spanner.Client) {
stmt := spanner.Statement{SQL: `SELECT 1`}
- _, _ = client.Single().Query(ctx, stmt).Next() // want "iterator must be stopped"
+ //lint:ignore unstopiter reason
+ _, _ = client.Single().Query(ctx, stmt).Next()
client.Single().Query(ctx, stmt).Stop() // OK
defer client.Single().Query(ctx, stmt).Stop() // OK
}
go test .\passes\unstopiter\unstopiter_test.go
Expected: Test passes
Actual: Test fails
$ go test .\passes\unstopiter\unstopiter_test.go
--- FAIL: Test (2.40s)
analysistest.go:251: a/a.go:12:30: unexpected diagnostic: iterator must be stopped
FAIL
FAIL command-line-arguments 2.550s
This is maybe github.com/gostaticanalysis/comment
bug or misusage.
skip functions which don't import spanner
With this commit, wrapped errors are now available in Cloud Spanner's ReadWriteTransaction.
googleapis/google-cloud-go@9f47821
Original issue
googleapis/google-cloud-go#1223
We often want to know version of zagane with trouble shootings.
So I would like to add --version
option.
$ zagane --version
0.3.4
(*spanner.Client).Single
.Currently unstopiter only checks next successor blocks.
It should check more far blocks.
unclosetx
cannot detect looks like this sample code.
func (h *Handler) fetchUser(ctx context.Context, userID string) (*database.User, error) {
txn := h.repository.Client.ReadOnlyTransaction() // h.repository.Client is a Spanner client.
user, err := database.FindUser(ctx, txn, userID)
if err != nil {
return nil, err
}
return user, nil
}
$ go version
go version go1.18.2 darwin/amd64
Yes.
Try running "zagane" in the following code.
// main.go
package main
import "fmt"
func main() {
Print([]string{"xxx"})
}
func Print[T any](s []T) {
for _, v := range s {
fmt.Println(v)
}
}
$ go vet -vettool=(which zagane) main.go
No errors.
# command-line-arguments
panic: T
goroutine 17 [running]:
golang.org/x/tools/go/ssa.(*Program).needMethods(0xc0000940d0, {0x132b478?, 0xc0001a21b0?}, 0x0)
/Users/shota/go/1.18.2/pkg/mod/golang.org/x/[email protected]/go/ssa/methods.go:237 +0x5b1
golang.org/x/tools/go/ssa.(*Program).needMethods(0xc0000940d0, {0x132b400?, 0xc000063d40?}, 0x0)
/Users/shota/go/1.18.2/pkg/mod/golang.org/x/[email protected]/go/ssa/methods.go:196 +0x347
golang.org/x/tools/go/ssa.(*Program).needMethods(0xc0000940d0, {0x132b450?, 0xc00000d1a0?}, 0x0)
/Users/shota/go/1.18.2/pkg/mod/golang.org/x/[email protected]/go/ssa/methods.go:233 +0x708
golang.org/x/tools/go/ssa.(*Program).needMethods(0xc0000940d0, {0x132b3d8?, 0xc000198bc0?}, 0x0)
/Users/shota/go/1.18.2/pkg/mod/golang.org/x/[email protected]/go/ssa/methods.go:209 +0x448
golang.org/x/tools/go/ssa.(*Program).needMethodsOf(0xc0000940d0, {0x132b3d8?, 0xc000198bc0?})
/Users/shota/go/1.18.2/pkg/mod/golang.org/x/[email protected]/go/ssa/methods.go:145 +0x70
golang.org/x/tools/go/ssa.(*Package).build(0xc000090360)
/Users/shota/go/1.18.2/pkg/mod/golang.org/x/[email protected]/go/ssa/builder.go:2284 +0x111
sync.(*Once).doSlow(0xc0000940d0?, 0xc0000776d0?)
/Users/shota/.goenv/versions/1.18.2/src/sync/once.go:68 +0xc2
sync.(*Once).Do(...)
/Users/shota/.goenv/versions/1.18.2/src/sync/once.go:59
golang.org/x/tools/go/ssa.(*Package).Build(...)
/Users/shota/go/1.18.2/pkg/mod/golang.org/x/[email protected]/go/ssa/builder.go:2272
golang.org/x/tools/go/analysis/passes/buildssa.run(0xc000094000)
/Users/shota/go/1.18.2/pkg/mod/golang.org/x/[email protected]/go/analysis/passes/buildssa/buildssa.go:72 +0x2ee
golang.org/x/tools/go/analysis/unitchecker.run.func5.1()
/Users/shota/go/1.18.2/pkg/mod/golang.org/x/[email protected]/go/analysis/unitchecker/unitchecker.go:355 +0x82e
sync.(*Once).doSlow(0x0?, 0x0?)
/Users/shota/.goenv/versions/1.18.2/src/sync/once.go:68 +0xc2
sync.(*Once).Do(...)
/Users/shota/.goenv/versions/1.18.2/src/sync/once.go:59
golang.org/x/tools/go/analysis/unitchecker.run.func5(0x149f380?)
/Users/shota/go/1.18.2/pkg/mod/golang.org/x/[email protected]/go/analysis/unitchecker/unitchecker.go:307 +0x1a5
golang.org/x/tools/go/analysis/unitchecker.run.func6.1(0x0?)
/Users/shota/go/1.18.2/pkg/mod/golang.org/x/[email protected]/go/analysis/unitchecker/unitchecker.go:367 +0x29
created by golang.org/x/tools/go/analysis/unitchecker.run.func6
/Users/shota/go/1.18.2/pkg/mod/golang.org/x/[email protected]/go/analysis/unitchecker/unitchecker.go:366 +0x47
Detect that CommitTimestamp contains time.Now () in TIMESTAMP column with allow_commit_timestamp = true
Unless there are special circumstances, set the commit_timestamp column to
spanner.CommitTimestamp.
If time.Now () is included, Transaction will fail if a future time is set due to the time difference of the execution environment.
It's hard to notice in Test that the time is a few ms in the future, so it would be nice to be able to find it by static analysis.
However, it is difficult to judge whether it is allow_commit_timestamp = true because it is time.Time type in Go source code.
yo will add a new tag to the allow_commit_timestamp column of the generated code.
I can't come up with a good way to determine if a TIMESTAMP column is an allow_commit_timestamp column if I'm still using google-cloud-go 🤔
When I use errgroup, zagane reports transaction must be closed
. I think that it's false positive detection.
sample code:
func f5(ctx context.Context, client *spanner.Client) error {
tx := client.ReadOnlyTransaction() // OK
defer tx.Close()
var eg errgroup.Group
eg.Go(func() error {
_ = tx // use tx
return nil
})
if err := eg.Wait(); err != nil {
return err
}
return nil
}
$ zagane version
zagame must fix version of target spanner package because spanner package will update and zagame also will follow it. But some users of zagane may not update spanner package by own reason.
Related issue: #29
This comment does not work.
//lint:ignore zagane ignore it
client.ReadOnlyTransaction() // OK
ユースケースなどのドキュメントを作成する
zagane regards RowIterator.Do
invocations without RowIterator.Stop()
as unstopiter
.
However, since RowIterator.Do
calls Stop
internally, I think they are false positive detections.
https://godoc.org/cloud.google.com/go/spanner#RowIterator.Do
unclosetx cannot detect looks like this sample code.
func f7(ctx context.Context, client *spanner.Client) error {
ro := client.ReadOnlyTransaction()
err := Find01(ctx, ro)
return err
}
func Find01(ctx context.Context, ro *spanner.ReadOnlyTransaction) error {
row, err := ro.ReadRow(ctx, "DummyTable", spanner.Key{1}, []string{"Id"})
log.Printf("row: %s", row)
return err
}
This sample code become OK.
package a
import (
"context"
"cloud.google.com/go/spanner"
)
func f1(ctx context.Context, client *spanner.Client) {
ro, _ := client.BatchReadOnlyTransaction(ctx, spanner.StrongRead())
if ro != nil {
}
}
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.