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 }