-
-
Notifications
You must be signed in to change notification settings - Fork 3k
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
Makefile rework and sharness test coverage #3504
Conversation
0e2682e
to
7bb4c7f
Compare
b051e28
to
bb2575f
Compare
It finally works again. Teamcity OSX and js-ipfs-api test failures are unrelated. 67 commits bye-bye. |
239200b
to
a95f691
Compare
The sharness test with coverage is about 4 to 6 min + 2min for coverage report merge procedure. |
1ed402b
to
a1f4fae
Compare
@lgierth @whyrusleeping this should be ready for CR |
I have figured out smart way to do cross package coverage. The cross package unit test coverage increased the test time only by 10% over normal coverage unit tests. |
I have some experience with Makefiles, I am also going to have a look. |
cmd/ipfs/Rules.mk
Outdated
# DEPS_OO_$(d) += pin/internal/pb/header.pb.go unixfs/pb/unixfs.pb.go | ||
|
||
# uses second expansion to collect all $(DEPS_GO) | ||
$(IPFS_BIN_$(d)): $(d) $$(DEPS_GO) ALWAYS #| $(DEPS_OO_$(d)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I missed the ldflags for the current hash.
Also, this looks like it is going to disrupt my workflow so I want a chance to try it. Added myself as a reviewer. Should be able to look at it this week. |
The makefile is a bit slow. For example:
That is around a second to do nothing. |
@Kubuxu would it be okay if I add some dummy Makefiles in some key sub-directories that just call the top level Makefile? For example I often do:
in the shareness directory. I also sometimes do
within the shareness directory and then run a failing test manually. Now I have to type something a lot longer to get the same effect. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
From what I can tell it looks good. I left two general comments but neither of them are critical.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This PR conflates a lot of real changes with refactor. I would really appreciate breaking this apart into isolated changes as much as we can.
bin/Rules.mk
Outdated
|
||
dist_root_$(d)=/ipfs/QmNZL8wNsvAGdVYr8uGeUE9aGfHjFpHegAWywQFEdSaJbp | ||
|
||
$(d)/gx: $(d)/gx-v0.9.0 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what is d?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See point number 4 in the PR comment.
bin/gen-make-dep-chain
Outdated
@@ -0,0 +1,9 @@ | |||
#!/bin/sh | |||
(for p ; do |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what is going on here? where is p coming from? i'm so confused. what is tac?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This script is not used right now, committed as I thought I would use it, tac
is cat that reverses lines, for p;
is equivalent to for p in "@";
circle.yml
Outdated
@@ -35,6 +35,6 @@ dependencies: | |||
|
|||
test: | |||
override: | |||
- case $CIRCLE_NODE_INDEX in 0) make coverage ;; 1) make test_sharness_expensive ;; esac: | |||
- case $CIRCLE_NODE_INDEX in 0) make -j 1 coverage/unit_tests.coverprofile && bash <(curl -s https://codecov.io/bash) -cF unittests -X search -f coverage/unit_tests.coverprofile;; 1) make -j 1 coverage/sharness_tests.coverprofile && bash <(curl -s https://codecov.io/bash) -cF sharness -X search -f coverage/sharness_tests.coverprofile;; esac: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
does this really need to be a one-liner? Its very... uh... Kubuxuy :P
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I can make it separate script, AFAIK yaml doesn't support multiline keys.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, makes sense. Having it be a separate script (with comments explaining its existence) might help readability a bit
$(COVER_BIN_$(d)): $(d) $$(DEPS_GO) ALWAYS | ||
$(eval TMP_PKGS := $(shell go list -f '{{range .Deps}}{{.}} {{end}}' $(go-flags-with-tags) ./cmd/ipfs | sed 's/ /\n/g' | grep ipfs/go-ipfs | grep -v ipfs/go-ipfs/Godeps) $(call go-pkg-name,$<)) | ||
$(eval TMP_LIST := $(call join-with,$(comma),$(TMP_PKGS))) | ||
@echo go test $@ -c -covermode atomic -coverpkg ... $(go-flags-with-tags) ./$(@D) # for info |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what is @D
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is short form of $(dir $@)
os.Args = append([]string{os.Args[0]}, args...) | ||
ret := mainRet() | ||
|
||
p := os.Getenv("IPFS_COVER_RET_FILE") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what is this used for?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I can't return value from test binary, it has to exit naturally, so I save the to be return value
to a file and return it from wrapper program, coverage/main/main.go
@@ -0,0 +1,8 @@ | |||
include mk/header.mk |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is this include relative to the root dir? That feels really weird...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, the working dir is constant and it is the root dir, the current working dir is under $(d)
.
pin/pin.go
Outdated
os.Exit(1) | ||
msg := "failed to decode empty key constant" | ||
log.Error(msg) | ||
panic(msg) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
whats the reason for this change? I'd prefer not the have the user see an ugly panic stack trace.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I didn't want to exit over there as it would change the coverage, but as it shouldn't happen here I will switch back to Exit
.
fa1ba24
to
3d84db9
Compare
@Kubuxu Is this ready? It seems to be failing on circleCI |
This commit introduces non-recursive Makefile infrastructure that replaces current Makefile infrastructure. It also generally cleanups the Makefiles, separates them into nicer sub-modules and centralizes common operations into single definitions. It allows to depend on any target that is defined in the makefile, this means that for example `gx install` is called once when `make build test_expensive_sharness` is called instead of 4 or 5 times. It also makes the dependencies much cleaner and allows for reuse of modules. For example sharness coverage collection (WIP) uses sharness target with amended PATH, previously it might have been possible but not without wiring in the coverage collection into sharness make runner code. Yes, it is more complex but not much more. There are few rules that have to be followed and few complexities added but IMHO it is worth it. How to NR-make: 1. If make is to generate some file via a target, it MUST be defined in Rules.mk file in the directory of the target. 2. `Rules.mk` file MUST have `include mk/header.mk` statement as the first line and `include mk/footer.mk` statement as the last line (apart from project root `Rules.mk`). 3. It then MUST be included by the closest `Rules.mk` file up the directory tree. 4. Inside a `Rules.mk` special variable accessed as `$(d)` is defined. Its value is current directory, use it so if the `Rules.mk` file is moved in the tree it still works without a problem. Caution: this variable is not available in the recipe part and MUST NOT be used. Use name of the target or prerequisite to extract it if you need it. 5. Make has only one global scope, this means that name conflicts are a thing. Names SHOULD follow `VAR_NAME_$(d)` convention. There are exceptions from this rule in form of well defined global variables. Examples: General lists `TGT_BIN`, `CLEAN`; General targets: `TEST`, `COVERAGE`; General variables: `GOFLAGS`, `DEPS_GO`. 3. Any rules, definitions or variables that fit some family SHOULD be defined in `mk/$family.mk` file and included from project root `Rules.mk` License: MIT Signed-off-by: Jakub Sztandera <kubuxu@protonmail.ch>
License: MIT Signed-off-by: Jakub Sztandera <kubuxu@protonmail.ch>
Figured out the way to do it much more cheaply, only few % overhead over normal coverage. License: MIT Signed-off-by: Jakub Sztandera <kubuxu@protonmail.ch>
License: MIT Signed-off-by: Jakub Sztandera <kubuxu@protonmail.ch>
License: MIT Signed-off-by: Jakub Sztandera <kubuxu@protonmail.ch>
License: MIT Signed-off-by: Jakub Sztandera <kubuxu@protonmail.ch>
License: MIT Signed-off-by: Jakub Sztandera <kubuxu@protonmail.ch>
This reduces flat make time by half License: MIT Signed-off-by: Jakub Sztandera <kubuxu@protonmail.ch>
License: MIT Signed-off-by: Jakub Sztandera <kubuxu@protonmail.ch>
License: MIT Signed-off-by: Jakub Sztandera <kubuxu@protonmail.ch>
The comparison was wrong License: MIT Signed-off-by: Jakub Sztandera <kubuxu@protonmail.ch>
License: MIT Signed-off-by: Jakub Sztandera <kubuxu@protonmail.ch>
License: MIT Signed-off-by: Jakub Sztandera <kubuxu@protonmail.ch>
License: MIT Signed-off-by: Jakub Sztandera <kubuxu@protonmail.ch>
4e496af
to
e5a1097
Compare
License: MIT Signed-off-by: Jakub Sztandera <kubuxu@protonmail.ch>
This last commit explains small issue I had in Jenkins with codecoverage, but because Jenkins doesn't provide require variables in Pipelines we will have to use Circle for time being. |
License: MIT Signed-off-by: Jakub Sztandera <kubuxu@protonmail.ch>
|
||
GOTAGS = | ||
GOTAGS += "" # we have to have always at least one tag, empty tag works well | ||
SHELL=PATH=$(PATH) /bin/sh |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Might this be causing the Windows build issue?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Possibly thanks.
TGTS_$(d) := $(d)/gx $(d)/gx-go | ||
DISTCLEAN += $(wildcard $(d)/gx-v*) $(wildcard $(d)/gx-go-v*) $(d)/tmp | ||
|
||
PATH := $(realpath $(d)):$(PATH) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure if this needs quoting, but it's probably safer to do so.
This PR introduces non-recursive Makefile infrastructure that replaces current Makefile infrastructure.
It also generally cleanups the Makefiles, separates them into nicer sub-modules and centralizes common operations into single definitions.
Why non-recursive Makefile?
It allows to depend on any target that is defined in the makefile, this means that for example
gx install
is called once whenmake build test_expensive_sharness
is called instead of 4 or 5 times.It also makes the dependencies much cleaner and allows for reuse of modules. For example sharness coverage collection uses sharness target with amended PATH, previously it might have been possible but not without wiring the coverage collection into sharness Makefile runner code.
Isn't non-recursive Makefile much more complex?
Yes, it is a bit more complex but not much more. There are few rules that have to be followed and few complexities added but IMHO it is worth it.
How to NR-make:
Rules.mk
file MUST haveinclude mk/header.mk
statement as the first line andinclude mk/footer.mk
statement as the last line (apart from project rootRules.mk
).Rules.mk
file up the directory tree.Rules.mk
special variable accessed as$(d)
is defined. Its value is current directory, use it so if theRules.mk
file is moved in the tree it still works without a problem. Caution: this variable is not available in the recipe part and MUST NOT be used there. Use name of the target or prerequisite to extract it if you need it.VAR_NAME_$(d)
convention. There are exceptions from this rule in form of well defined global variables. Examples: General listsTGT_BIN
,CLEAN
; General targets:TEST
,COVERAGE
; General variables:GOFLAGS
,DEPS_GO
.mk/$family.mk
file and included from project rootRules.mk
(Based on https://evbergen.home.xs4all.nl/nonrecursive-make.html)
Resolves: #3488