Skip to content

Commit 52faefa

Browse files
committed
Fix metadata root for module packages
The metadata path should be the import path relative to the module root, not simply the import path. Fix the calculation and add additional tests. FAB-16530 # done Change-Id: If987c758c1718a33b6572998196e5d3ad53888a2 Signed-off-by: Matthew Sykes <sykesmat@us.ibm.com>
1 parent 7af6c32 commit 52faefa

File tree

6 files changed

+146
-23
lines changed

6 files changed

+146
-23
lines changed

core/chaincode/platforms/golang/list.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -105,13 +105,13 @@ const moduleListFormat = `{
105105
"dir": "{{ .Module.Dir }}",
106106
"gomod": "{{ .Module.GoMod }}",
107107
"import_path": "{{ .ImportPath }}",
108-
"path": "{{ .Module.Path }}"
108+
"module_path": "{{ .Module.Path }}"
109109
}`
110110

111111
type ModuleInfo struct {
112112
Dir string `json:"dir,omitempty"`
113113
ImportPath string `json:"import_path,omitempty"`
114-
Path string `json:"path,omitempty"`
114+
ModulePath string `json:"module_path,omitempty"`
115115
GoMod string `json:"gomod,omitempty"`
116116
}
117117

core/chaincode/platforms/golang/list_test.go

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,10 +86,24 @@ func Test_listModuleInfo(t *testing.T) {
8686
assert.NoError(t, err, "failed to get module info")
8787

8888
expected := &ModuleInfo{
89-
Path: "ccmodule",
89+
ModulePath: "ccmodule",
9090
ImportPath: "ccmodule",
9191
Dir: moduleDir,
9292
GoMod: filepath.Join(moduleDir, "go.mod"),
9393
}
9494
assert.Equal(t, expected, mi)
95+
96+
err = os.Chdir("nested")
97+
require.NoError(t, err, "failed to change to module directory")
98+
99+
mi, err = listModuleInfo()
100+
assert.NoError(t, err, "failed to get module info")
101+
102+
expected = &ModuleInfo{
103+
ModulePath: "ccmodule",
104+
ImportPath: "ccmodule/nested",
105+
Dir: moduleDir,
106+
GoMod: filepath.Join(moduleDir, "go.mod"),
107+
}
108+
assert.Equal(t, expected, mi)
95109
}

