Hyperledger Fabric unit test cross-chaincode invocation without collapsing vendor folder - go

I have been running into compilation issues when I tried to perform unit testing in golang locally, when trying to instantiate and invoke another chaincode through the MockStub object. Below is my file hierarchy:
├── transaction-chaincode
│   ├── transaction.go
│   ├── transaction_test.go
│   └── vendor
└── user-chaincode
├── user.go
├── user_test.go
└── vendor
The scenario here basically involves one of the chaincode, for example user.go, calling the other chaincode transaction.go. The vendor folders in both directories contain the exact same content.
The problem occurs when I try to instantiate a new instance of the transaction chaincode thru shim.NewMockStub in user_test.go, as the transaction mock object looks for the init method from within transaction-chaincode/vendor/ instead of user-chaincode/vendor/, despite the vendor folders having the same packages (and thus the same method).
I was able to get rid of this error by having a single vendor folder at the parent directory of transaction-chaincode & user-chaincode, but I cannot do so for developmental purposes. How would you suggest I solve this unit testing problem while keeping the vendor folders in their respective locations?

If I understood correctly, you are putting shim and other dependencies in each vendor folder. user_test.go then does something like NewMockStub(..., &transaction_chaincode.transaction{}). You want transaction_chaincode.transaction to bind to user/vendor ?
I don't think that'll happen. The shim import in transaction_chaincode.transaction will bind to its transaction_chaincode/vendor.
If the above understanding is correct, why do you think its a "problem" ?

Related

How do I run ansible-test on the root of my collection?

