github.com/hyperledger/aries-framework-go@v0.3.2/pkg/framework/aries/framework_test.go (about)

     1  /*
     2  Copyright SecureKey Technologies Inc. All Rights Reserved.
     3  
     4  SPDX-License-Identifier: Apache-2.0
     5  */
     6  
     7  package aries
     8  
     9  import (
    10  	"crypto/rand"
    11  	"crypto/sha256"
    12  	"encoding/base64"
    13  	"errors"
    14  	"fmt"
    15  	"io/ioutil"
    16  	"net"
    17  	"net/http"
    18  	"os"
    19  	"strings"
    20  	"testing"
    21  
    22  	"github.com/golang/mock/gomock"
    23  	"github.com/stretchr/testify/require"
    24  
    25  	"github.com/hyperledger/aries-framework-go/component/storageutil/mem"
    26  	"github.com/hyperledger/aries-framework-go/pkg/common/model"
    27  	"github.com/hyperledger/aries-framework-go/pkg/didcomm/common/service"
    28  	"github.com/hyperledger/aries-framework-go/pkg/didcomm/dispatcher"
    29  	"github.com/hyperledger/aries-framework-go/pkg/didcomm/packer"
    30  	"github.com/hyperledger/aries-framework-go/pkg/didcomm/protocol/decorator"
    31  	"github.com/hyperledger/aries-framework-go/pkg/didcomm/protocol/didexchange"
    32  	"github.com/hyperledger/aries-framework-go/pkg/didcomm/transport"
    33  	"github.com/hyperledger/aries-framework-go/pkg/doc/did"
    34  	"github.com/hyperledger/aries-framework-go/pkg/framework/aries/api"
    35  	"github.com/hyperledger/aries-framework-go/pkg/framework/context"
    36  	mocks "github.com/hyperledger/aries-framework-go/pkg/internal/gomocks/didcomm/common/service"
    37  	didStoreMocks "github.com/hyperledger/aries-framework-go/pkg/internal/gomocks/store/did"
    38  	verifiableStoreMocks "github.com/hyperledger/aries-framework-go/pkg/internal/gomocks/store/verifiable"
    39  	"github.com/hyperledger/aries-framework-go/pkg/internal/ldtestutil"
    40  	"github.com/hyperledger/aries-framework-go/pkg/kms"
    41  	"github.com/hyperledger/aries-framework-go/pkg/kms/localkms"
    42  	mockcrypto "github.com/hyperledger/aries-framework-go/pkg/mock/crypto"
    43  	"github.com/hyperledger/aries-framework-go/pkg/mock/didcomm"
    44  	"github.com/hyperledger/aries-framework-go/pkg/mock/didcomm/msghandler"
    45  	mockdidexchange "github.com/hyperledger/aries-framework-go/pkg/mock/didcomm/protocol/didexchange"
    46  	"github.com/hyperledger/aries-framework-go/pkg/mock/didcomm/protocol/generic"
    47  	mockdiddoc "github.com/hyperledger/aries-framework-go/pkg/mock/diddoc"
    48  	mockkms "github.com/hyperledger/aries-framework-go/pkg/mock/kms"
    49  	mockldstore "github.com/hyperledger/aries-framework-go/pkg/mock/ld"
    50  	"github.com/hyperledger/aries-framework-go/pkg/mock/storage"
    51  	mockvdr "github.com/hyperledger/aries-framework-go/pkg/mock/vdr"
    52  	"github.com/hyperledger/aries-framework-go/pkg/secretlock"
    53  	locallock "github.com/hyperledger/aries-framework-go/pkg/secretlock/local"
    54  	"github.com/hyperledger/aries-framework-go/pkg/secretlock/local/masterlock/hkdf"
    55  	"github.com/hyperledger/aries-framework-go/pkg/secretlock/noop"
    56  	"github.com/hyperledger/aries-framework-go/pkg/vdr/peer"
    57  )
    58  
    59  //nolint:lll
    60  const doc = `{
    61    "@context": ["https://www.w3.org/ns/did/v1","https://www.w3.org/ns/did/v2"],
    62    "id": "did:peer:21tDAKCERh95uGgKbJNHYp",
    63    "verificationMethod": [
    64      {
    65        "id": "did:peer:123456789abcdefghi#keys-1",
    66        "type": "Secp256k1VerificationKey2018",
    67        "controller": "did:peer:123456789abcdefghi",
    68        "publicKeyBase58": "H3C2AVvLMv6gmMNam3uVAjZpfkcJCwDwnZn6z3wXmqPV"
    69      },
    70      {
    71        "id": "did:peer:123456789abcdefghw#key2",
    72        "type": "RsaVerificationKey2018",
    73        "controller": "did:peer:123456789abcdefghw",
    74        "publicKeyPem": "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAryQICCl6NZ5gDKrnSztO\n3Hy8PEUcuyvg/ikC+VcIo2SFFSf18a3IMYldIugqqqZCs4/4uVW3sbdLs/6PfgdX\n7O9D22ZiFWHPYA2k2N744MNiCD1UE+tJyllUhSblK48bn+v1oZHCM0nYQ2NqUkvS\nj+hwUU3RiWl7x3D2s9wSdNt7XUtW05a/FXehsPSiJfKvHJJnGOX0BgTvkLnkAOTd\nOrUZ/wK69Dzu4IvrN4vs9Nes8vbwPa/ddZEzGR0cQMt0JBkhk9kU/qwqUseP1QRJ\n5I1jR4g8aYPL/ke9K35PxZWuDp3U0UPAZ3PjFAh+5T+fc7gzCs9dPzSHloruU+gl\nFQIDAQAB\n-----END PUBLIC KEY-----"
    75      }
    76    ]
    77  }`
    78  
    79  func TestFramework(t *testing.T) {
    80  	t.Run("test framework new - returns error", func(t *testing.T) {
    81  		// framework new - error
    82  		_, err := New(func(opts *Aries) error {
    83  			return errors.New("error creating the framework option")
    84  		})
    85  		require.Error(t, err)
    86  	})
    87  
    88  	t.Run("test framework new - with default outbound dispatcher", func(t *testing.T) {
    89  		// prepare http server
    90  		server := startMockServer(t, mockHTTPHandler{})
    91  		port := getServerPort(server)
    92  		defer func() {
    93  			err := server.Close()
    94  			if err != nil {
    95  				t.Fatalf("Failed to stop server: %s", err)
    96  			}
    97  		}()
    98  		serverURL := fmt.Sprintf("http://localhost:%d", port)
    99  
   100  		aries, err := New(
   101  			WithInboundTransport(&mockInboundTransport{}),
   102  			WithKMS(func(ctx kms.Provider) (kms.KeyManager, error) {
   103  				return &mockkms.KeyManager{CreateKeyID: "abc"}, nil
   104  			}),
   105  			WithCrypto(&mockcrypto.Crypto{SignValue: []byte("mockValue")}),
   106  			WithPacker(func(ctx packer.Provider) (packer.Packer, error) {
   107  				return &didcomm.MockAuthCrypt{
   108  					EncryptValue: func(cty string, payload, senderPubKey []byte, recipients [][]byte) (bytes []byte, e error) {
   109  						return []byte("packed message"), nil
   110  					},
   111  					DecryptValue: nil,
   112  				}, nil
   113  			},
   114  				func(ctx packer.Provider) (packer.Packer, error) {
   115  					return &didcomm.MockAuthCrypt{
   116  						EncryptValue: nil,
   117  					}, nil
   118  				}),
   119  			WithMediaTypeProfiles([]string{"mockProfile"}))
   120  		require.NoError(t, err)
   121  
   122  		// context
   123  		ctx, err := aries.Context()
   124  		require.NoError(t, err)
   125  
   126  		e := ctx.OutboundDispatcher().Send(
   127  			[]byte("Hello World"),
   128  			mockdiddoc.MockDIDKey(t),
   129  			&service.Destination{ServiceEndpoint: model.NewDIDCommV1Endpoint(serverURL)},
   130  		)
   131  		require.NoError(t, e)
   132  	})
   133  
   134  	// framework new - success
   135  	t.Run("test vdr - with DIDComm V2", func(t *testing.T) {
   136  		vdr := &mockvdr.MockVDR{}
   137  		aries, err := New(WithVDR(vdr), WithInboundTransport(&mockInboundTransport{}),
   138  			WithMediaTypeProfiles([]string{transport.MediaTypeDIDCommV2Profile}))
   139  		require.NoError(t, err)
   140  		require.NotEmpty(t, aries)
   141  
   142  		require.Equal(t, len(aries.vdr), 1)
   143  		require.Equal(t, vdr, aries.vdr[0])
   144  		err = aries.Close()
   145  		require.NoError(t, err)
   146  	})
   147  
   148  	t.Run("test vdr - with user provided", func(t *testing.T) {
   149  		vdr := &mockvdr.MockVDR{}
   150  		aries, err := New(WithVDR(vdr), WithInboundTransport(&mockInboundTransport{}))
   151  		require.NoError(t, err)
   152  		require.NotEmpty(t, aries)
   153  
   154  		require.Equal(t, len(aries.vdr), 1)
   155  		require.Equal(t, vdr, aries.vdr[0])
   156  		err = aries.Close()
   157  		require.NoError(t, err)
   158  	})
   159  
   160  	t.Run("test error create vdr", func(t *testing.T) {
   161  		sp := storage.NewMockStoreProvider()
   162  		sp.FailNamespace = peer.StoreNamespace
   163  
   164  		_, err := New(
   165  			WithStoreProvider(sp),
   166  			WithInboundTransport(&mockInboundTransport{}))
   167  		require.Error(t, err)
   168  		require.Contains(t, err.Error(), "create new vdr peer failed")
   169  	})
   170  
   171  	t.Run("test vdr - close error", func(t *testing.T) {
   172  		vdr := &mockvdr.MockVDR{CloseErr: fmt.Errorf("close vdr error")}
   173  		aries, err := New(WithVDR(vdr), WithInboundTransport(&mockInboundTransport{}))
   174  		require.NoError(t, err)
   175  		require.NotEmpty(t, aries)
   176  
   177  		err = aries.Close()
   178  		require.Error(t, err)
   179  		require.Contains(t, err.Error(), "close vdr error")
   180  	})
   181  
   182  	t.Run("test vdr - with default vdr", func(t *testing.T) {
   183  		t.Skip()
   184  		// store peer DID in the store
   185  		dbprov := mem.NewProvider()
   186  		peerDID := "did:peer:21tDAKCERh95uGgKbJNHYp"
   187  		store, err := peer.New(dbprov)
   188  		require.NoError(t, err)
   189  		originalDoc, err := did.ParseDocument([]byte(doc))
   190  		require.NoError(t, err)
   191  		_, err = store.Create(originalDoc)
   192  		require.NoError(t, err)
   193  
   194  		err = dbprov.Close()
   195  		require.NoError(t, err)
   196  
   197  		// with default DID resolver
   198  		aries, err := New(WithInboundTransport(&mockInboundTransport{}))
   199  		require.NoError(t, err)
   200  		require.NotEmpty(t, aries)
   201  
   202  		resolvedDoc, err := aries.vdrRegistry.Resolve(peerDID)
   203  		require.NoError(t, err)
   204  		require.Equal(t, originalDoc, resolvedDoc)
   205  		err = aries.Close()
   206  		require.NoError(t, err)
   207  	})
   208  
   209  	t.Run("test protocol svc - with default protocol", func(t *testing.T) {
   210  		aries, err := New(WithInboundTransport(&mockInboundTransport{}))
   211  		require.NoError(t, err)
   212  		require.NotEmpty(t, aries)
   213  
   214  		ctx, err := aries.Context()
   215  		require.NoError(t, err)
   216  
   217  		_, err = ctx.Service(didexchange.DIDExchange)
   218  		require.NoError(t, err)
   219  		err = aries.Close()
   220  		require.NoError(t, err)
   221  	})
   222  
   223  	t.Run("test protocol svc - with user provided protocol", func(t *testing.T) {
   224  		newMockSvc := api.ProtocolSvcCreator{
   225  			Create: func(prv api.Provider) (dispatcher.ProtocolService, error) {
   226  				return &mockdidexchange.MockDIDExchangeSvc{
   227  					ProtocolName: "mockProtocolSvc",
   228  				}, nil
   229  			},
   230  		}
   231  		// with custom protocol
   232  		aries, err := New(WithProtocols(newMockSvc), WithInboundTransport(&mockInboundTransport{}))
   233  		require.NoError(t, err)
   234  		require.NotEmpty(t, aries)
   235  
   236  		ctx, err := aries.Context()
   237  		require.NoError(t, err)
   238  
   239  		_, err = ctx.Service(didexchange.DIDExchange)
   240  		require.NoError(t, err)
   241  
   242  		_, err = ctx.Service("mockProtocolSvc")
   243  		require.NoError(t, err)
   244  
   245  		err = aries.Close()
   246  		require.NoError(t, err)
   247  	})
   248  
   249  	t.Run("test new with protocol service", func(t *testing.T) {
   250  		mockSvcCreator := api.ProtocolSvcCreator{
   251  			Create: func(prv api.Provider) (dispatcher.ProtocolService, error) {
   252  				return &mockdidexchange.MockDIDExchangeSvc{
   253  					ProtocolName: "mockProtocolSvc",
   254  				}, nil
   255  			},
   256  		}
   257  		aries, err := New(WithProtocols(mockSvcCreator), WithInboundTransport(&mockInboundTransport{}))
   258  		require.NoError(t, err)
   259  
   260  		prov, err := aries.Context()
   261  		require.NoError(t, err)
   262  
   263  		_, err = prov.Service("mockProtocolSvc")
   264  		require.NoError(t, err)
   265  
   266  		_, err = prov.Service("mockProtocolSvc1")
   267  		require.Error(t, err)
   268  	})
   269  
   270  	t.Run("test error from protocol service", func(t *testing.T) {
   271  		newMockSvc := api.ProtocolSvcCreator{
   272  			Create: func(prv api.Provider) (dispatcher.ProtocolService, error) {
   273  				return nil, errors.New("error creating the protocol")
   274  			},
   275  		}
   276  		_, err := New(WithProtocols(newMockSvc))
   277  		require.Error(t, err)
   278  		require.Contains(t, err.Error(), "error creating the protocol")
   279  
   280  		newMockSvc = api.ProtocolSvcCreator{
   281  			Create: func(prv api.Provider) (dispatcher.ProtocolService, error) {
   282  				return &mockdidexchange.MockDIDExchangeSvc{
   283  					ProtocolName: "mockProtocolSvc",
   284  				}, nil
   285  			},
   286  
   287  			Init: func(srv dispatcher.ProtocolService, prv api.Provider) error {
   288  				return errors.New("error initializing the protocol")
   289  			},
   290  		}
   291  
   292  		_, err = New(WithProtocols(newMockSvc))
   293  		require.Error(t, err)
   294  		require.Contains(t, err.Error(), "error initializing the protocol")
   295  
   296  		newMockSvc = api.ProtocolSvcCreator{
   297  			Create: func(prv api.Provider) (dispatcher.ProtocolService, error) {
   298  				return &mockProtocolService{}, nil
   299  			},
   300  		}
   301  
   302  		_, err = New(WithProtocols(newMockSvc))
   303  		require.Error(t, err)
   304  		require.ErrorIs(t, err, errMockProtocolInit)
   305  	})
   306  
   307  	t.Run("test Inbound transport - with options", func(t *testing.T) {
   308  		aries, err := New(WithInboundTransport(&mockInboundTransport{}))
   309  		require.NoError(t, err)
   310  		require.NotEmpty(t, aries)
   311  	})
   312  
   313  	t.Run("test Inbound transport - start/stop error", func(t *testing.T) {
   314  		// start error
   315  		_, err := New(WithInboundTransport(&mockInboundTransport{startError: errors.New("start error")}))
   316  		require.Error(t, err)
   317  		require.Contains(t, err.Error(), "inbound transport start failed")
   318  
   319  		// stop error
   320  		aries, err := New(WithInboundTransport(&mockInboundTransport{stopError: errors.New("stop error")}))
   321  		require.NoError(t, err)
   322  		require.NotEmpty(t, aries)
   323  
   324  		err = aries.Close()
   325  		require.Error(t, err)
   326  		require.Contains(t, err.Error(), "inbound transport close failed")
   327  	})
   328  
   329  	t.Run("test KMS svc - with user provided instance", func(t *testing.T) {
   330  		// with custom KMS
   331  		aries, err := New(WithInboundTransport(&mockInboundTransport{}),
   332  			WithKMS(func(ctx kms.Provider) (kms.KeyManager, error) {
   333  				return &mockkms.KeyManager{CreateKeyID: "abc"}, nil
   334  			}),
   335  			WithCrypto(&mockcrypto.Crypto{SignValue: []byte("mockValue")}))
   336  		require.NoError(t, err)
   337  		require.NotEmpty(t, aries)
   338  
   339  		ctx, err := aries.Context()
   340  		require.NoError(t, err)
   341  
   342  		v, err := ctx.Crypto().Sign(nil, "")
   343  		require.NoError(t, err)
   344  		require.Equal(t, []byte("mockValue"), v)
   345  		err = aries.Close()
   346  		require.NoError(t, err)
   347  	})
   348  
   349  	t.Run("test crypto svc - with user provided crypto - Encrypt success", func(t *testing.T) {
   350  		// with custom crypto
   351  		aries, err := New(WithCrypto(&mockcrypto.Crypto{
   352  			EncryptValue:      []byte("mockValue"),
   353  			EncryptNonceValue: []byte("mockNonce"),
   354  		}))
   355  		require.NoError(t, err)
   356  		require.NotEmpty(t, aries)
   357  
   358  		ctx, err := aries.Context()
   359  		require.NoError(t, err)
   360  
   361  		v, n, err := ctx.Crypto().Encrypt([]byte{}, []byte{}, nil)
   362  		require.NoError(t, err)
   363  		require.Equal(t, []byte("mockValue"), v)
   364  		require.Equal(t, []byte("mockNonce"), n)
   365  		err = aries.Close()
   366  		require.NoError(t, err)
   367  	})
   368  
   369  	t.Run("test crypto svc - with user provided crypto - Encrypt fail", func(t *testing.T) {
   370  		// with custom crypto
   371  		aries, err := New(WithCrypto(&mockcrypto.Crypto{
   372  			EncryptErr: fmt.Errorf("error encrypting from crypto"),
   373  		}))
   374  		require.NoError(t, err)
   375  		require.NotEmpty(t, aries)
   376  
   377  		ctx, err := aries.Context()
   378  		require.NoError(t, err)
   379  
   380  		_, _, err = ctx.Crypto().Encrypt([]byte{}, []byte{}, nil)
   381  		require.EqualError(t, err, "error encrypting from crypto")
   382  		err = aries.Close()
   383  		require.NoError(t, err)
   384  	})
   385  
   386  	t.Run("test crypto svc - with user provided crypto - Sign success", func(t *testing.T) {
   387  		// with custom crypto
   388  		aries, err := New(WithCrypto(&mockcrypto.Crypto{SignValue: []byte("mockValue")}))
   389  		require.NoError(t, err)
   390  		require.NotEmpty(t, aries)
   391  
   392  		ctx, err := aries.Context()
   393  		require.NoError(t, err)
   394  
   395  		v, err := ctx.Crypto().Sign(nil, "")
   396  		require.NoError(t, err)
   397  		require.Equal(t, []byte("mockValue"), v)
   398  		err = aries.Close()
   399  		require.NoError(t, err)
   400  	})
   401  
   402  	t.Run("test crypto svc - with user provided crypto - Sign fail", func(t *testing.T) {
   403  		// with custom crypto
   404  		aries, err := New(WithCrypto(&mockcrypto.Crypto{
   405  			SignErr: fmt.Errorf("error signing from crypto"),
   406  		}))
   407  		require.NoError(t, err)
   408  		require.NotEmpty(t, aries)
   409  
   410  		ctx, err := aries.Context()
   411  		require.NoError(t, err)
   412  
   413  		_, err = ctx.Crypto().Sign(nil, "")
   414  		require.EqualError(t, err, "error signing from crypto")
   415  		err = aries.Close()
   416  		require.NoError(t, err)
   417  	})
   418  
   419  	t.Run("test error from kms svc", func(t *testing.T) {
   420  		// with custom legacy kms
   421  		_, err := New(WithInboundTransport(&mockInboundTransport{}),
   422  			WithKMS(func(ctx kms.Provider) (kms.KeyManager, error) {
   423  				return nil, fmt.Errorf("error from KMS")
   424  			}))
   425  		require.Error(t, err)
   426  		require.Contains(t, err.Error(), "error from KMS")
   427  	})
   428  
   429  	t.Run("test new with explicitly passing noop secret lock svc as an option", func(t *testing.T) {
   430  		// create noop secret lock service
   431  		s := &noop.NoLock{}
   432  
   433  		// final step, create the Aries agent with this secret lock
   434  		a, err := New(WithSecretLock(s), WithStoreProvider(storage.NewMockStoreProvider()))
   435  		require.NoError(t, err)
   436  		require.NotEmpty(t, a)
   437  		require.Equal(t, s, a.secretLock)
   438  
   439  		err = a.Close()
   440  		require.NoError(t, err)
   441  	})
   442  
   443  	t.Run("test new with custom (unprotected master key) secret lock svc and with custom KMS", func(t *testing.T) {
   444  		masterKeyFilePath := "masterKey_aries.txt"
   445  		tmpfile, err := ioutil.TempFile("", masterKeyFilePath)
   446  		require.NoError(t, err)
   447  
   448  		defer func() {
   449  			// close file
   450  			require.NoError(t, tmpfile.Close())
   451  			// clean up
   452  			require.NoError(t, os.Remove(tmpfile.Name()))
   453  		}()
   454  
   455  		keySize := sha256.Size
   456  
   457  		// generate a random master key
   458  		masterKeyContent := make([]byte, keySize)
   459  		_, err = rand.Read(masterKeyContent)
   460  		require.NoError(t, err)
   461  		require.NotEmpty(t, masterKeyContent)
   462  
   463  		// store masterKeyContent to file
   464  		n, err := tmpfile.Write([]byte(base64.URLEncoding.EncodeToString(masterKeyContent)))
   465  		require.NoError(t, err)
   466  		require.Equal(t, base64.URLEncoding.EncodedLen(keySize), n)
   467  
   468  		r, err := locallock.MasterKeyFromPath(tmpfile.Name())
   469  		require.NoError(t, err)
   470  		require.NotEmpty(t, r)
   471  
   472  		s, err := locallock.NewService(r, nil)
   473  		require.NoError(t, err)
   474  		require.NotEmpty(t, s)
   475  
   476  		// final step, create the Aries agent with this secret lock
   477  		a, err := New(WithSecretLock(s), WithStoreProvider(storage.NewMockStoreProvider()))
   478  		require.NoError(t, err)
   479  		require.NotEmpty(t, a)
   480  		require.Equal(t, s, a.secretLock)
   481  
   482  		err = a.Close()
   483  		require.NoError(t, err)
   484  	})
   485  
   486  	t.Run("test new with custom (protected) secret lock svc and with custom KMS", func(t *testing.T) {
   487  		// pre steps (preparation), create a protected master key and store it in a local file
   488  		masterKeyFilePath := "masterKey_aries.txt"
   489  		tmpfile, err := ioutil.TempFile("", masterKeyFilePath)
   490  		require.NoError(t, err)
   491  
   492  		defer func() {
   493  			// close file
   494  			require.NoError(t, tmpfile.Close())
   495  			// clean up
   496  			require.NoError(t, os.Remove(tmpfile.Name()))
   497  		}()
   498  
   499  		passphrase := "testPassword"
   500  		keySize := sha256.Size
   501  
   502  		salt := make([]byte, keySize)
   503  		_, err = rand.Read(salt)
   504  		require.NoError(t, err)
   505  
   506  		// create a master lock to protect the master key (salt is optional)
   507  		masterLock, err := hkdf.NewMasterLock(passphrase, sha256.New, salt)
   508  		require.NoError(t, err)
   509  		require.NotEmpty(t, masterLock)
   510  
   511  		// generate a random master key
   512  		masterKeyContent := make([]byte, keySize)
   513  		_, err = rand.Read(masterKeyContent)
   514  		require.NoError(t, err)
   515  		require.NotEmpty(t, masterKeyContent)
   516  
   517  		// encrypt it
   518  		masterKeyEnc, err := masterLock.Encrypt("", &secretlock.EncryptRequest{
   519  			Plaintext: string(masterKeyContent),
   520  		})
   521  		require.NoError(t, err)
   522  		require.NotEmpty(t, masterKeyEnc)
   523  
   524  		// store encrypted content to file
   525  		n, err := tmpfile.Write([]byte(masterKeyEnc.Ciphertext))
   526  		require.NoError(t, err)
   527  		require.Equal(t, len(masterKeyEnc.Ciphertext), n)
   528  
   529  		r, err := locallock.MasterKeyFromPath(tmpfile.Name())
   530  		require.NoError(t, err)
   531  		require.NotEmpty(t, r)
   532  
   533  		s, err := locallock.NewService(r, masterLock)
   534  		require.NoError(t, err)
   535  		require.NotEmpty(t, s)
   536  
   537  		// final step, create the Aries agent with this secret lock
   538  		a, err := New(WithSecretLock(s), WithStoreProvider(storage.NewMockStoreProvider()))
   539  		require.NoError(t, err)
   540  		require.NotEmpty(t, a)
   541  		require.Equal(t, s, a.secretLock)
   542  
   543  		err = a.Close()
   544  		require.NoError(t, err)
   545  
   546  		// now test New with a custom kms using the same secretlock created above
   547  		// create the kms provider first..
   548  		p, err := context.New(
   549  			context.WithSecretLock(s),
   550  			context.WithStorageProvider(storage.NewMockStoreProvider()),
   551  		)
   552  		require.NoError(t, err)
   553  
   554  		kmsStore, err := kms.NewAriesProviderWrapper(p.StorageProvider())
   555  		require.NoError(t, err)
   556  
   557  		kmsProv := &kmsProvider{
   558  			kmsStore:          kmsStore,
   559  			secretLockService: p.SecretLock(),
   560  		}
   561  
   562  		// create a custom KMS instance with this provider
   563  		customKMS, err := localkms.New("local-lock://custom/master/key/", kmsProv)
   564  		require.NoError(t, err)
   565  		require.NotEmpty(t, customKMS)
   566  
   567  		// finally test New using a KMSCreator function returning the above customKMS
   568  		a, err = New(WithKMS(func(ctx kms.Provider) (kms.KeyManager, error) {
   569  			return customKMS, nil
   570  		}), WithStoreProvider(storage.NewMockStoreProvider()))
   571  		require.NoError(t, err)
   572  		require.NotEmpty(t, a)
   573  		require.Equal(t, customKMS, a.kms)
   574  
   575  		err = a.Close()
   576  		require.NoError(t, err)
   577  	})
   578  
   579  	t.Run("test protocol state store - with user provided protocol state store", func(t *testing.T) {
   580  		s := storage.NewMockStoreProvider()
   581  
   582  		aries, err := New(WithInboundTransport(&mockInboundTransport{}), WithProtocolStateStoreProvider(s))
   583  		require.NoError(t, err)
   584  		require.NotEmpty(t, aries)
   585  		require.Equal(t, s, aries.protocolStateStoreProvider)
   586  	})
   587  
   588  	t.Run("test new with outbound transport service", func(t *testing.T) {
   589  		aries, err := New(WithOutboundTransports(&didcomm.MockOutboundTransport{ExpectedResponse: "data"},
   590  			&didcomm.MockOutboundTransport{ExpectedResponse: "data1"}))
   591  		require.NoError(t, err)
   592  		require.Equal(t, 2, len(aries.outboundTransports))
   593  		r, err := aries.outboundTransports[0].Send([]byte("data"),
   594  			&service.Destination{ServiceEndpoint: model.NewDIDCommV1Endpoint("url")})
   595  		require.NoError(t, err)
   596  		require.Equal(t, "data", r)
   597  		r, err = aries.outboundTransports[1].Send([]byte("data1"),
   598  			&service.Destination{ServiceEndpoint: model.NewDIDCommV1Endpoint("url")})
   599  		require.NoError(t, err)
   600  		require.Equal(t, "data1", r)
   601  		require.NoError(t, aries.Close())
   602  	})
   603  
   604  	t.Run("test new with messenger handler", func(t *testing.T) {
   605  		ctrl := gomock.NewController(t)
   606  		defer ctrl.Finish()
   607  
   608  		messengerHandler := mocks.NewMockMessengerHandler(ctrl)
   609  		aries, err := New(WithMessengerHandler(messengerHandler))
   610  		require.NoError(t, err)
   611  		require.Equal(t, messengerHandler, aries.Messenger())
   612  	})
   613  
   614  	t.Run("test new with transport return route", func(t *testing.T) {
   615  		transportReturnRoute := decorator.TransportReturnRouteAll
   616  		aries, err := New(WithTransportReturnRoute(transportReturnRoute))
   617  		require.NoError(t, err)
   618  		require.Equal(t, transportReturnRoute, aries.transportReturnRoute)
   619  		require.NoError(t, aries.Close())
   620  
   621  		transportReturnRoute = decorator.TransportReturnRouteThread
   622  		_, err = New(WithTransportReturnRoute(transportReturnRoute))
   623  		require.Error(t, err)
   624  		require.Contains(t, err.Error(), "invalid transport return route option : "+transportReturnRoute)
   625  
   626  		transportReturnRoute = decorator.TransportReturnRouteNone
   627  		aries, err = New(WithTransportReturnRoute(transportReturnRoute))
   628  		require.NoError(t, err)
   629  		require.Equal(t, transportReturnRoute, aries.transportReturnRoute)
   630  		require.NoError(t, aries.Close())
   631  
   632  		transportReturnRoute = "invalid-transport-route"
   633  		_, err = New(WithTransportReturnRoute(transportReturnRoute))
   634  		require.Error(t, err)
   635  		require.Contains(t, err.Error(), "invalid transport return route option : "+transportReturnRoute)
   636  	})
   637  
   638  	t.Run("test message service provider option", func(t *testing.T) {
   639  		// custom message service provider
   640  		handler := msghandler.NewMockMsgServiceProvider()
   641  		aries, err := New(WithMessageServiceProvider(handler))
   642  		require.NoError(t, err)
   643  
   644  		err = handler.Register(&generic.MockMessageSvc{})
   645  		require.NoError(t, err)
   646  
   647  		require.NotNil(t, aries)
   648  		require.NotNil(t, aries.msgSvcProvider)
   649  	})
   650  
   651  	t.Run("test default message service provider option", func(t *testing.T) {
   652  		// default message service provider
   653  		aries, err := New()
   654  		require.NoError(t, err)
   655  		require.NotNil(t, aries.msgSvcProvider)
   656  		require.Empty(t, aries.msgSvcProvider.Services())
   657  	})
   658  
   659  	t.Run("test verifiable store option", func(t *testing.T) {
   660  		mockStore := &verifiableStoreMocks.MockStore{}
   661  		// default message service provider
   662  		aries, err := New(WithVerifiableStore(mockStore))
   663  		require.NoError(t, err)
   664  		require.Equal(t, mockStore, aries.verifiableStore)
   665  	})
   666  
   667  	t.Run("test DID connection store option", func(t *testing.T) {
   668  		mockStore := &didStoreMocks.MockConnectionStore{}
   669  		aries, err := New(WithDIDConnectionStore(mockStore))
   670  		require.NoError(t, err)
   671  		require.Equal(t, mockStore, aries.didConnectionStore)
   672  	})
   673  
   674  	t.Run("test JSON-LD context store option", func(t *testing.T) {
   675  		store := mockldstore.NewMockContextStore()
   676  
   677  		aries, err := New(WithJSONLDContextStore(store))
   678  		require.NoError(t, err)
   679  		require.Equal(t, store, aries.contextStore)
   680  	})
   681  
   682  	t.Run("test JSON-LD remote provider store option", func(t *testing.T) {
   683  		store := mockldstore.NewMockRemoteProviderStore()
   684  
   685  		aries, err := New(WithJSONLDRemoteProviderStore(store))
   686  		require.NoError(t, err)
   687  		require.Equal(t, store, aries.remoteProviderStore)
   688  	})
   689  
   690  	t.Run("test JSON-LD document loader option", func(t *testing.T) {
   691  		loader, err := ldtestutil.DocumentLoader()
   692  		require.NoError(t, err)
   693  
   694  		aries, err := New(WithJSONLDDocumentLoader(loader))
   695  		require.NoError(t, err)
   696  		require.Equal(t, loader, aries.documentLoader)
   697  	})
   698  
   699  	t.Run("test KeyType and KeyAgreement option", func(t *testing.T) {
   700  		aries, err := New(WithKeyType(kms.BLS12381G2Type), WithKeyAgreementType(kms.NISTP384ECDHKWType))
   701  		require.NoError(t, err)
   702  		require.Equal(t, kms.BLS12381G2Type, aries.keyType)
   703  		require.Equal(t, kms.NISTP384ECDHKWType, aries.keyAgreementType)
   704  	})
   705  
   706  	t.Run("test new with mediaTypeProfiles", func(t *testing.T) {
   707  		aries, err := New(WithMediaTypeProfiles([]string{
   708  			transport.MediaTypeV2EncryptedEnvelope,
   709  			transport.MediaTypeV1EncryptedEnvelope,
   710  		}))
   711  		require.NoError(t, err)
   712  		require.Equal(t, 2, len(aries.mediaTypeProfiles))
   713  		require.Equal(t, transport.MediaTypeV2EncryptedEnvelope, aries.mediaTypeProfiles[0])
   714  		require.Equal(t, transport.MediaTypeV1EncryptedEnvelope, aries.mediaTypeProfiles[1])
   715  	})
   716  
   717  	t.Run("failure while creating KMS Aries provider wrapper", func(t *testing.T) {
   718  		mockStoreProvider := &storage.MockStoreProvider{
   719  			FailNamespace: kms.AriesWrapperStoreName,
   720  			Store: &storage.MockStore{
   721  				Store: map[string]storage.DBEntry{},
   722  			},
   723  		}
   724  
   725  		aries, err := New(WithStoreProvider(mockStoreProvider))
   726  		require.EqualError(t, err, "create Aries provider KMS store wrapper failed: "+
   727  			"failed to open store for name space kmsdb")
   728  		require.Nil(t, aries)
   729  	})
   730  }
   731  
   732  func Test_Packager(t *testing.T) {
   733  	t.Run("test error from packager svc - primary packer", func(t *testing.T) {
   734  		f, err := New(WithInboundTransport(&mockInboundTransport{}),
   735  			WithStoreProvider(storage.NewMockStoreProvider()),
   736  			WithPacker(func(ctx packer.Provider) (packer.Packer, error) {
   737  				return nil, fmt.Errorf("error from primary packer")
   738  			}))
   739  		require.Error(t, err)
   740  		require.Nil(t, f)
   741  		require.Contains(t, err.Error(), "error from primary packer")
   742  	})
   743  
   744  	t.Run("test error from packager svc - fallback packer", func(t *testing.T) {
   745  		f, err := New(WithInboundTransport(&mockInboundTransport{}),
   746  			WithStoreProvider(storage.NewMockStoreProvider()),
   747  			WithPacker(func(ctx packer.Provider) (packer.Packer, error) {
   748  				return nil, nil
   749  			},
   750  				func(ctx packer.Provider) (packer.Packer, error) {
   751  					return nil, fmt.Errorf("error from fallback packer")
   752  				}))
   753  		require.Error(t, err)
   754  		require.Nil(t, f)
   755  		require.Contains(t, err.Error(), "error from fallback packer")
   756  	})
   757  }
   758  
   759  func startMockServer(t *testing.T, handler http.Handler) net.Listener {
   760  	// ":0" will make the listener auto assign a free port
   761  	listener, err := net.Listen("tcp", "127.0.0.1:0")
   762  	require.NoError(t, err)
   763  
   764  	go func() {
   765  		err := http.Serve(listener, handler)
   766  		if err != nil && !strings.Contains(err.Error(), "use of closed network connection") {
   767  			require.NoError(t, err)
   768  		}
   769  	}()
   770  
   771  	return listener
   772  }
   773  
   774  type mockHTTPHandler struct{}
   775  
   776  func (m mockHTTPHandler) ServeHTTP(res http.ResponseWriter, req *http.Request) {
   777  	if req.Body != nil {
   778  		body, err := ioutil.ReadAll(req.Body)
   779  		if err != nil || string(body) == "bad" {
   780  			res.WriteHeader(http.StatusBadRequest)
   781  			res.Write([]byte(fmt.Sprintf("bad request: %s", body))) // nolint
   782  
   783  			return
   784  		}
   785  	}
   786  
   787  	// mocking successful response
   788  	res.WriteHeader(http.StatusAccepted)
   789  	res.Write([]byte("success")) // nolint
   790  }
   791  
   792  func getServerPort(server net.Listener) int {
   793  	return server.Addr().(*net.TCPAddr).Port
   794  }
   795  
   796  type mockInboundTransport struct {
   797  	startError error
   798  	stopError  error
   799  }
   800  
   801  func (m *mockInboundTransport) Start(prov transport.Provider) error {
   802  	if m.startError != nil {
   803  		return m.startError
   804  	}
   805  
   806  	return nil
   807  }
   808  
   809  func (m *mockInboundTransport) Stop() error {
   810  	if m.stopError != nil {
   811  		return m.stopError
   812  	}
   813  
   814  	return nil
   815  }
   816  
   817  func (m *mockInboundTransport) Endpoint() string {
   818  	return ""
   819  }
   820  
   821  type mockProtocolService struct{}
   822  
   823  func (m mockProtocolService) HandleInbound(msg service.DIDCommMsg, ctx service.DIDCommContext) (string, error) {
   824  	panic("implement me")
   825  }
   826  
   827  func (m mockProtocolService) HandleOutbound(msg service.DIDCommMsg, myDID, theirDID string) (string, error) {
   828  	panic("implement me")
   829  }
   830  
   831  func (m mockProtocolService) Accept(msgType string) bool {
   832  	panic("implement me")
   833  }
   834  
   835  func (m mockProtocolService) Name() string {
   836  	panic("implement me")
   837  }
   838  
   839  var errMockProtocolInit = errors.New("mock protocol init error")
   840  
   841  func (m mockProtocolService) Initialize(i interface{}) error {
   842  	return errMockProtocolInit
   843  }