| 1 | package tests |
| 2 | |
| 3 | import ( |
| 4 | "context" |
| 5 | "errors" |
| 6 | "testing" |
| 7 | "time" |
| 8 | |
| 9 | coreiface "github.com/ipfs/kubo/core/coreiface" |
| 10 | ) |
| 11 | |
| 12 | var errAPINotImplemented = errors.New("api not implemented") |
| 13 | |
| 14 | type Provider interface { |
| 15 | // Make creates n nodes. fullIdentity set to false can be ignored |
| 16 | MakeAPISwarm(t *testing.T, ctx context.Context, fullIdentity bool, online bool, n int) ([]coreiface.CoreAPI, error) |
| 17 | } |
| 18 | |
| 19 | func (tp *TestSuite) makeAPISwarm(t *testing.T, ctx context.Context, fullIdentity bool, online bool, n int) ([]coreiface.CoreAPI, error) { |
| 20 | if tp.apis != nil { |
| 21 | tp.apis <- 1 |
| 22 | go func() { |
| 23 | <-ctx.Done() |
| 24 | tp.apis <- -1 |
| 25 | }() |
| 26 | } |
| 27 | |
| 28 | return tp.Provider.MakeAPISwarm(t, ctx, fullIdentity, online, n) |
| 29 | } |
| 30 | |
| 31 | func (tp *TestSuite) makeAPI(t *testing.T, ctx context.Context) (coreiface.CoreAPI, error) { |
| 32 | api, err := tp.makeAPISwarm(t, ctx, false, false, 1) |
| 33 | if err != nil { |
| 34 | return nil, err |
| 35 | } |
| 36 | |
| 37 | return api[0], nil |
| 38 | } |
| 39 | |
| 40 | func (tp *TestSuite) makeAPIWithIdentityAndOffline(t *testing.T, ctx context.Context) (coreiface.CoreAPI, error) { |
| 41 | api, err := tp.makeAPISwarm(t, ctx, true, false, 1) |
| 42 | if err != nil { |
| 43 | return nil, err |
| 44 | } |
| 45 | |
| 46 | return api[0], nil |
| 47 | } |
| 48 | |
| 49 | func (tp *TestSuite) MakeAPISwarm(t *testing.T, ctx context.Context, n int) ([]coreiface.CoreAPI, error) { |
| 50 | return tp.makeAPISwarm(t, ctx, true, true, n) |
| 51 | } |
| 52 | |
| 53 | type TestSuite struct { |
| 54 | Provider |
| 55 | |
| 56 | apis chan int |
| 57 | } |
| 58 | |
| 59 | func TestApi(p Provider) func(t *testing.T) { |
| 60 | running := 1 |
| 61 | apis := make(chan int) |
| 62 | zeroRunning := make(chan struct{}) |
| 63 | go func() { |
| 64 | for i := range apis { |
| 65 | running += i |
| 66 | if running < 1 { |
| 67 | close(zeroRunning) |
| 68 | return |
| 69 | } |
| 70 | } |
| 71 | }() |
| 72 | |
| 73 | tp := &TestSuite{Provider: p, apis: apis} |
| 74 | |
| 75 | return func(t *testing.T) { |
| 76 | t.Run("Block", tp.TestBlock) |
| 77 | t.Run("Dag", tp.TestDag) |
| 78 | t.Run("Key", tp.TestKey) |
| 79 | t.Run("Name", tp.TestName) |
| 80 | t.Run("Object", tp.TestObject) |
| 81 | t.Run("Path", tp.TestPath) |
| 82 | t.Run("Pin", tp.TestPin) |
| 83 | t.Run("PubSub", tp.TestPubSub) |
| 84 | t.Run("Routing", tp.TestRouting) |
| 85 | t.Run("Unixfs", tp.TestUnixfs) |
| 86 | |
| 87 | apis <- -1 |
| 88 | t.Run("TestsCancelCtx", func(t *testing.T) { |
| 89 | select { |
| 90 | case <-zeroRunning: |
| 91 | case <-time.After(time.Second): |
| 92 | t.Errorf("%d test swarms(s) not closed", running) |
| 93 | } |
| 94 | }) |
| 95 | } |
| 96 | } |
| 97 | |
| 98 | func (tp *TestSuite) hasApi(t *testing.T, tf func(coreiface.CoreAPI) error) { |
| 99 | ctx, cancel := context.WithCancel(context.Background()) |
| 100 | defer cancel() |
| 101 | api, err := tp.makeAPI(t, ctx) |
| 102 | if err != nil { |
| 103 | t.Fatal(err) |
| 104 | } |
| 105 | |
| 106 | if err := tf(api); err != nil { |
| 107 | t.Fatal(api) |
| 108 | } |
| 109 | } |