mirror of
https://github.com/ipfs/kubo.git
synced 2025-08-06 19:44:01 +08:00
Add test for running gc during an add
License: MIT Signed-off-by: Jeromy <jeromyj@gmail.com>
This commit is contained in:
@ -155,7 +155,7 @@ func (params *Adder) PinRoot() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
rnk, err := root.Key()
|
||||
rnk, err := params.node.DAG.Add(root)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -1,10 +1,18 @@
|
||||
package coreunix
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/ipfs/go-ipfs/Godeps/_workspace/src/golang.org/x/net/context"
|
||||
"github.com/ipfs/go-ipfs/blocks/key"
|
||||
"github.com/ipfs/go-ipfs/commands/files"
|
||||
"github.com/ipfs/go-ipfs/core"
|
||||
dag "github.com/ipfs/go-ipfs/merkledag"
|
||||
"github.com/ipfs/go-ipfs/pin/gc"
|
||||
"github.com/ipfs/go-ipfs/repo"
|
||||
"github.com/ipfs/go-ipfs/repo/config"
|
||||
"github.com/ipfs/go-ipfs/util/testutil"
|
||||
@ -29,3 +37,125 @@ func TestAddRecursive(t *testing.T) {
|
||||
t.Fatal("keys do not match: ", k)
|
||||
}
|
||||
}
|
||||
|
||||
func TestAddGCLive(t *testing.T) {
|
||||
r := &repo.Mock{
|
||||
C: config.Config{
|
||||
Identity: config.Identity{
|
||||
PeerID: "Qmfoo", // required by offline node
|
||||
},
|
||||
},
|
||||
D: testutil.ThreadSafeCloserMapDatastore(),
|
||||
}
|
||||
node, err := core.NewNode(context.Background(), &core.BuildCfg{Repo: r})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
errs := make(chan error)
|
||||
out := make(chan interface{})
|
||||
adder, err := NewAdder(context.Background(), node, out)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
dataa := ioutil.NopCloser(bytes.NewBufferString("testfileA"))
|
||||
rfa := files.NewReaderFile("a", "a", dataa, nil)
|
||||
|
||||
// make two files with pipes so we can 'pause' the add for timing of the test
|
||||
piper, pipew := io.Pipe()
|
||||
hangfile := files.NewReaderFile("b", "b", piper, nil)
|
||||
|
||||
datad := ioutil.NopCloser(bytes.NewBufferString("testfileD"))
|
||||
rfd := files.NewReaderFile("d", "d", datad, nil)
|
||||
|
||||
slf := files.NewSliceFile("files", "files", []files.File{rfa, hangfile, rfd})
|
||||
|
||||
addDone := make(chan struct{})
|
||||
go func() {
|
||||
defer close(addDone)
|
||||
defer close(out)
|
||||
err := adder.AddFile(slf)
|
||||
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
}()
|
||||
|
||||
addedHashes := make(map[string]struct{})
|
||||
select {
|
||||
case o := <-out:
|
||||
addedHashes[o.(*AddedObject).Hash] = struct{}{}
|
||||
case <-addDone:
|
||||
t.Fatal("add shouldnt complete yet")
|
||||
}
|
||||
|
||||
var gcout <-chan key.Key
|
||||
gcstarted := make(chan struct{})
|
||||
go func() {
|
||||
defer close(gcstarted)
|
||||
gcchan, err := gc.GC(context.Background(), node.Blockstore, node.Pinning)
|
||||
if err != nil {
|
||||
log.Error("GC ERROR:", err)
|
||||
errs <- err
|
||||
return
|
||||
}
|
||||
|
||||
gcout = gcchan
|
||||
}()
|
||||
|
||||
// gc shouldnt start until we let the add finish its current file.
|
||||
pipew.Write([]byte("some data for file b"))
|
||||
|
||||
select {
|
||||
case <-gcstarted:
|
||||
t.Fatal("gc shouldnt have started yet")
|
||||
case err := <-errs:
|
||||
t.Fatal(err)
|
||||
default:
|
||||
}
|
||||
|
||||
time.Sleep(time.Millisecond * 100) // make sure gc gets to requesting lock
|
||||
|
||||
// finish write and unblock gc
|
||||
pipew.Close()
|
||||
|
||||
// receive next object from adder
|
||||
select {
|
||||
case o := <-out:
|
||||
addedHashes[o.(*AddedObject).Hash] = struct{}{}
|
||||
case err := <-errs:
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
select {
|
||||
case <-gcstarted:
|
||||
case err := <-errs:
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
for k := range gcout {
|
||||
if _, ok := addedHashes[k.B58String()]; ok {
|
||||
t.Fatal("gc'ed a hash we just added")
|
||||
}
|
||||
}
|
||||
|
||||
var last key.Key
|
||||
for a := range out {
|
||||
// wait for it to finish
|
||||
last = key.B58KeyDecode(a.(*AddedObject).Hash)
|
||||
}
|
||||
|
||||
ctx, cancel := context.WithTimeout(context.Background(), time.Second*5)
|
||||
defer cancel()
|
||||
root, err := node.DAG.Get(ctx, last)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
err = dag.EnumerateChildren(ctx, node.DAG, root, key.NewKeySet())
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user