Skip to content
This repository has been archived by the owner on Apr 29, 2024. It is now read-only.

Commit

Permalink
Merge pull request #45 from rollkit/tux/cover-unit-test
Browse files Browse the repository at this point in the history
test: mock node rpc service
  • Loading branch information
gupadhyaya authored Jan 9, 2024
2 parents 5069c00 + a12df66 commit ad7e4cb
Show file tree
Hide file tree
Showing 2 changed files with 224 additions and 1 deletion.
132 changes: 131 additions & 1 deletion celestia/celestia_test.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,139 @@
package celestia

import (
"context"
"encoding/hex"
"testing"

"github.com/celestiaorg/celestia-app/pkg/appconsts"
rpc "github.com/celestiaorg/celestia-node/api/rpc/client"
"github.com/celestiaorg/celestia-node/share"
"github.com/celestiaorg/nmt"
"github.com/stretchr/testify/assert"
)

// Blob is the data submitted/received from DA interface.
type Blob = []byte

// ID should contain serialized data required by the implementation to find blob in Data Availability layer.
type ID = []byte

// Commitment should contain serialized cryptographic commitment to Blob value.
type Commitment = []byte

// Proof should contain serialized proof of inclusion (publication) of Blob in Data Availability layer.
type Proof = []byte

// setup initializes the test instance and sets up common resources.
func setup(t *testing.T) *mockDA {
mockService := NewMockService()

t.Logf("mock json-rpc server listening on: %s", mockService.server.URL)

ctx := context.TODO()
client, err := rpc.NewClient(ctx, mockService.server.URL, "test")
assert.NoError(t, err)
ns, err := hex.DecodeString("0000c9761e8b221ae42f")
assert.NoError(t, err)
namespace, err := share.NewBlobNamespaceV0(ns)
assert.NoError(t, err)
da := NewCelestiaDA(client, namespace, ctx)
assert.Equal(t, da.client, client)

return &mockDA{mockService, *da}
}

// teardown closes the client
func teardown(m *mockDA) {
m.client.Close()
m.s.Close()
}

// TestCelestiaDA is the test suite function.
func TestCelestiaDA(t *testing.T) {
// TODO
m := setup(t)
defer teardown(m)

t.Run("MaxBlobSize", func(t *testing.T) {
maxBlobSize, err := m.MaxBlobSize()
assert.NoError(t, err)
assert.Equal(t, uint64(appconsts.DefaultMaxBytes), maxBlobSize)
})

t.Run("Get_empty", func(t *testing.T) {
blobs, err := m.Get(nil)
assert.NoError(t, err)
assert.Equal(t, 0, len(blobs))
})

t.Run("GetIDs_empty", func(t *testing.T) {
blobs, err := m.GetIDs(0)
assert.NoError(t, err)
assert.Equal(t, 0, len(blobs))
})

t.Run("Commit_empty", func(t *testing.T) {
commitments, err := m.Commit(nil)
assert.NoError(t, err)
assert.Equal(t, 0, len(commitments))
})

t.Run("Submit_empty", func(t *testing.T) {
blobs, proofs, err := m.Submit(nil)
assert.NoError(t, err)
assert.Equal(t, 0, len(blobs))
assert.Equal(t, 0, len(proofs))
})

t.Run("Validate_empty", func(t *testing.T) {
valids, err := m.Validate(nil, nil)
assert.NoError(t, err)
assert.Equal(t, 0, len(valids))
})

t.Run("Get_existing", func(t *testing.T) {
commitment, err := hex.DecodeString("1b454951cd722b2cf7be5b04554b76ccf48f65a7ad6af45055006994ce70fd9d")
assert.NoError(t, err)
blobs, err := m.Get([]ID{makeID(42, commitment)})
assert.NoError(t, err)
assert.Equal(t, 1, len(blobs))
blob1 := blobs[0]
assert.Equal(t, "This is an example of some blob data", string(blob1))
})

t.Run("GetIDs_existing", func(t *testing.T) {
ids, err := m.GetIDs(42)
assert.NoError(t, err)
assert.Equal(t, 1, len(ids))
id1 := ids[0]
commitment, err := hex.DecodeString("1b454951cd722b2cf7be5b04554b76ccf48f65a7ad6af45055006994ce70fd9d")
assert.NoError(t, err)
assert.Equal(t, makeID(42, commitment), id1)
})

t.Run("Commit_existing", func(t *testing.T) {
commitments, err := m.Commit([]Blob{[]byte{0x00, 0x01, 0x02}})
assert.NoError(t, err)
assert.Equal(t, 1, len(commitments))
})

t.Run("Submit_existing", func(t *testing.T) {
blobs, proofs, err := m.Submit([]Blob{[]byte{0x00, 0x01, 0x02}})
assert.NoError(t, err)
assert.Equal(t, 1, len(blobs))
assert.Equal(t, 1, len(proofs))
})

t.Run("Validate_existing", func(t *testing.T) {
commitment, err := hex.DecodeString("1b454951cd722b2cf7be5b04554b76ccf48f65a7ad6af45055006994ce70fd9d")
assert.NoError(t, err)
proof := nmt.NewInclusionProof(0, 4, [][]byte{[]byte("test")}, true)
proofJSON, err := proof.MarshalJSON()
assert.NoError(t, err)
ids := []ID{makeID(42, commitment)}
proofs := []Proof{proofJSON}
valids, err := m.Validate(ids, proofs)
assert.NoError(t, err)
assert.Equal(t, 1, len(valids))
})
}
93 changes: 93 additions & 0 deletions celestia/mock.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
package celestia

