.golangci.yml: enable funlen checker

Checks for too long functions (based on lines and statements).
This commit is contained in:
Dmitry Vyukov 2020-06-04 23:07:55 +02:00
parent 2fcb2b5c16
commit 2b2857bd21
13 changed files with 272 additions and 250 deletions

View File

@ -39,6 +39,7 @@ linters:
- goprintffuncname
- godot
- gocognit
- funlen
disable:
- bodyclose
- depguard
@ -85,6 +86,10 @@ linters-settings:
gocognit:
# TODO: consider reducing this value.
min-complexity: 70
funlen:
# TODO: consider reducing these value.
lines: 200
statements: 80
issues:
exclude-use-default: false

View File

@ -39,6 +39,7 @@ func TestAccessConfig(t *testing.T) {
}
// TestAccess checks that all UIs respect access levels.
// nolint: funlen
func TestAccess(t *testing.T) {
if testing.Short() {
t.Skip()

View File

@ -15,6 +15,7 @@ import (
db "google.golang.org/appengine/datastore"
)
// nolint: funlen
func TestBisectCause(t *testing.T) {
c := NewCtx(t)
defer c.Close()

View File

@ -13,6 +13,7 @@ import (
"github.com/google/syzkaller/pkg/email"
)
// nolint: funlen
func TestEmailReport(t *testing.T) {
c := NewCtx(t)
defer c.Close()

View File

@ -15,6 +15,7 @@ import (
db "google.golang.org/appengine/datastore"
)
// nolint: funlen
func TestJob(t *testing.T) {
c := NewCtx(t)
defer c.Close()

View File

@ -149,184 +149,185 @@ type BisectionTest struct {
culprit int
}
var bisectionTests = []BisectionTest{
// Tests that bisection returns the correct cause commit.
{
name: "cause-finds-cause",
startCommit: 905,
commitLen: 1,
expectRep: true,
culprit: 602,
},
// Tests that cause bisection returns error when crash does not reproduce
// on the original commit.
{
name: "cause-does-not-repro",
startCommit: 400,
expectErr: true,
},
// Tests that no commits are returned when crash occurs on oldest commit
// for cause bisection.
{
name: "cause-crashes-oldest",
startCommit: 905,
commitLen: 0,
expectRep: true,
culprit: 0,
oldestLatest: 400,
},
// Tests that more than 1 commit is returned when cause bisection is inconclusive.
{
name: "cause-inconclusive",
startCommit: 802,
brokenStart: 500,
brokenEnd: 700,
commitLen: 15,
culprit: 605,
},
// Tests that bisection returns the correct fix commit.
{
name: "fix-finds-fix",
fix: true,
startCommit: 400,
commitLen: 1,
culprit: 500,
isRelease: true,
},
// Tests that fix bisection returns error when crash does not reproduce
// on the original commit.
{
name: "fix-does-not-repro",
fix: true,
startCommit: 905,
expectErr: true,
},
// Tests that no commits are returned when crash occurs on HEAD
// for fix bisection.
{
name: "fix-crashes-HEAD",
fix: true,
startCommit: 400,
commitLen: 0,
expectRep: true,
culprit: 1000,
oldestLatest: 905,
},
// Tests that more than 1 commit is returned when fix bisection is inconclusive.
{
name: "fix-inconclusive",
fix: true,
startCommit: 400,
brokenStart: 500,
brokenEnd: 600,
commitLen: 8,
culprit: 501,
},
{
name: "cause-same-binary",
startCommit: 905,
commitLen: 1,
expectRep: true,
culprit: 503,
sameBinaryStart: 502,
sameBinaryEnd: 503,
noopChange: true,
},
{
name: "cause-same-binary-off-by-one",
startCommit: 905,
commitLen: 1,
expectRep: true,
culprit: 503,
sameBinaryStart: 400,
sameBinaryEnd: 502,
},
{
name: "cause-same-binary-off-by-one-2",
startCommit: 905,
commitLen: 1,
expectRep: true,
culprit: 503,
sameBinaryStart: 503,
sameBinaryEnd: 905,
},
{
name: "fix-same-binary",
fix: true,
startCommit: 400,
commitLen: 1,
culprit: 503,
sameBinaryStart: 502,
sameBinaryEnd: 504,
noopChange: true,
},
{
name: "cause-same-binary-release1",
startCommit: 905,
commitLen: 1,
expectRep: true,
culprit: 500,
sameBinaryStart: 405,
sameBinaryEnd: 500,
noopChange: true,
isRelease: true,
},
{
name: "cause-same-binary-release2",
startCommit: 905,
commitLen: 1,
expectRep: true,
culprit: 501,
sameBinaryStart: 500,
sameBinaryEnd: 501,
noopChange: true,
},
{
name: "cause-same-binary-release3",
startCommit: 905,
commitLen: 1,
expectRep: true,
culprit: 405,
sameBinaryStart: 404,
sameBinaryEnd: 405,
noopChange: true,
},
{
name: "fix-same-binary-last",
fix: true,
startCommit: 400,
commitLen: 1,
culprit: 905,
sameBinaryStart: 904,
sameBinaryEnd: 905,
noopChange: true,
},
{
name: "fix-release",
fix: true,
startCommit: 400,
commitLen: 1,
culprit: 900,
isRelease: true,
},
{
name: "cause-not-in-previous-release-issue-1527",
startCommit: 905,
culprit: 650,
commitLen: 1,
expectRep: true,
sameBinaryStart: 500,
sameBinaryEnd: 650,
noopChange: true,
},
}
func TestBisectionResults(t *testing.T) {
t.Parallel()
tests := []BisectionTest{
// Tests that bisection returns the correct cause commit.
{
name: "cause-finds-cause",
startCommit: 905,
commitLen: 1,
expectRep: true,
culprit: 602,
},
// Tests that cause bisection returns error when crash does not reproduce
// on the original commit.
{
name: "cause-does-not-repro",
startCommit: 400,
expectErr: true,
},
// Tests that no commits are returned when crash occurs on oldest commit
// for cause bisection.
{
name: "cause-crashes-oldest",
startCommit: 905,
commitLen: 0,
expectRep: true,
culprit: 0,
oldestLatest: 400,
},
// Tests that more than 1 commit is returned when cause bisection is inconclusive.
{
name: "cause-inconclusive",
startCommit: 802,
brokenStart: 500,
brokenEnd: 700,
commitLen: 15,
culprit: 605,
},
// Tests that bisection returns the correct fix commit.
{
name: "fix-finds-fix",
fix: true,
startCommit: 400,
commitLen: 1,
culprit: 500,
isRelease: true,
},
// Tests that fix bisection returns error when crash does not reproduce
// on the original commit.
{
name: "fix-does-not-repro",
fix: true,
startCommit: 905,
expectErr: true,
},
// Tests that no commits are returned when crash occurs on HEAD
// for fix bisection.
{
name: "fix-crashes-HEAD",
fix: true,
startCommit: 400,
commitLen: 0,
expectRep: true,
culprit: 1000,
oldestLatest: 905,
},
// Tests that more than 1 commit is returned when fix bisection is inconclusive.
{
name: "fix-inconclusive",
fix: true,
startCommit: 400,
brokenStart: 500,
brokenEnd: 600,
commitLen: 8,
culprit: 501,
},
{
name: "cause-same-binary",
startCommit: 905,
commitLen: 1,
expectRep: true,
culprit: 503,
sameBinaryStart: 502,
sameBinaryEnd: 503,
noopChange: true,
},
{
name: "cause-same-binary-off-by-one",
startCommit: 905,
commitLen: 1,
expectRep: true,
culprit: 503,
sameBinaryStart: 400,
sameBinaryEnd: 502,
},
{
name: "cause-same-binary-off-by-one-2",
startCommit: 905,
commitLen: 1,
expectRep: true,
culprit: 503,
sameBinaryStart: 503,
sameBinaryEnd: 905,
},
{
name: "fix-same-binary",
fix: true,
startCommit: 400,
commitLen: 1,
culprit: 503,
sameBinaryStart: 502,
sameBinaryEnd: 504,
noopChange: true,
},
{
name: "cause-same-binary-release1",
startCommit: 905,
commitLen: 1,
expectRep: true,
culprit: 500,
sameBinaryStart: 405,
sameBinaryEnd: 500,
noopChange: true,
isRelease: true,
},
{
name: "cause-same-binary-release2",
startCommit: 905,
commitLen: 1,
expectRep: true,
culprit: 501,
sameBinaryStart: 500,
sameBinaryEnd: 501,
noopChange: true,
},
{
name: "cause-same-binary-release3",
startCommit: 905,
commitLen: 1,
expectRep: true,
culprit: 405,
sameBinaryStart: 404,
sameBinaryEnd: 405,
noopChange: true,
},
{
name: "fix-same-binary-last",
fix: true,
startCommit: 400,
commitLen: 1,
culprit: 905,
sameBinaryStart: 904,
sameBinaryEnd: 905,
noopChange: true,
},
{
name: "fix-release",
fix: true,
startCommit: 400,
commitLen: 1,
culprit: 900,
isRelease: true,
},
{
name: "cause-not-in-previous-release-issue-1527",
startCommit: 905,
culprit: 650,
commitLen: 1,
expectRep: true,
sameBinaryStart: 500,
sameBinaryEnd: 650,
noopChange: true,
},
}
// Creating new repos takes majority of the test time,
// so we reuse them across tests.
repoCache := make(chan string, len(tests))
repoCache := make(chan string, len(bisectionTests))
t.Run("group", func(t *testing.T) {
for _, test := range tests {
for _, test := range bisectionTests {
test := test
t.Run(test.name, func(t *testing.T) {
t.Parallel()

View File

@ -37,9 +37,30 @@ func TestCompilerIdentity(t *testing.T) {
}
func TestExtractRootCause(t *testing.T) {
// nolint: lll
for i, test := range []struct{ e, reason, src, file string }{
{`
for i, test := range rootCauseTests {
test := test
t.Run(fmt.Sprint(i), func(t *testing.T) {
reason, file := extractCauseInner([]byte(test.e), test.src)
if test.reason != string(reason) {
t.Errorf("expected:\n%s\ngot:\n%s", test.reason, reason)
}
if test.file != file {
t.Errorf("expected file: %q, got: %q", test.file, file)
}
})
}
}
type RootCauseTest struct {
e string
reason string
src string
file string
}
// nolint: lll
var rootCauseTests = []RootCauseTest{
{`
LINK /home/dvyukov/src/linux2/tools/objtool/objtool
MKELF scripts/mod/elfconfig.h
HOSTCC scripts/mod/modpost.o
@ -52,11 +73,11 @@ func TestExtractRootCause(t *testing.T) {
UPD include/generated/asm-offsets.h
CALL scripts/checksyscalls.sh
`,
"",
"",
"",
},
{`
"",
"",
"",
},
{`
cc -g -Werror db_break.c
sys/dev/kcov.c:93:6: error: use of undeclared identifier 'kcov_cold123'; did you mean 'kcov_cold'?
if (kcov_cold123)
@ -67,11 +88,11 @@ int kcov_cold = 1;
^
1 error generated.
`,
"sys/dev/kcov.c:93:6: error: use of undeclared identifier 'kcov_cold123'; did you mean 'kcov_cold'?",
"",
"sys/dev/kcov.c",
},
{`
"sys/dev/kcov.c:93:6: error: use of undeclared identifier 'kcov_cold123'; did you mean 'kcov_cold'?",
"",
"sys/dev/kcov.c",
},
{`
CC /tools/objtool/parse-options.o
In file included from ./scripts/gcc-plugins/gcc-common.h:119:0,
from <stdin>:1:
@ -83,11 +104,11 @@ make: *** [gcc-plugins-check] Error 1
make: *** Waiting for unfinished jobs....
UPD include/config/kernel.release
`,
"/gcc-5.5.0/bin/../lib/gcc/x86_64-unknown-linux-gnu/5.5.0/plugin/include/builtins.h:23:17: fatal error: mpc.h: No such file or directory",
"",
"",
},
{`
"/gcc-5.5.0/bin/../lib/gcc/x86_64-unknown-linux-gnu/5.5.0/plugin/include/builtins.h:23:17: fatal error: mpc.h: No such file or directory",
"",
"",
},
{`
Starting local Bazel server and connecting to it...
Loading:
Loading: 0 packages loaded
@ -103,13 +124,13 @@ INFO: Elapsed time: 14.914s
INFO: 0 processes.
FAILED: Build did NOT complete successfully (189 packages loaded)
`,
`ERROR: /kernel/vdso/BUILD:13:1: no such target '@bazel_tools//tools/cpp:cc_flags': target 'cc_flags' not declared in package 'tools/cpp' defined by /syzkaller/home/.cache/bazel/_bazel_root/e1c9d86bae2b34f90e83d224bc900958/external/bazel_tools/tools/cpp/BUILD and referenced by '//vdso:vdso'
`ERROR: /kernel/vdso/BUILD:13:1: no such target '@bazel_tools//tools/cpp:cc_flags': target 'cc_flags' not declared in package 'tools/cpp' defined by /syzkaller/home/.cache/bazel/_bazel_root/e1c9d86bae2b34f90e83d224bc900958/external/bazel_tools/tools/cpp/BUILD and referenced by '//vdso:vdso'
ERROR: Analysis of target '//runsc:runsc' failed; build aborted: Analysis failed
FAILED: Build did NOT complete successfully (189 packages loaded)`,
"",
"",
},
{`
"",
"",
},
{`
ld -T ld.script -X --warn-common -nopie -o bsd ${SYSTEM_HEAD} vers.o ${OBJS}
ld: error: undefined symbol: __stack_smash_handler
>>> referenced by bktr_card.c:0 (/kernel/sys/dev/pci/bktr/bktr_card.c:0)
@ -126,12 +147,12 @@ ld: error: undefined symbol: __stack_smash_handler
ld: error: too many errors emitted, stopping now (use -error-limit=0 to see all errors)
*** Error 1 in /kernel/sys/arch/amd64/compile/SYZKALLER (Makefile:991 'bsd': @echo ld -T ld.script -X --warn-commo...)
`,
`ld: error: undefined symbol: __stack_smash_handler
`ld: error: undefined symbol: __stack_smash_handler
ld: error: too many errors emitted, stopping now (use -error-limit=0 to see all errors)`,
"",
"",
},
{`
"",
"",
},
{`
make: execvp: /gcc-5.5.0/bin/gcc: Permission denied
scripts/kconfig/conf --silentoldconfig Kconfig
arch/x86/Makefile:123: stack-protector enabled but compiler support broken
@ -161,13 +182,13 @@ make: *** [scripts] Error 2
make: *** Waiting for unfinished jobs....
HOSTLD arch/x86/tools/relocs
`,
`make: execvp: /gcc-5.5.0/bin/gcc: Permission denied
`make: execvp: /gcc-5.5.0/bin/gcc: Permission denied
scripts/xen-hypercalls.sh: line 7: /gcc-5.5.0/bin/gcc: Permission denied
/bin/sh: 1: /gcc-5.5.0/bin/gcc: Permission denied`,
"",
"",
},
{`
"",
"",
},
{`
./arch/x86/include/asm/nospec-branch.h:360:1: warning: data definition has no type or storage class
360 | DECLARE_STATIC_KEY_FALSE(mds_user_clear);
| ^~~~~~~~~~~~~~~~~~~~~~~~
@ -189,10 +210,10 @@ make: *** [prepare0] Error 2
`, `./arch/x86/include/asm/nospec-branch.h:360:1: error: type defaults to 'int' in declaration of 'DECLARE_STATIC_KEY_FALSE' [-Werror=implicit-int]
./arch/x86/include/asm/nospec-branch.h:394:6: error: implicit declaration of function 'static_branch_likely' [-Werror=implicit-function-declaration]
./arch/x86/include/asm/nospec-branch.h:394:28: error: 'mds_user_clear' undeclared (first use in this function)`,
"/some/unrelated/path",
"arch/x86/include/asm/nospec-branch.h",
},
{`
"/some/unrelated/path",
"arch/x86/include/asm/nospec-branch.h",
},
{`
CC fs/notify/group.o
CC lib/zlib_deflate/deftree.o
CC net/ipv4/devinet.o
@ -216,11 +237,11 @@ make[1]: *** Waiting for unfinished jobs....
CC arch/x86/kernel/apic/ipi.o
CC sound/hda/hdac_controller.o
`,
"kernel/rcu/tasks.h:1070:37: error: 'rcu_tasks_rude' undeclared (first use in this function); did you mean 'rcu_tasks_qs'?",
"",
"kernel/rcu/tasks.h",
},
{`
"kernel/rcu/tasks.h:1070:37: error: 'rcu_tasks_rude' undeclared (first use in this function); did you mean 'rcu_tasks_qs'?",
"",
"kernel/rcu/tasks.h",
},
{`
CC arch/x86/boot/compressed/kaslr.o
AS arch/x86/boot/compressed/mem_encrypt.o
CC arch/x86/boot/compressed/kaslr_64.o
@ -312,12 +333,12 @@ make[1]: *** [arch/x86/boot/compressed/vmlinux] Error 2
arch/x86/Makefile:284: recipe for target 'bzImage' failed
make: *** [bzImage] Error 2
`,
`clang-10: error: unable to execute command: Aborted (core dumped)
`clang-10: error: unable to execute command: Aborted (core dumped)
clang-10: error: clang integrated assembler command failed due to signal (use -v to see invocation)`,
"",
"",
},
{`
"",
"",
},
{`
scripts/kconfig/conf --syncconfig Kconfig
DESCEND objtool
CALL scripts/atomic/check-atomics.sh
@ -340,20 +361,20 @@ arch/x86/platform/efi/efi_64.o: In function 'efi_set_virtual_address_map':
Makefile:1078: recipe for target 'vmlinux' failed
make: *** [vmlinux] Error 1
`,
`arch/x86/platform/efi/efi_64.c:560: undefined reference to '__efi64_thunk'
`arch/x86/platform/efi/efi_64.c:560: undefined reference to '__efi64_thunk'
arch/x86/platform/efi/efi_64.c:902: undefined reference to 'efi_uv1_memmap_phys_prolog'
arch/x86/platform/efi/efi_64.c:921: undefined reference to 'efi_uv1_memmap_phys_epilog'`,
"/syzkaller/managers/upstream-linux-next-kasan-gce-root/kernel",
"arch/x86/platform/efi/efi_64.c",
},
{`
"/syzkaller/managers/upstream-linux-next-kasan-gce-root/kernel",
"arch/x86/platform/efi/efi_64.c",
},
{`
/syzkaller/managers/upstream-linux-next-kasan-gce-root/kernel/arch/x86/platform/efi/efi_64.c:560: undefined reference to '__efi64_thunk'
`,
`arch/x86/platform/efi/efi_64.c:560: undefined reference to '__efi64_thunk'`,
"/syzkaller/managers/upstream-linux-next-kasan-gce-root/kernel/",
"arch/x86/platform/efi/efi_64.c",
},
{`
`arch/x86/platform/efi/efi_64.c:560: undefined reference to '__efi64_thunk'`,
"/syzkaller/managers/upstream-linux-next-kasan-gce-root/kernel/",
"arch/x86/platform/efi/efi_64.c",
},
{`
CC net/ipv6/ip6_output.o
CC security/selinux/ss/policydb.o
CC net/ipv4/route.o
@ -390,20 +411,8 @@ make[1]: *** Waiting for unfinished jobs....
CC net/netlabel/netlabel_domainhash.o
CC net/netlabel/netlabel_addrlist.o
`,
"./include/linux/netfilter_ipv6.h:110:9: error: implicit declaration of function 'nf_ct_frag6_gather' [-Werror=implicit-function-declaration]",
"",
"include/linux/netfilter_ipv6.h",
},
} {
test := test
t.Run(fmt.Sprint(i), func(t *testing.T) {
reason, file := extractCauseInner([]byte(test.e), test.src)
if test.reason != string(reason) {
t.Errorf("expected:\n%s\ngot:\n%s", test.reason, reason)
}
if test.file != file {
t.Errorf("expected file: %q, got: %q", test.file, file)
}
})
}
"./include/linux/netfilter_ipv6.h:110:9: error: implicit declaration of function 'nf_ct_frag6_gather' [-Werror=implicit-function-declaration]",
"",
"include/linux/netfilter_ipv6.h",
},
}

View File

@ -10,7 +10,7 @@ import (
// Decode decodes instruction length for the given mode.
// It can have falsely decode incorrect instructions,
// but should not fail to decode correct instructions.
// nolint: gocyclo, nestif, gocognit
// nolint: gocyclo, nestif, gocognit, funlen
func Decode(mode int, text []byte) (int, error) {
if len(text) == 0 {
return 0, fmt.Errorf("zero-length instruction")

View File

@ -11,7 +11,7 @@ import (
"math/rand"
)
// nolint: gocyclo, nestif, gocognit
// nolint: gocyclo, nestif, gocognit, funlen
func (insn *Insn) Encode(cfg *Config, r *rand.Rand) []byte {
if !insn.isCompatible(cfg) {
panic("instruction is not suitable for this mode")

View File

@ -17,7 +17,7 @@ import (
"github.com/google/syzkaller/pkg/serializer"
)
// nolint: gocyclo, gocognit
// nolint: gocyclo, gocognit, funlen
func main() {
if len(os.Args) != 2 {
failf("usage: gen instructions.txt")
@ -180,7 +180,7 @@ func (err errSkip) Error() string {
return string(err)
}
// nolint: gocyclo, gocognit
// nolint: gocyclo, gocognit, funlen
func parsePattern(insn *ifuzz.Insn, vals []string) error {
if insn.Opcode != nil {
return fmt.Errorf("PATTERN is already parsed for the instruction")

View File

@ -7,6 +7,7 @@ import (
"math/rand"
)
// nolint: funlen
func initPseudo() {
Insns = append(Insns, &Insn{
Name: "PSEUDO_RDMSR",

View File

@ -28,6 +28,7 @@ func TestSerializeForExecRandom(t *testing.T) {
}
}
// nolint: funlen
func TestSerializeForExec(t *testing.T) {
target := initTargetTest(t, "test", "64")
var (

View File

@ -102,6 +102,7 @@ const (
OutputFile
)
// nolint: funlen
func main() {
debug.SetGCPercent(50)