I'm currently developing my own Ansible collection and following the documentation. The directory structure looks like this:
~/.ansible/collections/gertvdijk/mycollection
├── galaxy.yml
├── plugins
│   └── lookup
│   └── mylookup.py
├── README.md
└── tests
└── unit
└── plugins
└── lookup
└── test_mylookup.py
The location ~/.ansible/collections/gertvdijk/mycollection is chosen for convenience so that it's found on the default search paths for collections (COLLECTIONS_PATHS).
The Ansible developer document section Testing collections mentions that I should use ansible-test command from the root of my collection with the given structure.
You must always execute ansible-test from the root directory of a collection.
However, that fails to me, with an error as if I should use this in a project already.
Even running --help fails with the current working directory error:
$ ansible-test --help
ERROR: The current working directory must be at or below:
- an Ansible collection: {...}/ansible_collections/{namespace}/{collection}/
Current working directory: /home/gert/.ansible/collections/gertvdijk/mycollection
Same thing happens by cloning an existing community collection (e.g. community.grafana). The GitHub CI steps include an installation in a ansible_collections/{namespace}/{collection} path (seen here).
Taking that as a work-around for now (I'd like to avoid that); move the repository of the collection to some path that includes /ansible_collections/gertvdijk/mycollection and then run it from there.
This can't be true, right, that the directory name two levels up make or break the ansible-test tool? What am I missing here?
TL;DR: The path for your home collection should be /home/gert/.ansible/collections/ansible_collections/gertvdijk/mycollection
The directories listed in COLLECTION_PATH are actually expected to contain a top level ansible_collections folder. This is linked to the ansible_collections convention used by e.g. module_utils as explained in the documentation
You can also observe how a blank folder gets structured by running e.g.
ansible-galaxy collection install -p /whatever community.grafana
In this case, you will end up with the folder /whatever/ansible_collections/community/grafana.
So your actual home folder collection path should be /home/gert/.ansible/collections/ansible_collections/gertvdijk/mycollection

Structuring a multi-executable Go project

I am trying to build a micro-services architecture project in Go. I am currently using Go 1.11 which supports modules, so I put my root directory in an arbitrary chosen directory, outside of GOPATH.
If I am getting the micro-services architecture concepts right, although my microservices need to be independent, they can share dependencies (and I don't see another way to do stuff, is it?)
Below is my directory structure:
.
├── go.mod
├── lambda
│   └── account_create
│   └── main.go
├── readme.md
└── types
├── account.go
├── location.go
├── order.go
├── pricing.go
├── product.go
└── types.go
Now the behavior I expected was to be able to run go build lambda/account_create and get an executable with that functionality so I can supply it to the respective AWS Lambda function.
However, when I run the command, I get:
can't load package: package lambda/account_create: unknown import path "lambda/account_create": cannot find module providing package lambda/account_create
Please explain me why this does not work and give me some advice on how a project like this should look.
Thank you very much!
Edit Here is my lambda/account_create/main.go file contents:
package account_create
import (
"fmt"
"roasted.ro/pkg/types"
)
func main() {
account := types.UserAccount{Name: "Victor"}
fmt.Printf("Welcome %s", account.Name)
}
To answer the latter part of your question (as the first half is more about preference), you need to do:
go build ./lambda/account_create
Notice the ./. go build takes in a package name or a path. If you don't prepend the path with a ./, it assumes you are giving it a package name.
Edit: the package has to be main if you want an executable. According to the docs, you always have to use package main for projects that build an executable:
Executable commands must always use package main.
Edit: I'll add some opinions on layout:
Consider which parts of your project are exported to other go projects. Meaning someone could import your package and expect to gain value and not have their code break when yours changes.
That should be either in a github.com/you/pkg/somepath package or just github.com/you/somepath.
Anything else (other than main packages) should be under a /internal package.
I typically make a /cmd/myexecurable1 /cmd/myexecurable2 and so forth for each executable.

Where to place go.mod file

I have a repository structure as follows :-
xyz/src
1. abc
- p
- q
- r
2. def
- t
- u
- v
3. etc
- o
- m
- n
I have created a .mod file in src and run go build ./...
Except for local packages everything is fine. So if abc/p is being used in def then it throws the following exception :- cannot find module providing package abc/p. The idea behind keeping the .mod file in src package was to make sure the path is being found from where the mod file is located. Can anyone suggest where should the mod file ideally should be? also i tried placing it one directory above in xyz but still same issue as well as i created one for each sub directory. I am bit confused on this. Will I have to create separate repository for abc and etc. But considering gopath which earlier used to work for the same I think module should also be able to do the same. Any suggestions?
The most common and easiest approach is a single go.mod file in your repository, where that single go.mod file is placed in the root of your repository.
Russ Cox commented in #26664:
For all but power users, you probably want to adopt the usual convention that one repo = one module. It's important for long-term evolution of code storage options that a repo can contain multiple modules, but it's almost certainly not something you want to do by default.
The Modules wiki says:
For example, if you are creating a module for a repository
github.com/my/repo that will contain two packages with import paths
github.com/my/repo/foo and github.com/my/repo/bar, then the first
line in your go.mod file typically would declare your module path as
module github.com/my/repo, and the corresponding on-disk structure
could be:
repo/
├── go.mod <<<<< Note go.mod is located in repo root
├── bar
│   └── bar.go
└── foo
└── foo.go
In Go source code, packages are imported using the full path including
the module path. For example, if a module declared its identity in its
go.mod as module github.com/my/repo, a consumer could do:
import "example.com/my/repo/bar"
That imports package bar from the module github.com/my/repo.
I have a single go.mod in the root of my go application. I am using the following structure inspired by Kat Zien - How Do You Structure Your Go Apps
At the minute one of my applications looks like this
.
├── bin
├── cmd
│   ├── cli
│   └── server
│ └── main.go
├── pkg
│   ├── http
│   │   └── rest
| │ # app-specific directories excluded
│   └── storage
│   └── sqlite
All packages are imported via their full path, i.e. import "github.com/myusername/myapp/pkg/http/rest" otherwise it causes problems all over the place and this was the one change I had to make going from $GOPATH to go mod.
go mod then handles all the dependencies it discovers properly as far as I've discovered so far.

Error with Go modules build using /cmd structure

I'm new to go modules, and am taking them for a spin in a new project which I'm trying to model after the structure described here
Here is an example of my directory structure:
.
├── cmd
│   └── app_name
│   └── main.go
├── go.mod
├── go.sum
├── internal
│   └── bot
│   └── bot.go
└── pkg
├── website_name
│   ├── client.go
│   ├── client.options.go
│   ├── server.go
│   └── server.options.go
└── lib
└── lib.go
Is this idiomatically correct? I know there's not a whole lot of consensus out there, but I'd like to follow best practices.
When I run go build I get 'unexpected module path "github.com/ragurney/app_name/cmd/app_name"', but when I run go build ./... it works. Why?
When I move main.go to the top level everything works as expected. Should I just not use the /cmd pattern with modules?
To answer your first question, its completely opinionated and whatever you like best that is also easy to understand for others you should go with (I think it's fine).
To answer your second question the reason go build ./... works as opposed to go build from the root directory is because ./... starts in the current directory (the root) and searches for all program entry-points and builds them. When you move main.go to the root directory, with this new information, go build working then makes sense, as its only looking in the current directory.
You can explicitly say go build ./cmd/app_name which would also work.
Your application structure works perfectly fine with modules, as I use something very similar to it (https://www.ardanlabs.com/blog/2017/02/package-oriented-design.html) and modules work very well for me.
from what i can tell there is nothing wrong with your project structure. What has worked for me is to run the go build/run command from the project root
eg.
go run github.com/username/project/cmd/somecommand
go build -o somebinary github.com/username/project/cmd/somecommand
I prefer to add the specific file to build, there are some projects with more than one executable
go build -o app ./cmd/server/main.go

Require paths for rspec tests in a Ruby Gem

I am creating a simple Ruby Gem which is currently laid out as per the example in the Making your own gem documentation.
My directory structure:
.
├── Gemfile
├── Gemfile.lock
├── lib
│   ├── go_run
│   │   ├── parser.rb
│   │   └── runner.rb
│   └── go_run.rb
└── spec
├── go_run_spec.rb
├── parser_spec.rb
└── runner_spec.rb
I originally called the Runner class in lib/go_run/runner.rb just Runner, but now, as per the documented example I have namespaced it under GoRun::Runner. The code works. The problem is that now running bundle exec rspec spec/parser_spec.rb does not. It fails with:
/home/smurf/dev/ruby/go_run/lib/go_run/parser.rb:3:in `<top (required)>': uninitialized constant GoRun (NameError)
The 3rd line of that file is:
class GoRun::Parser
I am requireing the library code in spec/parser_spec.rb using require 'go_run/parser'.
I tried including it with require_relative '../lib/go_run/parser', but that produced the same error.
Does anybody know what I am doing wrong?
Update: I have uploaded the complete code on this branch: https://github.com/henrytk/go_run/tree/stackoverflow-43155117
The problem is originating in lib/go_run/parser.rb rather than from the test itself. Whenever Ruby finds the GoRun::Parser definition, it goes looking for GoRun in the constant lookup table, but it won't be there, and so the program exits with an error.
Note that using lib/go_run.rb as an entry point also will not work, because go_run/parser.rb is required before GoRun is defined.
Part of the problem is using GoRun as both the project level namespace, and an entry point class.
There are a couple of idioms you should consider to fix this situation:
Make GoRun a top level module, used purely for namespacing. Move the logic that lives in the current logic into its own class, for example go_run/cli.rb. The go_run.rb file is then kept as a sort of manifest file, that requires the classes of your project.
Use the nested module- and class syntax. This will define the outer module if it isn't already.
Use a spec_helper.rb file that bootstraps your project using require 'go_run', to make sure everything is properly loaded before running your tests.

Resources