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