This repository has been archived by the owner on Apr 29, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 14
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #45 from rollkit/tux/cover-unit-test
test: mock node rpc service
- Loading branch information
Showing
2 changed files
with
224 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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)) | ||
}) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 | ||
} |