github.com/hechain20/hechain@v0.0.0-20220316014945-b544036ba106/core/handlers/library/registry_plugin_test.go (about)

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