core/chaincode/platforms/golang/platform.go

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ func (p *Platform) Name() string {
4242
//
4343
// NOTE: this is only used at the _client_ side by the peer CLI.
4444
func (p *Platform) ValidatePath(rawPath string) error {
45-
_, err := describeCode(rawPath)
45+
_, err := DescribeCode(rawPath)
4646
if err != nil {
4747
return err
4848
}
@@ -113,7 +113,7 @@ const c_ISDIR = 040000
113113
//
114114
// NOTE: this is only used at the _client_ side by the peer CLI.
115115
func (p *Platform) GetDeploymentPayload(codepath string) ([]byte, error) {
116-
codeDescriptor, err := describeCode(codepath)
116+
codeDescriptor, err := DescribeCode(codepath)
117117
if err != nil {
118118
return nil, err
119119
}
@@ -234,8 +234,8 @@ func (cd CodeDescriptor) isMetadata(path string) bool {
234234
)
235235
}
236236

237-
// describeCode returns GOPATH and package information
238-
func describeCode(path string) (*CodeDescriptor, error) {
237+
// DescribeCode returns GOPATH and package information.
238+
func DescribeCode(path string) (*CodeDescriptor, error) {
239239
if path == "" {
240240
return nil, errors.New("cannot collect files from empty chaincode path")
241241
}
@@ -247,9 +247,15 @@ func describeCode(path string) (*CodeDescriptor, error) {
247247
}
248248

249249
if modInfo != nil {
250+
// calculate where the metadata should be relative to module root
251+
relImport, err := filepath.Rel(modInfo.ModulePath, modInfo.ImportPath)
252+
if err != nil {
253+
return nil, err
254+
}
255+
250256
return &CodeDescriptor{
251257
Module: true,
252-
MetadataRoot: filepath.Join(modInfo.Dir, modInfo.ImportPath, "META-INF"),
258+
MetadataRoot: filepath.Join(modInfo.Dir, relImport, "META-INF"),
253259
Path: modInfo.ImportPath,
254260
Source: modInfo.Dir,
255261
}, nil

core/chaincode/platforms/golang/platform_test.go

Lines changed: 85 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -189,12 +189,14 @@ func Test_findSource(t *testing.T) {
189189
Path: "ccmodule",
190190
})
191191
require.NoError(t, err, "failed to find source")
192-
assert.Len(t, source, 5)
192+
assert.Len(t, source, 7)
193193
assert.Contains(t, source, "META-INF/statedb/couchdb/indexes/indexOwner.json")
194194
assert.Contains(t, source, "src/go.mod")
195195
assert.Contains(t, source, "src/go.sum")
196196
assert.Contains(t, source, "src/chaincode.go")
197197
assert.Contains(t, source, "src/customlogger/customlogger.go")
198+
assert.Contains(t, source, "src/nested/chaincode.go")
199+
assert.Contains(t, source, "src/nested/META-INF/statedb/couchdb/indexes/nestedIndexOwner.json")
198200
})
199201

200202
t.Run("NonExistent", func(t *testing.T) {
@@ -204,32 +206,71 @@ func Test_findSource(t *testing.T) {
204206
})
205207
}
206208

207-
func TestDeploymentPayload(t *testing.T) {
208-
platform := &Platform{}
209-
210-
payload, err := platform.GetDeploymentPayload("github.com/hyperledger/fabric/core/chaincode/platforms/golang/testdata/src/chaincodes/noop")
211-
assert.NoError(t, err)
209+
func tarContents(t *testing.T, payload []byte) []string {
210+
var files []string
212211

213212
is := bytes.NewReader(payload)
214213
gr, err := gzip.NewReader(is)
215-
assert.NoError(t, err, "failed to create new gzip reader")
216-
tr := tar.NewReader(gr)
214+
require.NoError(t, err, "failed to create new gzip reader")
217215

218-
// gather the entries and verify contents
219-
var foundIndexArtifact bool
216+
tr := tar.NewReader(gr)
220217
for {
221218
header, err := tr.Next()
222219
if err == io.EOF {
223220
break
224221
}
225-
assert.NoError(t, err, "unexpected error while processing package")
222+
assert.NoError(t, err)
226223

227-
if header.Name == "META-INF/statedb/couchdb/indexes/indexOwner.json" {
228-
foundIndexArtifact = true
229-
break
224+
if header.Typeflag == tar.TypeReg {
225+
files = append(files, header.Name)
230226
}
231227
}
232-
assert.Equal(t, true, foundIndexArtifact, "should have found statedb index artifact in noop META-INF directory")
228+
229+
return files
230+
}
231+
232+
func TestGopathDeploymentPayload(t *testing.T) {
233+
platform := &Platform{}
234+
235+
payload, err := platform.GetDeploymentPayload("github.com/hyperledger/fabric/core/chaincode/platforms/golang/testdata/src/chaincodes/noop")
236+
assert.NoError(t, err)
237+
238+
contents := tarContents(t, payload)
239+
assert.Contains(t, contents, "META-INF/statedb/couchdb/indexes/indexOwner.json")
240+
}
241+
242+
func TestModuleDeploymentPayload(t *testing.T) {
243+
platform := &Platform{}
244+
245+
t.Run("TopLevel", func(t *testing.T) {
246+
dp, err := platform.GetDeploymentPayload("testdata/ccmodule")
247+
assert.NoError(t, err)
248+
contents := tarContents(t, dp)
249+
assert.ElementsMatch(t, contents, []string{
250+
"META-INF/statedb/couchdb/indexes/indexOwner.json", // top level metadata
251+
"src/chaincode.go",
252+
"src/customlogger/customlogger.go",
253+
"src/go.mod",
254+
"src/go.sum",
255+
"src/nested/META-INF/statedb/couchdb/indexes/nestedIndexOwner.json",
256+
"src/nested/chaincode.go",
257+
})
258+
})
259+
260+
t.Run("NestedPackage", func(t *testing.T) {
261+
dp, err := platform.GetDeploymentPayload("testdata/ccmodule/nested")
262+
assert.NoError(t, err)
263+
contents := tarContents(t, dp)
264+
assert.ElementsMatch(t, contents, []string{
265+
"META-INF/statedb/couchdb/indexes/nestedIndexOwner.json", // nested metadata
266+
"src/META-INF/statedb/couchdb/indexes/indexOwner.json",
267+
"src/chaincode.go",
268+
"src/customlogger/customlogger.go",
269+
"src/go.mod",
270+
"src/go.sum",
271+
"src/nested/chaincode.go",
272+
})
273+
})
233274
}
234275

235276
func updateGopath(t *testing.T, path string) func() {
@@ -335,6 +376,35 @@ echo Done!
335376
assert.Equal(t, expectedOpts, opts)
336377
}
337378

379+
func TestDescribeCode(t *testing.T) {
380+
abs, err := filepath.Abs("testdata/ccmodule")
381+
assert.NoError(t, err)
382+
383+
t.Run("TopLevelModulePackage", func(t *testing.T) {
384+
cd, err := DescribeCode("testdata/ccmodule")
385+
assert.NoError(t, err)
386+
expected := &CodeDescriptor{
387+
Source: abs,
388+
MetadataRoot: filepath.Join(abs, "META-INF"),
389+
Path: "ccmodule",
390+
Module: true,
391+
}
392+
assert.Equal(t, expected, cd)
393+
})
394+
395+
t.Run("NestedModulePackage", func(t *testing.T) {
396+
cd, err := DescribeCode("testdata/ccmodule/nested")
397+
assert.NoError(t, err)
398+
expected := &CodeDescriptor{
399+
Source: abs,
400+
MetadataRoot: filepath.Join(abs, "nested", "META-INF"),
401+
Path: "ccmodule/nested",
402+
Module: true,
403+
}
404+
assert.Equal(t, expected, cd)
405+
})
406+
}
407+
338408
func TestMain(m *testing.M) {
339409
viper.SetConfigName("core")
340410
viper.SetEnvPrefix("CORE")
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{"index":{"fields":["docType","owner"]},"ddoc":"indexOwnerDoc", "name":"indexOwner","type":"json"}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
/*
2+
Copyright IBM Corp. All Rights Reserved.
3+
4+
SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
package main
8+
9+
import (
10+
"ccmodule/customlogger"
11+
12+
"github.com/hyperledger/fabric-chaincode-go/shim"
13+
pb "github.com/hyperledger/fabric-protos-go/peer"
14+
)
15+
16+
// No-op test chaincode
17+
type TestChaincode struct{}
18+
19+
func (t *TestChaincode) Init(stub shim.ChaincodeStubInterface) pb.Response {
20+
return shim.Success(nil)
21+
}
22+
23+
func (t *TestChaincode) Invoke(stub shim.ChaincodeStubInterface) pb.Response {
24+
return shim.Success(nil)
25+
}
26+
27+
func main() {
28+
err := shim.Start(new(TestChaincode))
29+
if err != nil {
30+
customlogger.Logf("Error starting TestChaincode: %s", err)
31+
}
32+
}

0 commit comments

Comments
 (0)