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 }