github.com/kaleido-io/firefly@v0.0.0-20210622132723-8b4b6aacb971/internal/events/dx_callbacks_test.go (about)

     1  // Copyright © 2021 Kaleido, Inc.
     2  //
     3  // SPDX-License-Identifier: Apache-2.0
     4  //
     5  // Licensed under the Apache License, Version 2.0 (the "License");
     6  // you may not use this file except in compliance with the License.
     7  // You may obtain a copy of the License at
     8  //
     9  //     http://www.apache.org/licenses/LICENSE-2.0
    10  //
    11  // Unless required by applicable law or agreed to in writing, software
    12  // distributed under the License is distributed on an "AS IS" BASIS,
    13  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    14  // See the License for the specific language governing permissions and
    15  // limitations under the License.
    16  
    17  package events
    18  
    19  import (
    20  	"encoding/json"
    21  	"fmt"
    22  	"testing"
    23  
    24  	"github.com/kaleido-io/firefly/mocks/databasemocks"
    25  	"github.com/kaleido-io/firefly/mocks/dataexchangemocks"
    26  	"github.com/kaleido-io/firefly/pkg/fftypes"
    27  	"github.com/stretchr/testify/mock"
    28  )
    29  
    30  func TestMessageReceiveOK(t *testing.T) {
    31  	em, cancel := newTestEventManager(t)
    32  	defer cancel()
    33  
    34  	batch := &fftypes.Batch{
    35  		ID:     nil, // so that we only test up to persistBatch which will return a non-retry error
    36  		Author: "signingOrg",
    37  	}
    38  	b, _ := json.Marshal(batch)
    39  
    40  	mdi := em.database.(*databasemocks.Plugin)
    41  	mdx := &dataexchangemocks.Plugin{}
    42  	mdi.On("GetNodes", em.ctx, mock.Anything).Return([]*fftypes.Node{
    43  		{Name: "node1", Owner: "parentOrg"},
    44  	}, nil)
    45  	mdi.On("GetOrganizationByIdentity", em.ctx, "signingOrg").Return(&fftypes.Organization{
    46  		Identity: "signingOrg", Parent: "parentOrg",
    47  	}, nil)
    48  	mdi.On("GetOrganizationByIdentity", em.ctx, "parentOrg").Return(&fftypes.Organization{
    49  		Identity: "parentOrg",
    50  	}, nil)
    51  	em.MessageReceived(mdx, "peer1", b)
    52  
    53  	mdi.AssertExpectations(t)
    54  	mdx.AssertExpectations(t)
    55  }
    56  
    57  func TestMessageReceivePersistBatchError(t *testing.T) {
    58  	em, cancel := newTestEventManager(t)
    59  	cancel() // retryable error
    60  
    61  	batch := &fftypes.Batch{
    62  		ID:     fftypes.NewUUID(),
    63  		Author: "signingOrg",
    64  		Payload: fftypes.BatchPayload{
    65  			TX: fftypes.TransactionRef{
    66  				ID: fftypes.NewUUID(),
    67  			},
    68  		},
    69  	}
    70  	batch.Hash = batch.Payload.Hash()
    71  	b, _ := json.Marshal(batch)
    72  
    73  	mdi := em.database.(*databasemocks.Plugin)
    74  	mdx := &dataexchangemocks.Plugin{}
    75  	mdi.On("GetNodes", em.ctx, mock.Anything).Return([]*fftypes.Node{
    76  		{Name: "node1", Owner: "parentOrg"},
    77  	}, nil)
    78  	mdi.On("GetOrganizationByIdentity", em.ctx, "signingOrg").Return(&fftypes.Organization{
    79  		Identity: "signingOrg", Parent: "parentOrg",
    80  	}, nil)
    81  	mdi.On("GetOrganizationByIdentity", em.ctx, "parentOrg").Return(&fftypes.Organization{
    82  		Identity: "parentOrg",
    83  	}, nil)
    84  	mdi.On("UpsertBatch", em.ctx, mock.Anything, true, false).Return(fmt.Errorf("pop"))
    85  	em.MessageReceived(mdx, "peer1", b)
    86  
    87  	mdi.AssertExpectations(t)
    88  	mdx.AssertExpectations(t)
    89  }
    90  
    91  func TestMessageReceivedBadData(t *testing.T) {
    92  	em, cancel := newTestEventManager(t)
    93  	defer cancel()
    94  
    95  	mdx := &dataexchangemocks.Plugin{}
    96  	em.MessageReceived(mdx, "peer1", []byte(`!{}`))
    97  }
    98  
    99  func TestMessageReceiveNodeLookupError(t *testing.T) {
   100  	em, cancel := newTestEventManager(t)
   101  	cancel() // to stop retry
   102  
   103  	batch := &fftypes.Batch{}
   104  	b, _ := json.Marshal(batch)
   105  
   106  	mdi := em.database.(*databasemocks.Plugin)
   107  	mdx := &dataexchangemocks.Plugin{}
   108  	mdi.On("GetNodes", em.ctx, mock.Anything).Return(nil, fmt.Errorf("pop"))
   109  	em.MessageReceived(mdx, "peer1", b)
   110  }
   111  
   112  func TestMessageReceiveNodeNotFound(t *testing.T) {
   113  	em, cancel := newTestEventManager(t)
   114  	defer cancel()
   115  
   116  	batch := &fftypes.Batch{}
   117  	b, _ := json.Marshal(batch)
   118  
   119  	mdi := em.database.(*databasemocks.Plugin)
   120  	mdx := &dataexchangemocks.Plugin{}
   121  	mdi.On("GetNodes", em.ctx, mock.Anything).Return(nil, nil)
   122  	em.MessageReceived(mdx, "peer1", b)
   123  }
   124  
   125  func TestMessageReceiveAuthorLookupError(t *testing.T) {
   126  	em, cancel := newTestEventManager(t)
   127  	cancel() // to stop retry
   128  
   129  	batch := &fftypes.Batch{}
   130  	b, _ := json.Marshal(batch)
   131  
   132  	mdi := em.database.(*databasemocks.Plugin)
   133  	mdx := &dataexchangemocks.Plugin{}
   134  	mdi.On("GetNodes", em.ctx, mock.Anything).Return([]*fftypes.Node{
   135  		{Name: "node1", Owner: "org1"},
   136  	}, nil)
   137  	mdi.On("GetOrganizationByIdentity", em.ctx, mock.Anything).Return(nil, fmt.Errorf("pop"))
   138  	em.MessageReceived(mdx, "peer1", b)
   139  }
   140  
   141  func TestMessageReceiveAuthorNotFound(t *testing.T) {
   142  	em, cancel := newTestEventManager(t)
   143  	defer cancel()
   144  
   145  	batch := &fftypes.Batch{}
   146  	b, _ := json.Marshal(batch)
   147  
   148  	mdi := em.database.(*databasemocks.Plugin)
   149  	mdx := &dataexchangemocks.Plugin{}
   150  	mdi.On("GetNodes", em.ctx, mock.Anything).Return([]*fftypes.Node{
   151  		{Name: "node1", Owner: "org1"},
   152  	}, nil)
   153  	mdi.On("GetOrganizationByIdentity", em.ctx, mock.Anything).Return(nil, nil)
   154  	em.MessageReceived(mdx, "peer1", b)
   155  }
   156  
   157  func TestMessageReceiveGetCandidateOrgFail(t *testing.T) {
   158  	em, cancel := newTestEventManager(t)
   159  	cancel() // retryable error so we need to break the loop
   160  
   161  	batch := &fftypes.Batch{
   162  		ID:     nil, // so that we only test up to persistBatch which will return a non-retry error
   163  		Author: "signingOrg",
   164  	}
   165  	b, _ := json.Marshal(batch)
   166  
   167  	mdi := em.database.(*databasemocks.Plugin)
   168  	mdx := &dataexchangemocks.Plugin{}
   169  	mdi.On("GetNodes", em.ctx, mock.Anything).Return([]*fftypes.Node{
   170  		{Name: "node1", Owner: "parentOrg"},
   171  	}, nil)
   172  	mdi.On("GetOrganizationByIdentity", em.ctx, "signingOrg").Return(&fftypes.Organization{
   173  		Identity: "signingOrg", Parent: "parentOrg",
   174  	}, nil)
   175  	mdi.On("GetOrganizationByIdentity", em.ctx, "parentOrg").Return(nil, fmt.Errorf("pop"))
   176  	em.MessageReceived(mdx, "peer1", b)
   177  
   178  	mdi.AssertExpectations(t)
   179  	mdx.AssertExpectations(t)
   180  }
   181  
   182  func TestMessageReceiveGetCandidateOrgNotFound(t *testing.T) {
   183  	em, cancel := newTestEventManager(t)
   184  	defer cancel()
   185  
   186  	batch := &fftypes.Batch{
   187  		ID:     nil, // so that we only test up to persistBatch which will return a non-retry error
   188  		Author: "signingOrg",
   189  	}
   190  	b, _ := json.Marshal(batch)
   191  
   192  	mdi := em.database.(*databasemocks.Plugin)
   193  	mdx := &dataexchangemocks.Plugin{}
   194  	mdi.On("GetNodes", em.ctx, mock.Anything).Return([]*fftypes.Node{
   195  		{Name: "node1", Owner: "parentOrg"},
   196  	}, nil)
   197  	mdi.On("GetOrganizationByIdentity", em.ctx, "signingOrg").Return(&fftypes.Organization{
   198  		Identity: "signingOrg", Parent: "parentOrg",
   199  	}, nil)
   200  	mdi.On("GetOrganizationByIdentity", em.ctx, "parentOrg").Return(nil, nil)
   201  	em.MessageReceived(mdx, "peer1", b)
   202  
   203  	mdi.AssertExpectations(t)
   204  	mdx.AssertExpectations(t)
   205  }
   206  
   207  func TestMessageReceiveGetCandidateOrgNotMatch(t *testing.T) {
   208  	em, cancel := newTestEventManager(t)
   209  	defer cancel()
   210  
   211  	batch := &fftypes.Batch{
   212  		ID:     nil, // so that we only test up to persistBatch which will return a non-retry error
   213  		Author: "signingOrg",
   214  	}
   215  	b, _ := json.Marshal(batch)
   216  
   217  	mdi := em.database.(*databasemocks.Plugin)
   218  	mdx := &dataexchangemocks.Plugin{}
   219  	mdi.On("GetNodes", em.ctx, mock.Anything).Return([]*fftypes.Node{
   220  		{Name: "node1", Owner: "another"},
   221  	}, nil)
   222  	mdi.On("GetOrganizationByIdentity", em.ctx, "signingOrg").Return(&fftypes.Organization{
   223  		Identity: "signingOrg", Parent: "parentOrg",
   224  	}, nil)
   225  	mdi.On("GetOrganizationByIdentity", em.ctx, "parentOrg").Return(&fftypes.Organization{
   226  		Identity: "parentOrg",
   227  	}, nil)
   228  	em.MessageReceived(mdx, "peer1", b)
   229  
   230  	mdi.AssertExpectations(t)
   231  	mdx.AssertExpectations(t)
   232  }
   233  
   234  func TestBLOBReceivedNoop(t *testing.T) {
   235  	em, cancel := newTestEventManager(t)
   236  	defer cancel()
   237  
   238  	mdx := &dataexchangemocks.Plugin{}
   239  	u := fftypes.NewUUID()
   240  	em.BLOBReceived(mdx, "peer1", "ns1", *u)
   241  }
   242  
   243  func TestTransferResultOk(t *testing.T) {
   244  	em, cancel := newTestEventManager(t)
   245  	defer cancel()
   246  
   247  	mdi := em.database.(*databasemocks.Plugin)
   248  	id := fftypes.NewUUID()
   249  	mdi.On("GetOperations", mock.Anything, mock.Anything).Return([]*fftypes.Operation{
   250  		{
   251  			ID:        id,
   252  			BackendID: "tracking12345",
   253  		},
   254  	}, nil)
   255  	mdi.On("UpdateOperation", mock.Anything, id, mock.Anything).Return(nil)
   256  
   257  	mdx := &dataexchangemocks.Plugin{}
   258  	mdx.On("Name").Return("utdx")
   259  	em.TransferResult(mdx, "tracking12345", fftypes.OpStatusFailed, "error info", fftypes.JSONObject{"extra": "info"})
   260  
   261  }
   262  
   263  func TestTransferResultNotFound(t *testing.T) {
   264  	em, cancel := newTestEventManager(t)
   265  	cancel() // avoid retries
   266  
   267  	mdi := em.database.(*databasemocks.Plugin)
   268  	mdi.On("GetOperations", mock.Anything, mock.Anything).Return([]*fftypes.Operation{}, nil)
   269  
   270  	mdx := &dataexchangemocks.Plugin{}
   271  	mdx.On("Name").Return("utdx")
   272  	em.TransferResult(mdx, "tracking12345", fftypes.OpStatusFailed, "error info", fftypes.JSONObject{"extra": "info"})
   273  
   274  }
   275  
   276  func TestTransferUpdateFail(t *testing.T) {
   277  	em, cancel := newTestEventManager(t)
   278  	defer cancel()
   279  
   280  	mdi := em.database.(*databasemocks.Plugin)
   281  	id := fftypes.NewUUID()
   282  	mdi.On("GetOperations", mock.Anything, mock.Anything).Return([]*fftypes.Operation{
   283  		{
   284  			ID:        id,
   285  			BackendID: "tracking12345",
   286  		},
   287  	}, nil)
   288  	mdi.On("UpdateOperation", mock.Anything, id, mock.Anything).Return(fmt.Errorf("pop"))
   289  
   290  	mdx := &dataexchangemocks.Plugin{}
   291  	mdx.On("Name").Return("utdx")
   292  	em.TransferResult(mdx, "tracking12345", fftypes.OpStatusFailed, "error info", fftypes.JSONObject{"extra": "info"})
   293  
   294  }