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

Use alpine images to make tests take less time #629

Merged
merged 7 commits into from
Jan 2, 2018
Merged

Conversation

denismakogon
Copy link
Member

  • use PG alpine
  • use Minio alpine
  • no official alpine distro for MySQL, uhhh :(
  • install swagger tool instead of docker image
  • use retry func to confirm that datastore is okay before running tests

@denismakogon
Copy link
Member Author

Reverting minio image:

docker images | grep minio
minio/minio                   latest              4110ee55fc11        4 weeks ago         27.3MB
webcenter/alpine-minio        latest              49c8f4547226        7 weeks ago         82.3MB

@denismakogon
Copy link
Member Author

Not sure what we can do with mysql image, which is 408Mb, mysql docker community has done zero to build on alpine by this time.

PG alpine size made me happy, really:

docker images | grep postgres
postgres                      latest              ec61d13c8566        12 days ago         287MB
postgres                      9.3-alpine          0350272b4017        2 weeks ago         35.5MB

So, the time difference is not that huge at this moment, but a good thing to have along with #624.

helpers.sh Outdated
docker rm -fv func-minio-test 2>/dev/null || true
}

function install_swagger_tool {
Copy link
Contributor

Choose a reason for hiding this comment

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

https://github.com/swagger-api/validator-badge seems to outline a way to send a file to a service running a swagger validator. the badge would be a nice addition, but sending our file to a validator service seems much cleaner than us downloading a binary every build, if anything because in theory the service will ensure we keep up to date with the latest swagger spec and here we have to manually keep the binary version up to date.

Copy link
Member Author

Choose a reason for hiding this comment

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

Well, the badge is a good thing, but it's not related to this PR, but what if I want to modify swagger how can know if that is okay?

I can add the badge, but we do know that github cache works really slow, we've seen that couple times with swagger that's why we use huge docker image with swagger tool only to validate our swagger doc through the mounted file:

docker run -v /Users/denismakogon/Documents/oracle/go/src/github.com/fnproject/fn:/go/src/github.com/fnproject/fn --rm quay.io/goswagger/swagger validate /go/src/github.com/fnproject/fn/docs/swagger.yml

The point of downloading binary is to reduce the time of swagger doc validation.
FYI, the swagger tool image is 493MB, swagger tool binary ~2MB.

Copy link
Contributor

Choose a reason for hiding this comment

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

Not worried about the badge so much here, it would be nice to have separate from this. We can send the file from on disk inside of CI to the swagger server listed from that link for validation (I think), which requires no binary download and then we don't have to worry about versioning of the binary. If we change swagger we had the same issue with the image previously, I don't think this is much of a concern vs us lagging behind swagger updates by manually downloading the binary.

Copy link
Member Author

@denismakogon denismakogon Dec 27, 2017

Choose a reason for hiding this comment

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

Unfortunately, recommended method (posting swagger doc as the payload) doesn't work:

curl -v -X POST -d @docs/swagger.yml -H 'Content-Type:application/json' http://online.swagger.io/validator/debug
Note: Unnecessary use of -X or --request, POST is already inferred.
*   Trying 23.22.16.221...
* TCP_NODELAY set
* Connected to online.swagger.io (23.22.16.221) port 80 (#0)
> POST /validator/debug HTTP/1.1
> Host: online.swagger.io
> User-Agent: curl/7.54.0
> Accept: */*
> Content-Type:application/json
> Content-Length: 19268
> Expect: 100-continue
> 
< HTTP/1.1 100 Continue
* We are completely uploaded and fine
< HTTP/1.1 500 Internal Server Error
< Date: Wed, 27 Dec 2017 16:19:42 GMT
< Access-Control-Allow-Origin: *
< Access-Control-Allow-Methods: GET, POST, DELETE, PUT
< Access-Control-Allow-Headers: Content-Type
< Content-Type: text/html; charset=ISO-8859-1
< Cache-Control: must-revalidate,no-cache,no-store
< Content-Length: 323
< Connection: close
< Server: Jetty(9.2.9.v20150224)
< 
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<title>Error 500 Internal Server Error</title>
</head>
<body><h2>HTTP ERROR 500</h2>
<p>Problem accessing /validator/debug. Reason:
<pre>    Internal Server Error</pre></p><hr><i><small>Powered by Jetty://</small></i><hr/>

</body>
</html>
* Closing connection 0

so, leaving as is.

Copy link
Contributor

Choose a reason for hiding this comment

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

Ok, next idea: can we build a smaller swagger image with that binary to use instead?

func retryDBConnection(t *testing.T, attempts int, sleep time.Duration, dbURL *url.URL) (err error) {
for i := 0; i < attempts; i++ {
t.Logf("[%v] - attempting to reach out datastore %v", i, dbURL.String())
_, err = newDS(dbURL)
Copy link
Contributor

Choose a reason for hiding this comment

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

this generates a lot of new db instances, which isn't really cheap afaik and also doesn't really ensure that the datastore instance we're going to actually use is valid and adds extra code in the db initialization caller path to call retryDBConnection. is there any reason not to do just do this in our db initialization ping inside of the sql package?

Copy link
Member Author

Choose a reason for hiding this comment

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

fixed, see #630, I'll rebase this PR to that branch.

@rdallman
Copy link
Contributor

Not sure what we can do with mysql image, which is 408Mb, mysql docker community has done zero to build on alpine by this time.

i might piddle around with this, it shouldn't be too bad to get all the deps into alpine but sometimes it is.

Copy link
Contributor

@rdallman rdallman left a comment

Choose a reason for hiding this comment

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

I'm OK with the pg image change but the rest of the changes I'm less sure of, esp. if we're not getting a lot of benefit.

@rdallman rdallman mentioned this pull request Dec 26, 2017
@rdallman
Copy link
Contributor

i might piddle around with this, it shouldn't be too bad to get all the deps into alpine but sometimes it is.

found docker-library/mysql#179 -- we can try to poke the right people internally to get this supported, it appears to work now but need to have release track to follow.

@denismakogon
Copy link
Member Author

@rdallman i'll address all comments except swagger tool change. Regarding the MySQL alpine image, we might ask @mattlord for help.

@denismakogon
Copy link
Member Author

@rdallman I pushed the image to my own docker repo: denismakogon/swagger-tool:0.0.1. Dockerfile you can find in-tree.
It's not 2Mb size, but 30Mb. Still better than 0.5Gb.

@treeder
Copy link
Contributor

treeder commented Jan 2, 2018

How about add it to fnproject/dockers ? Or at least we need the Dockerfile and build scripts public.

@denismakogon
Copy link
Member Author

Sure, can submit there.

@denismakogon
Copy link
Member Author

@skinowski
Copy link
Member

Kind of unrelated, but we should eventually be able to get rid of sleeper, hello and error images as fn-test-utils can perform same functionality. I tried removing these with one PR, but I quickly realized it's more work than I anticipated.

.gitignore Outdated
@@ -33,3 +33,4 @@ fnlb/fnlb
.idea/
*iml
target/
swagger
Copy link
Contributor

Choose a reason for hiding this comment

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

can remove this change now

Copy link
Contributor

@rdallman rdallman left a comment

Choose a reason for hiding this comment

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

needs rebase, but LGTM

 - implements retry func specifically for SQL datastore ping
 - fmt fixes
 - using sqlx.Db.PingContext instead of sqlx.Db.Ping
 - propogate context to SQL datastore
 * use PG alpine
 * use Minio alpine
 * no official alpine distro for MySQL, uhhh :(
 * install swagger tool instead of docker image
 * use retry func to confirm that datastore is okay before running tests
 somehow it's a problem to put binary to ${GOPATH}/bin
@denismakogon
Copy link
Member Author

Rebased.

@denismakogon
Copy link
Member Author

Nice, we're at 07:46, which is good. Is there anything else that we can speed up?

@rdallman rdallman merged commit 4bb0744 into master Jan 2, 2018
@rdallman rdallman deleted the small-images branch January 2, 2018 20:56
@rdallman
Copy link
Contributor

rdallman commented Jan 2, 2018

  • we could play with caching the static library files between runs. 99.9% of the time they don't change, and go install takes about a minute, and should handle building new versions only when it needs to.
  • seems like reducing tests down to one image could save maybe 30s or so, per Use alpine images to make tests take less time #629 (comment)
  • we're building the release docker image on branches even though we don't use it for anything, we only need to do this on master. that's 2 minutes.

seems like we could get under 5 minutes pretty easily.

@rdallman
Copy link
Contributor

rdallman commented Jan 2, 2018

we're also installing new docker version every time, that's 1 minute. maybe we could cache that, too

at least, we could have it in a .deb pack we could just dpkg -i it, that we could cache

@skinowski
Copy link
Member

+1 on "go install", that should shave extensions/middleware building time as well.

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