From 9d167cd5e8a77c8236334b45200ad250b592c0f3 Mon Sep 17 00:00:00 2001 From: Juan Batiz-Benet Date: Mon, 2 Mar 2015 01:58:54 -0800 Subject: [PATCH 1/9] testfix: dont break 8k goroutine limit under race --- Godeps/Godeps.json | 4 +++ .../github.com/jbenet/go-detect-race/LICENSE | 21 ++++++++++++ .../jbenet/go-detect-race/README.md | 33 +++++++++++++++++++ .../github.com/jbenet/go-detect-race/race.go | 7 ++++ .../jbenet/go-detect-race/race_test.go | 9 +++++ .../jbenet/go-detect-race/withoutrace.go | 5 +++ .../jbenet/go-detect-race/withrace.go | 5 +++ exchange/bitswap/bitswap_test.go | 10 +++++- 8 files changed, 93 insertions(+), 1 deletion(-) create mode 100644 Godeps/_workspace/src/github.com/jbenet/go-detect-race/LICENSE create mode 100644 Godeps/_workspace/src/github.com/jbenet/go-detect-race/README.md create mode 100644 Godeps/_workspace/src/github.com/jbenet/go-detect-race/race.go create mode 100644 Godeps/_workspace/src/github.com/jbenet/go-detect-race/race_test.go create mode 100644 Godeps/_workspace/src/github.com/jbenet/go-detect-race/withoutrace.go create mode 100644 Godeps/_workspace/src/github.com/jbenet/go-detect-race/withrace.go diff --git a/Godeps/Godeps.json b/Godeps/Godeps.json index 912742a38..a0eacf5b6 100644 --- a/Godeps/Godeps.json +++ b/Godeps/Godeps.json @@ -151,6 +151,10 @@ "ImportPath": "github.com/jbenet/go-datastore", "Rev": "35738aceb35505bd3c77c2a618fb1947ca3f72da" }, + { + "ImportPath": "github.com/jbenet/go-detect-race", + "Rev": "3463798d9574bd0b7eca275dccc530804ff5216f" + }, { "ImportPath": "github.com/jbenet/go-fuse-version", "Rev": "b733dfc0597e1f6780510ee7afad8b6e3c7af3eb" diff --git a/Godeps/_workspace/src/github.com/jbenet/go-detect-race/LICENSE b/Godeps/_workspace/src/github.com/jbenet/go-detect-race/LICENSE new file mode 100644 index 000000000..c7386b3c9 --- /dev/null +++ b/Godeps/_workspace/src/github.com/jbenet/go-detect-race/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2014 Juan Batiz-Benet + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/Godeps/_workspace/src/github.com/jbenet/go-detect-race/README.md b/Godeps/_workspace/src/github.com/jbenet/go-detect-race/README.md new file mode 100644 index 000000000..0ba69b7b0 --- /dev/null +++ b/Godeps/_workspace/src/github.com/jbenet/go-detect-race/README.md @@ -0,0 +1,33 @@ +# go-detect-race + +Check if the race detector is running. + +I didnt find a variable to check quickly enough so I made this. + + +## Usage + +```go +import ( + detectrace "github.com/jbenet/go-detect-race" +) + +func main() { + if detectrace.WithRace() { + // running with -race + } else { + // running without -race + } +} +``` + +## Why? + +Because the race detector doesnt like massive stress tests. Example: +https://groups.google.com/forum/#!topic/golang-nuts/XDPHUt2LE70 + +## Why didn't you just use... + +Please tell me about a better way of doing this. It wasn't +readily apparent to me, so I made this. But i would much prefer +an env var or some already existing var from the stdlib :) diff --git a/Godeps/_workspace/src/github.com/jbenet/go-detect-race/race.go b/Godeps/_workspace/src/github.com/jbenet/go-detect-race/race.go new file mode 100644 index 000000000..04639f4bb --- /dev/null +++ b/Godeps/_workspace/src/github.com/jbenet/go-detect-race/race.go @@ -0,0 +1,7 @@ +package detectrace + +// WithRace returns whether the binary was compiled +// with the race flag on. +func WithRace() bool { + return withRace +} diff --git a/Godeps/_workspace/src/github.com/jbenet/go-detect-race/race_test.go b/Godeps/_workspace/src/github.com/jbenet/go-detect-race/race_test.go new file mode 100644 index 000000000..2663ba39d --- /dev/null +++ b/Godeps/_workspace/src/github.com/jbenet/go-detect-race/race_test.go @@ -0,0 +1,9 @@ +package detectrace + +import ( + "testing" +) + +func TestWithRace(t *testing.T) { + t.Logf("WithRace() is %v\n", WithRace()) +} diff --git a/Godeps/_workspace/src/github.com/jbenet/go-detect-race/withoutrace.go b/Godeps/_workspace/src/github.com/jbenet/go-detect-race/withoutrace.go new file mode 100644 index 000000000..958498bbe --- /dev/null +++ b/Godeps/_workspace/src/github.com/jbenet/go-detect-race/withoutrace.go @@ -0,0 +1,5 @@ +// +build !race + +package detectrace + +const withRace = false diff --git a/Godeps/_workspace/src/github.com/jbenet/go-detect-race/withrace.go b/Godeps/_workspace/src/github.com/jbenet/go-detect-race/withrace.go new file mode 100644 index 000000000..59f0b03dc --- /dev/null +++ b/Godeps/_workspace/src/github.com/jbenet/go-detect-race/withrace.go @@ -0,0 +1,5 @@ +// +build race + +package detectrace + +const withRace = true diff --git a/exchange/bitswap/bitswap_test.go b/exchange/bitswap/bitswap_test.go index 781bde91f..21ad69dfb 100644 --- a/exchange/bitswap/bitswap_test.go +++ b/exchange/bitswap/bitswap_test.go @@ -6,7 +6,9 @@ import ( "testing" "time" + detectrace "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-detect-race" context "github.com/jbenet/go-ipfs/Godeps/_workspace/src/golang.org/x/net/context" + blocks "github.com/jbenet/go-ipfs/blocks" blocksutil "github.com/jbenet/go-ipfs/blocks/blocksutil" tn "github.com/jbenet/go-ipfs/exchange/bitswap/testnet" @@ -93,9 +95,15 @@ func TestLargeSwarm(t *testing.T) { if testing.Short() { t.SkipNow() } - t.Parallel() numInstances := 500 numBlocks := 2 + if detectrace.WithRace() { + // when running with the race detector, 500 instances launches + // well over 8k goroutines. This hits a race detector limit. + numInstances = 100 + } else { + t.Parallel() + } PerformDistributionTest(t, numInstances, numBlocks) } From f77dbe0a57052a88660d8b2bbf61be6092226347 Mon Sep 17 00:00:00 2001 From: Juan Batiz-Benet Date: Mon, 2 Mar 2015 05:18:45 -0800 Subject: [PATCH 2/9] fuse/ipns: implement NodeReadlinker --- fuse/ipns/link_unix.go | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/fuse/ipns/link_unix.go b/fuse/ipns/link_unix.go index 209849679..2b3bd0065 100644 --- a/fuse/ipns/link_unix.go +++ b/fuse/ipns/link_unix.go @@ -4,6 +4,7 @@ import ( "os" "github.com/jbenet/go-ipfs/Godeps/_workspace/src/bazil.org/fuse" + "github.com/jbenet/go-ipfs/Godeps/_workspace/src/bazil.org/fuse/fs" "github.com/jbenet/go-ipfs/Godeps/_workspace/src/golang.org/x/net/context" ) @@ -18,7 +19,9 @@ func (l *Link) Attr() fuse.Attr { } } -func (l *Link) Readlink(req *fuse.ReadlinkRequest, ctx context.Context) (string, error) { +func (l *Link) Readlink(ctx context.Context, req *fuse.ReadlinkRequest) (string, error) { log.Debugf("ReadLink: %s", l.Target) return l.Target, nil } + +var _ fs.NodeReadlinker = (*Link)(nil) From 38425b1a06514265f0944fb129b4a47fb59789fd Mon Sep 17 00:00:00 2001 From: Juan Batiz-Benet Date: Mon, 2 Mar 2015 06:12:54 -0800 Subject: [PATCH 3/9] fuse: fix read problem in osx @whyrusleeping's fix in c88340b broke reading fuse in osx. i'm not sure why... anyway, i chose to revert back to io.ReadFull, but use the min of req.Size and r.Size(), which should not encounter the reading problem in linux that a77ea2f fixed in the first place. This commit also changes ipns, which had not been changed. --- fuse/ipns/ipns_unix.go | 11 ++++++++++- fuse/readonly/readonly_unix.go | 13 ++++++++++--- 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/fuse/ipns/ipns_unix.go b/fuse/ipns/ipns_unix.go index 2ced56339..edb126f6c 100644 --- a/fuse/ipns/ipns_unix.go +++ b/fuse/ipns/ipns_unix.go @@ -354,7 +354,9 @@ func (s *Node) Read(ctx context.Context, req *fuse.ReadRequest, resp *fuse.ReadR if err != nil { return err } - n, err := io.ReadFull(r, resp.Data[:req.Size]) + + buf := resp.Data[:min(req.Size, int(r.Size()))] + n, err := io.ReadFull(r, buf) resp.Data = resp.Data[:n] lm["res_size"] = n return err // may be non-nil / not succeeded @@ -652,3 +654,10 @@ type ipnsNode interface { } var _ ipnsNode = (*Node)(nil) + +func min(a, b int) int { + if a < b { + return a + } + return b +} diff --git a/fuse/readonly/readonly_unix.go b/fuse/readonly/readonly_unix.go index 543ec0d4a..ed4b80f5d 100644 --- a/fuse/readonly/readonly_unix.go +++ b/fuse/readonly/readonly_unix.go @@ -5,7 +5,6 @@ package readonly import ( - "bytes" "io" "os" @@ -169,8 +168,9 @@ func (s *Node) Read(ctx context.Context, req *fuse.ReadRequest, resp *fuse.ReadR if err != nil { return err } - buf := bytes.NewBuffer(resp.Data) - n, err := io.CopyN(buf, r, int64(req.Size)) + + buf := resp.Data[:min(req.Size, int(r.Size()))] + n, err := io.ReadFull(r, buf) if err != nil && err != io.EOF { return err } @@ -196,3 +196,10 @@ type roNode interface { } var _ roNode = (*Node)(nil) + +func min(a, b int) int { + if a < b { + return a + } + return b +} From 999471d9bfc691082a1f91cc68546d888c2c5df2 Mon Sep 17 00:00:00 2001 From: Juan Batiz-Benet Date: Mon, 2 Mar 2015 06:17:17 -0800 Subject: [PATCH 4/9] test/sharness/t004-add-cat: quote hashes --- test/sharness/t0040-add-and-cat.sh | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/test/sharness/t0040-add-and-cat.sh b/test/sharness/t0040-add-and-cat.sh index a6e8efb6a..42800a03f 100755 --- a/test/sharness/t0040-add-and-cat.sh +++ b/test/sharness/t0040-add-and-cat.sh @@ -40,7 +40,7 @@ test_expect_success "ipfs add output looks good" ' ' test_expect_success "ipfs cat succeeds" ' - ipfs cat $HASH >actual + ipfs cat "$HASH" >actual ' test_expect_success "ipfs cat output looks good" ' @@ -49,7 +49,7 @@ test_expect_success "ipfs cat output looks good" ' ' test_expect_success FUSE "cat ipfs/stuff succeeds" ' - cat ipfs/$HASH >actual + cat "ipfs/$HASH" >actual ' test_expect_success FUSE "cat ipfs/stuff looks good" ' @@ -108,7 +108,7 @@ test_expect_success "'ipfs add bigfile' output looks good" ' test_cmp expected actual ' test_expect_success "'ipfs cat' succeeds" ' - ipfs cat $HASH >actual + ipfs cat "$HASH" >actual ' test_expect_success "'ipfs cat' output looks good" ' @@ -116,7 +116,7 @@ test_expect_success "'ipfs cat' output looks good" ' ' test_expect_success FUSE "cat ipfs/bigfile succeeds" ' - cat ipfs/$HASH >actual + cat "ipfs/$HASH" >actual ' test_expect_success FUSE "cat ipfs/bigfile looks good" ' @@ -144,11 +144,11 @@ test_expect_success EXPENSIVE "ipfs add bigfile output looks good" ' ' test_expect_success EXPENSIVE "ipfs cat succeeds" ' - ipfs cat $HASH | multihash -a=sha1 -e=hex >sha1_actual + ipfs cat "$HASH" | multihash -a=sha1 -e=hex >sha1_actual ' test_expect_success EXPENSIVE "ipfs cat output looks good" ' - ipfs cat $HASH >actual && + ipfs cat "$HASH" >actual && test_cmp mountdir/bigfile actual ' @@ -158,7 +158,7 @@ test_expect_success EXPENSIVE "ipfs cat output hashed looks good" ' ' test_expect_success FUSE,EXPENSIVE "cat ipfs/bigfile succeeds" ' - cat ipfs/$HASH | multihash -a=sha1 -e=hex >sha1_actual + cat "ipfs/$HASH" | multihash -a=sha1 -e=hex >sha1_actual ' test_expect_success FUSE,EXPENSIVE "cat ipfs/bigfile looks good" ' From 2a40d7679e273e7a6e52980e62f1c40181c27a06 Mon Sep 17 00:00:00 2001 From: Juan Batiz-Benet Date: Mon, 2 Mar 2015 06:38:18 -0800 Subject: [PATCH 5/9] test/sharness: randomize api port workaround we have a problem where initializing daemons with the same api port often fails-- it hangs indefinitely. The proper solution is to make ipfs pick an unused port for the api on startup, and then use that. Unfortunately, ipfs doesnt yet know how to do this-- the api port must be specified. Until ipfs learns how to do this, we must use specific port numbers, which may still fail but less frequently if we at least use different ones. --- test/sharness/lib/test-lib.sh | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/test/sharness/lib/test-lib.sh b/test/sharness/lib/test-lib.sh index d2896c60c..4eb116892 100644 --- a/test/sharness/lib/test-lib.sh +++ b/test/sharness/lib/test-lib.sh @@ -125,6 +125,24 @@ test_config_set() { test_init_ipfs() { + # we have a problem where initializing daemons with the same api port + # often fails-- it hangs indefinitely. The proper solution is to make + # ipfs pick an unused port for the api on startup, and then use that. + # Unfortunately, ipfs doesnt yet know how to do this-- the api port + # must be specified. Until ipfs learns how to do this, we must use + # specific port numbers, which may still fail but less frequently + # if we at least use different ones. + + # Using RANDOM like this is clearly wrong-- it samples with replacement + # and it doesnt even check the port is unused. this is a trivial stop gap + # until the proper solution is implemented. + apiport=$((RANDOM % 3000 + 5100)) + ADDR_API="/ip4/127.0.0.1/tcp/$apiport" + + # we set the Addresses.API config variable. + # the cli client knows to use it, so only need to set. + # todo: in the future, use env? + test_expect_success "ipfs init succeeds" ' export IPFS_PATH="$(pwd)/.go-ipfs" && ipfs init -b=1024 > /dev/null @@ -134,6 +152,7 @@ test_init_ipfs() { mkdir mountdir ipfs ipns && test_config_set Mounts.IPFS "$(pwd)/ipfs" && test_config_set Mounts.IPNS "$(pwd)/ipns" && + test_config_set Addresses.API "$ADDR_API" && ipfs bootstrap rm --all || test_fsh cat "\"$IPFS_PATH/config\"" ' @@ -172,7 +191,6 @@ test_launch_ipfs_daemon() { ' # we say the daemon is ready when the API server is ready. - ADDR_API="/ip4/127.0.0.1/tcp/5001" test_expect_success "'ipfs daemon' is ready" ' IPFS_PID=$! && pollEndpoint -ep=/version -host=$ADDR_API -v -tout=1s -tries=60 2>poll_apierr > poll_apiout || From 0510633a17977b548d7de4951772fe5c5c614dc6 Mon Sep 17 00:00:00 2001 From: Juan Batiz-Benet Date: Mon, 2 Mar 2015 06:42:51 -0800 Subject: [PATCH 6/9] tests/sharness: t0111-gateway-writable ideally this port would be a randomly picked unused port. for now we just pick a different port than t0110-gateway. --- test/sharness/lib/test-lib.sh | 8 ++++-- test/sharness/t0110-gateway.sh | 21 +++++++------- test/sharness/t0111-gateway-writable.sh | 37 +++++++++++++++---------- 3 files changed, 39 insertions(+), 27 deletions(-) diff --git a/test/sharness/lib/test-lib.sh b/test/sharness/lib/test-lib.sh index 4eb116892..a04e42320 100644 --- a/test/sharness/lib/test-lib.sh +++ b/test/sharness/lib/test-lib.sh @@ -136,8 +136,11 @@ test_init_ipfs() { # Using RANDOM like this is clearly wrong-- it samples with replacement # and it doesnt even check the port is unused. this is a trivial stop gap # until the proper solution is implemented. - apiport=$((RANDOM % 3000 + 5100)) - ADDR_API="/ip4/127.0.0.1/tcp/$apiport" + PORT_API=$((RANDOM % 3000 + 5100)) + ADDR_API="/ip4/127.0.0.1/tcp/$PORT_API" + + PORT_GWAY=$((RANDOM % 3000 + 8100)) + ADDR_GWAY="/ip4/127.0.0.1/tcp/$PORT_GWAY" # we set the Addresses.API config variable. # the cli client knows to use it, so only need to set. @@ -153,6 +156,7 @@ test_init_ipfs() { test_config_set Mounts.IPFS "$(pwd)/ipfs" && test_config_set Mounts.IPNS "$(pwd)/ipns" && test_config_set Addresses.API "$ADDR_API" && + test_config_set Addresses.Gateway "$ADDR_GWAY" && ipfs bootstrap rm --all || test_fsh cat "\"$IPFS_PATH/config\"" ' diff --git a/test/sharness/t0110-gateway.sh b/test/sharness/t0110-gateway.sh index 3bd56945e..923d0a9b4 100755 --- a/test/sharness/t0110-gateway.sh +++ b/test/sharness/t0110-gateway.sh @@ -9,10 +9,11 @@ test_description="Test HTTP Gateway" . lib/test-lib.sh test_init_ipfs -test_config_ipfs_gateway_readonly "/ip4/0.0.0.0/tcp/5002" +test_config_ipfs_gateway_readonly $ADDR_GWAY test_launch_ipfs_daemon -webui_hash="QmXdu7HWdV6CUaUabd9q2ZeA4iHZLVyDRj3Gi4dsJsWjbr" +port=$PORT_GWAY +apiport=$PORT_API # TODO check both 5001 and 5002. # 5001 should have a readable gateway (part of the API) @@ -24,7 +25,7 @@ webui_hash="QmXdu7HWdV6CUaUabd9q2ZeA4iHZLVyDRj3Gi4dsJsWjbr" test_expect_success "GET IPFS path succeeds" ' echo "Hello Worlds!" > expected && HASH=`ipfs add -q expected` && - wget "http://127.0.0.1:5002/ipfs/$HASH" -O actual + wget "http://127.0.0.1:$port/ipfs/$HASH" -O actual ' test_expect_success "GET IPFS path output looks good" ' @@ -36,11 +37,11 @@ test_expect_success "GET IPFS directory path succeeds" ' mkdir dir && echo "12345" > dir/test && HASH2=`ipfs add -r -q dir | tail -n 1` && - wget "http://127.0.0.1:5002/ipfs/$HASH2" + wget "http://127.0.0.1:$port/ipfs/$HASH2" ' test_expect_success "GET IPFS directory file succeeds" ' - wget "http://127.0.0.1:5002/ipfs/$HASH2/test" -O actual + wget "http://127.0.0.1:$port/ipfs/$HASH2/test" -O actual ' test_expect_success "GET IPFS directory file output looks good" ' @@ -50,7 +51,7 @@ test_expect_success "GET IPFS directory file output looks good" ' test_expect_failure "GET IPNS path succeeds" ' ipfs name publish "$HASH" && NAME=`ipfs config Identity.PeerID` && - wget "http://127.0.0.1:5002/ipns/$NAME" -O actual + wget "http://127.0.0.1:$port/ipns/$NAME" -O actual ' test_expect_failure "GET IPNS path output looks good" ' @@ -58,24 +59,24 @@ test_expect_failure "GET IPNS path output looks good" ' ' test_expect_success "GET invalid IPFS path errors" ' - test_must_fail wget http://127.0.0.1:5002/ipfs/12345 + test_must_fail wget http://127.0.0.1:$port/ipfs/12345 ' test_expect_success "GET invalid path errors" ' - test_must_fail wget http://127.0.0.1:5002/12345 + test_must_fail wget http://127.0.0.1:$port/12345 ' test_expect_success "GET /webui returns code expected" ' echo "HTTP/1.1 302 Found" | head -c 18 > expected && echo "HTTP/1.1 301 Moved Permanently" | head -c 18 > also_ok && - curl -I http://127.0.0.1:5001/webui | head -c 18 > actual1 && + curl -I http://127.0.0.1:$apiport/webui | head -c 18 > actual1 && (test_cmp expected actual1 || test_cmp actual1 also_ok) && rm actual1 ' test_expect_success "GET /webui/ returns code expected" ' - curl -I http://127.0.0.1:5001/webui/ | head -c 18 > actual2 && + curl -I http://127.0.0.1:$apiport/webui/ | head -c 18 > actual2 && (test_cmp expected actual2 || test_cmp actual2 also_ok) && rm expected && rm also_ok && diff --git a/test/sharness/t0111-gateway-writable.sh b/test/sharness/t0111-gateway-writable.sh index 46a9d26b7..3ad78c9d8 100755 --- a/test/sharness/t0111-gateway-writable.sh +++ b/test/sharness/t0111-gateway-writable.sh @@ -9,35 +9,41 @@ test_description="Test HTTP Gateway (Writable)" . lib/test-lib.sh test_init_ipfs -test_config_ipfs_gateway_writable "/ip4/0.0.0.0/tcp/5002" +test_config_ipfs_gateway_writable $ADDR_GWAY test_launch_ipfs_daemon -test_expect_success "ipfs daemon listening to TCP port 5002" ' - test_wait_open_tcp_port_10_sec 5002 +port=$PORT_GWAY + +test_expect_success "ipfs daemon listening to TCP port $port" ' + test_wait_open_tcp_port_10_sec "$PORT_GWAY" ' test_expect_success "HTTP gateway gives access to sample file" ' - curl -s -o welcome "http://localhost:5002/ipfs/$HASH_WELCOME_DOCS/readme" && + curl -s -o welcome "http://localhost:$PORT_GWAY/ipfs/$HASH_WELCOME_DOCS/readme" && grep "Hello and Welcome to IPFS!" welcome ' test_expect_success "HTTP POST file gives Hash" ' echo "$RANDOM" >infile && - URL="http://localhost:5002/ipfs/" && + URL="http://localhost:$port/ipfs/" && curl -svX POST --data-binary @infile "$URL" 2>curl.out && grep "HTTP/1.1 201 Created" curl.out && LOCATION=$(grep Location curl.out) && - HASH=$(expr "$LOCATION" : "< Location: /ipfs/\(.*\)\s") + HASH=$(expr "$LOCATION" : "< Location: /ipfs/\(.*\)$") ' -test_expect_success "We can HTTP GET file just created" ' - URL="http://localhost:5002/ipfs/$HASH" && +# this is failing on osx +# claims "multihash too short. must be > 3 bytes" but the multihash is there. +test_expect_failure "We can HTTP GET file just created" ' + URL="http://localhost:$port/ipfs/$HASH" && curl -so outfile "$URL" && - test_cmp infile outfile + test_cmp infile outfile || + echo $URL && + test_fsh cat outfile ' test_expect_success "HTTP PUT empty directory" ' - URL="http://localhost:5002/ipfs/$HASH_EMPTY_DIR/" && + URL="http://localhost:$port/ipfs/$HASH_EMPTY_DIR/" && echo "PUT $URL" && curl -svX PUT "$URL" 2>curl.out && cat curl.out && @@ -54,7 +60,7 @@ test_expect_success "HTTP GET empty directory" ' test_expect_success "HTTP PUT file to construct a hierarchy" ' echo "$RANDOM" >infile && - URL="http://localhost:5002/ipfs/$HASH_EMPTY_DIR/test.txt" && + URL="http://localhost:$port/ipfs/$HASH_EMPTY_DIR/test.txt" && echo "PUT $URL" && curl -svX PUT --data-binary @infile "$URL" 2>curl.out && grep "HTTP/1.1 201 Created" curl.out && @@ -63,7 +69,7 @@ test_expect_success "HTTP PUT file to construct a hierarchy" ' ' test_expect_success "We can HTTP GET file just created" ' - URL="http://localhost:5002/ipfs/$HASH/test.txt" && + URL="http://localhost:$port/ipfs/$HASH/test.txt" && echo "GET $URL" && curl -so outfile "$URL" && test_cmp infile outfile @@ -71,7 +77,7 @@ test_expect_success "We can HTTP GET file just created" ' test_expect_success "HTTP PUT file to append to existing hierarchy" ' echo "$RANDOM" >infile2 && - URL="http://localhost:5002/ipfs/$HASH/test/test.txt" && + URL="http://localhost:$port/ipfs/$HASH/test/test.txt" && echo "PUT $URL" && curl -svX PUT --data-binary @infile2 "$URL" 2>curl.out && grep "HTTP/1.1 201 Created" curl.out && @@ -79,12 +85,13 @@ test_expect_success "HTTP PUT file to append to existing hierarchy" ' HASH=$(expr "$LOCATION" : "< Location: /ipfs/\(.*\)/test/test.txt") ' + test_expect_success "We can HTTP GET file just created" ' - URL="http://localhost:5002/ipfs/$HASH/test/test.txt" && + URL="http://localhost:$port/ipfs/$HASH/test/test.txt" && echo "GET $URL" && curl -so outfile2 "$URL" && test_cmp infile2 outfile2 && - URL="http://localhost:5002/ipfs/$HASH/test.txt" && + URL="http://localhost:$port/ipfs/$HASH/test.txt" && echo "GET $URL" && curl -so outfile "$URL" && test_cmp infile outfile From 25f042ce36a62213a96e43a3e2b5af9bea83dee5 Mon Sep 17 00:00:00 2001 From: Juan Batiz-Benet Date: Mon, 2 Mar 2015 07:25:07 -0800 Subject: [PATCH 7/9] daemon: consolidate writable gway line --- cmd/ipfs/daemon.go | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/cmd/ipfs/daemon.go b/cmd/ipfs/daemon.go index 6c4e996be..4d180ed97 100644 --- a/cmd/ipfs/daemon.go +++ b/cmd/ipfs/daemon.go @@ -215,9 +215,10 @@ func daemonFunc(req cmds.Request, res cmds.Response) { if rootRedirect != nil { opts = append(opts, rootRedirect) } - fmt.Printf("Gateway server listening on %s\n", gatewayMaddr) if writable { - fmt.Printf("Gateway server is writable\n") + fmt.Printf("Gateway (writable) server listening on %s\n", gatewayMaddr) + } else { + fmt.Printf("Gateway (readonly) server listening on %s\n", gatewayMaddr) } err := corehttp.ListenAndServe(node, gatewayMaddr.String(), opts...) if err != nil { From 04a3a66c6ca59a32b707de620a92c8e0ec9aa341 Mon Sep 17 00:00:00 2001 From: Juan Batiz-Benet Date: Mon, 2 Mar 2015 07:40:26 -0800 Subject: [PATCH 8/9] sharness/testlib: seed RANDOM this is ugly. ideally would seed using date, but unclear what a portable datetime is. date '+%s' doesnt work on osx. --- test/sharness/lib/test-lib.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/test/sharness/lib/test-lib.sh b/test/sharness/lib/test-lib.sh index a04e42320..bc1be0be9 100644 --- a/test/sharness/lib/test-lib.sh +++ b/test/sharness/lib/test-lib.sh @@ -136,6 +136,7 @@ test_init_ipfs() { # Using RANDOM like this is clearly wrong-- it samples with replacement # and it doesnt even check the port is unused. this is a trivial stop gap # until the proper solution is implemented. + RANDOM=$$ PORT_API=$((RANDOM % 3000 + 5100)) ADDR_API="/ip4/127.0.0.1/tcp/$PORT_API" From 4dd2e8fde92b42f42159bdb6539b013c515d06a4 Mon Sep 17 00:00:00 2001 From: Juan Batiz-Benet Date: Wed, 4 Mar 2015 08:28:46 -0800 Subject: [PATCH 9/9] fixed dht kbucket race closes #836 --- routing/kbucket/table.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/routing/kbucket/table.go b/routing/kbucket/table.go index a785bf8b5..7b10d8daf 100644 --- a/routing/kbucket/table.go +++ b/routing/kbucket/table.go @@ -185,9 +185,11 @@ func (rt *RoutingTable) NearestPeers(id ID, count int) []peer.ID { // Size returns the total number of peers in the routing table func (rt *RoutingTable) Size() int { var tot int + rt.tabLock.RLock() for _, buck := range rt.Buckets { tot += buck.Len() } + rt.tabLock.RUnlock() return tot }