github.com/true-sqn/fabric@v2.1.1+incompatible/core/handlers/library/registry_plugin_test.go (about)

     1  // +build go1.9,linux,cgo go1.10,darwin,cgo
     2  // +build !ppc64le
     3  
     4  /*
     5  Copyright SecureKey Technologies Inc. All Rights Reserved.
     6  
     7  SPDX-License-Identifier: Apache-2.0
     8  */
     9  
    10  package library
    11  
    12  import (
    13  	"context"
    14  	"io/ioutil"
    15  	"os"
    16  	"os/exec"
    17  	"path/filepath"
    18  	"testing"
    19  
    20  	"github.com/golang/protobuf/proto"
    21  	"github.com/hyperledger/fabric-protos-go/peer"
    22  	endorsement "github.com/hyperledger/fabric/core/handlers/endorsement/api"
    23  	validation "github.com/hyperledger/fabric/core/handlers/validation/api"
    24  	"github.com/stretchr/testify/assert"
    25  )
    26  
    27  const (
    28  	authPluginPackage      = "github.com/hyperledger/fabric/core/handlers/auth/plugin"
    29  	decoratorPluginPackage = "github.com/hyperledger/fabric/core/handlers/decoration/plugin"
    30  	endorsementTestPlugin  = "github.com/hyperledger/fabric/core/handlers/endorsement/testdata/"
    31  	validationTestPlugin   = "github.com/hyperledger/fabric/core/handlers/validation/testdata/"
    32  )
    33  
    34  // raceEnabled is set to true when the race build tag is enabled.
    35  // see race_test.go
    36  var raceEnabled bool
    37  
    38  func buildPlugin(t *testing.T, dest, pkg string) {
    39  	cmd := exec.Command("go", "build", "-o", dest, "-buildmode=plugin")
    40  	if raceEnabled {
    41  		cmd.Args = append(cmd.Args, "-race")
    42  	}
    43  	cmd.Args = append(cmd.Args, pkg)
    44  	output, err := cmd.CombinedOutput()
    45  	assert.NoError(t, err, "Could not build plugin: "+string(output))
    46  }
    47  
    48  func TestLoadAuthPlugin(t *testing.T) {
    49  	endorser := &mockEndorserServer{}
    50  
    51  	testDir, err := ioutil.TempDir("", "")
    52  	assert.NoError(t, err, "Could not create temp directory for plugins")
    53  	defer os.Remove(testDir)
    54  
    55  	pluginPath := filepath.Join(testDir, "authplugin.so")
    56  	buildPlugin(t, pluginPath, authPluginPackage)
    57  
    58  	testReg := registry{}
    59  	testReg.loadPlugin(pluginPath, Auth)
    60  	assert.Len(t, testReg.filters, 1, "Expected filter to be registered")
    61  
    62  	testReg.filters[0].Init(endorser)
    63  	testReg.filters[0].ProcessProposal(nil, nil)
    64  	assert.True(t, endorser.invoked, "Expected filter to invoke endorser on invoke")
    65  }
    66  
    67  func TestLoadDecoratorPlugin(t *testing.T) {
    68  	testProposal := &peer.Proposal{Payload: []byte("test")}
    69  	testInput := &peer.ChaincodeInput{Args: [][]byte{[]byte("test")}}
    70  
    71  	testDir, err := ioutil.TempDir("", "")
    72  	assert.NoError(t, err, "Could not create temp directory for plugins")
    73  	defer os.Remove(testDir)
    74  
    75  	pluginPath := filepath.Join(testDir, "decoratorplugin.so")
    76  	buildPlugin(t, pluginPath, decoratorPluginPackage)
    77  
    78  	testReg := registry{}
    79  	testReg.loadPlugin(pluginPath, Decoration)
    80  	assert.Len(t, testReg.decorators, 1, "Expected decorator to be registered")
    81  
    82  	decoratedInput := testReg.decorators[0].Decorate(testProposal, testInput)
    83  	assert.True(t, proto.Equal(decoratedInput, testInput), "Expected chaincode input to remain unchanged")
    84  }
    85  
    86  func TestEndorsementPlugin(t *testing.T) {
    87  	testDir, err := ioutil.TempDir("", "")
    88  	assert.NoError(t, err, "Could not create temp directory for plugins")
    89  	defer os.Remove(testDir)
    90  
    91  	pluginPath := filepath.Join(testDir, "endorsementplugin.so")
    92  	buildPlugin(t, pluginPath, endorsementTestPlugin)
    93  
    94  	testReg := registry{endorsers: make(map[string]endorsement.PluginFactory)}
    95  	testReg.loadPlugin(pluginPath, Endorsement, "escc")
    96  	mapping := testReg.Lookup(Endorsement).(map[string]endorsement.PluginFactory)
    97  	factory := mapping["escc"]
    98  	assert.NotNil(t, factory)
    99  	instance := factory.New()
   100  	assert.NotNil(t, instance)
   101  	assert.NoError(t, instance.Init())
   102  	_, output, err := instance.Endorse([]byte{1, 2, 3}, nil)
   103  	assert.NoError(t, err)
   104  	assert.Equal(t, []byte{1, 2, 3}, output)
   105  }
   106  
   107  func TestValidationPlugin(t *testing.T) {
   108  	testDir, err := ioutil.TempDir("", "")
   109  	assert.NoError(t, err, "Could not create temp directory for plugins")
   110  	defer os.Remove(testDir)
   111  
   112  	pluginPath := filepath.Join(testDir, "validationplugin.so")
   113  	buildPlugin(t, pluginPath, validationTestPlugin)
   114  
   115  	testReg := registry{validators: make(map[string]validation.PluginFactory)}
   116  	testReg.loadPlugin(pluginPath, Validation, "vscc")
   117  	mapping := testReg.Lookup(Validation).(map[string]validation.PluginFactory)
   118  	factory := mapping["vscc"]
   119  	assert.NotNil(t, factory)
   120  	instance := factory.New()
   121  	assert.NotNil(t, instance)
   122  	assert.NoError(t, instance.Init())
   123  	err = instance.Validate(nil, "", 0, 0)
   124  	assert.NoError(t, err)
   125  }
   126  
   127  func TestLoadPluginInvalidPath(t *testing.T) {
   128  	defer func() {
   129  		if r := recover(); r == nil {
   130  			t.Errorf("Expected panic with incorrect plugin path")
   131  		}
   132  	}()
   133  	reg.loadPlugin("/NotAReal/Plugin.so", Auth)
   134  }
   135  
   136  type mockEndorserServer struct {
   137  	invoked bool
   138  }
   139  
   140  func (es *mockEndorserServer) ProcessProposal(ctx context.Context, prop *peer.SignedProposal) (*peer.ProposalResponse, error) {
   141  	es.invoked = true
   142  	return nil, nil
   143  }