import (
"context"
"encoding/hex"
"net/http/httptest"

"github.com/celestiaorg/celestia-node/blob"
"github.com/celestiaorg/celestia-node/share"
"github.com/celestiaorg/nmt"
"github.com/filecoin-project/go-jsonrpc"
)

// MockBlobAPI mocks the blob API
type MockBlobAPI struct {
height uint64
}

// Submit mocks the blob.Submit method
func (m *MockBlobAPI) Submit(context.Context, []*blob.Blob, *blob.SubmitOptions) (uint64, error) {
m.height += 1
return m.height, nil
}

// Get mocks the blob.Get method
func (m *MockBlobAPI) Get(ctx context.Context, height uint64, ns share.Namespace, _ blob.Commitment) (*blob.Blob, error) {
data, err := hex.DecodeString("5468697320697320616e206578616d706c65206f6620736f6d6520626c6f622064617461")
if err != nil {
return nil, err
}
return blob.NewBlobV0(ns, data)
}

// GetAll mocks the blob.GetAll method
func (m *MockBlobAPI) GetAll(ctx context.Context, height uint64, ns []share.Namespace) ([]*blob.Blob, error) {
if height == 0 {
return []*blob.Blob{}, nil
}
data, err := hex.DecodeString("5468697320697320616e206578616d706c65206f6620736f6d6520626c6f622064617461")
if err != nil {
return nil, err
}
b, err := blob.NewBlobV0(ns[0], data)
if err != nil {
return nil, err
}
return []*blob.Blob{b}, nil
}

// GetProof mocks the blob.GetProof method
func (m *MockBlobAPI) GetProof(context.Context, uint64, share.Namespace, blob.Commitment) (*blob.Proof, error) {
proof := nmt.NewInclusionProof(0, 4, [][]byte{[]byte("test")}, true)
return &blob.Proof{&proof}, nil
}

// Included mocks the blob.Included method
func (m *MockBlobAPI) Included(context.Context, uint64, share.Namespace, *blob.Proof, blob.Commitment) (bool, error) {
return true, nil
}

// MockService mocks the node RPC service
type MockService struct {
blob *MockBlobAPI
server *httptest.Server
}

// Close closes the server
func (m *MockService) Close() {
m.server.Close()
}

// NewMockService returns the mock service
func NewMockService() *MockService {
rpcServer := jsonrpc.NewServer()

blobAPI := &MockBlobAPI{}
rpcServer.Register("blob", blobAPI)

testServ := httptest.NewServer(rpcServer)

mockService := &MockService{
blob: blobAPI,
server: testServ,
}

return mockService
}

// mockDA returns the mock DA
type mockDA struct {
s *MockService
CelestiaDA
}

0 comments on commit ad7e4cb

Please sign in to comment.