ktrysmt/go-bitbucket

Error running list_test

drewmoseley opened this issue · 9 comments

I'm trying to use gickup with my bitbucket account and was having an issue getting it to authenticate properly. I pulled this repo down and attempted to run the tests/list_test.go test and get the following:
$ env | grep BITBUCKET BITBUCKET_TEST_REPOSLUG=drewmoseley/blink BITBUCKET_TEST_OWNER=drewmoseley BITBUCKET_TEST_USERNAME=drewmoseley BITBUCKET_TEST_PASSWORD=redacted $ go test -v ./tests/list_test.go === RUN TestList panic: test timed out after 10m0s <snip>

This is consistent with what I see using gickup so I suspect I am doing something wrong wiith the OWNER or USERNAME field or some such. I used an app password created with all permissions. I get the same behavior whether I use drewmoseley/blink or blink for the REPOSLUG value.

Does anyone have any troubleshooting suggestions here?

@drewmoseley ./tests/list_test.go is listing all repos the owner has.
Therefore, I think it is correct to put only drewmoseley in the BITBUCKET_TEST_REPOSLUG.

That doesn't help. I still seem to lock up when authenticating with the server.

Interestingly I created a new account with a different email address and that one works.

OK. I instrumented the code a bit and what appears to be happening is that this for loop is never exiting. I have about 3 pages of repo when I view it with the web UI.

Oh it is wrong to put yourname in reposlug, the ENV is ignored in the list_test.go.

the for-loop is for pagenation. Perhaps the /repositories api's pagenate is only different from others.

Yeah, that was my expectation. I'm not a Golang programmer nor do I know the bitbucket API so I can't spot anything obviously wrong here. I do see the first time through the loop responsePaginated.Next is pointing at https://api.bitbucket.org/2.0/repositories/drewmoseley?page=2 but even the doRawRequest and the JSON Decode, the Next value is unmodified.

I grabbed a python sample and it does properly iterate through all the pages:

import requests
import json

page = 0
while (True):
    page += 1
    response = requests.request(
        "GET",
        "https://api.bitbucket.org/2.0/repositories/drewmoseley?page=%d" % page,
        auth=('drewmoseley', 'REDACTED')
    )
    respj=json.loads(response.text)
    if "next" not in respj:
        break
    print (respj["page"])
    print (respj["next"])

I've spent some more time digging here and I just cannot understand why pagination is not working here. Using curl returns page 3 as expected:

$ curl -s -u $BITBUCKET_TEST_USERNAME:$BITBUCKET_TEST_PASSWORD https://api.bitbucket.org/2.0/repositories/drewmoseley?page=2 | jq .next
"https://api.bitbucket.org/2.0/repositories/drewmoseley?page=3"

but for some reason the pagination code gets stuck on page 2. When responsePaginated.Next points to page 2, and the new request is created, executed, and the response decoded, responsePaginated.Next is unchanged. Any thoughts?

I've just taken a look at this, and the fix isn't quite right (and actually breaks paging in certain circumstances). The real issue is that the responsePaginated variable is being reused for each request, and the json deserialization doesn't empty out properties that aren't present in the response: https://github.com/ktrysmt/go-bitbucket/blob/master/client.go#L339

So the actual fix is to just allocate a new struct before decoding.

The issue with the current fix is that it breaks for certain page sizes. For example, if you have 13 repos, and a page size of 10, the code only ever requests a single page because 13/10 in integer arithmetic == 1.

I'll push a PR for the fix.