Execute custom script before integration tests - spring

my application is using Spring Boot, with 2 main modules main and test. In another directory on same level I have folder which contains script with database triggers which I need create in database before tests.
Here is my project structure:
src/
├── main
├── scripts (this is not module, only default folder)
│   └── custom_script.sql
└── test
└── persistent
└── TestConfiguration.java
Test configuration is only interface where I set some configuration for tests, currently contains following code:
#Sql("../../scripts/custom_script.sql")
public interface TestConfiguration {
}
This code didn't work, and custom_script.sql isn't executed. Can you tell me why, or what is the better to execute it?

Related

How to tell Gradle and Intellij that the project's folder structure is different?

I'm using Gradle with the wrapper, and the folder structure by default is like so:
.
├── settings.gradle
├── build.gradle
├── gradle.properties
├── gradle
│ └── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradlew
└── gradlew.bat
However, I would like to change it to so:
.
├── gradle
| ├── build.gradle
│ ├── settings.gradle
│ ├── gradle.properties
│ └── wrapper
│ ├── gradlew
│ ├── gradlew.bat
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
└── src
├── main
└── test
Other than the fact that I don't know how to tell IntelliJ about the folder structure, I don't know how to change it for Gradle since the Environment Options related with changing the folder structure are deprecated:
-b, --build-file (deprecated)
Specifies the build file. For example: gradle --build-file=foo.gradle. The default is build.gradle, then build.gradle.kts.
-c, --settings-file (deprecated)
Specifies the settings file. For example: gradle --settings-file=somewhere/else/settings.gradle
You can't tell Gradle and Intellij IDEA that you use a non-standard Gradle build layout. And in all honesty, you shouldn't even consider that unless you have strong reasons to do so. There are mainly two reasons for that:
Developers familiar with one Gradle project feel immediately at home when starting with your Gradle project.
A non-standard build file and directory layout requires additional logic in IDE's (which is not present) and requires to provide extra parameters when building on the command line.
To put things into context, please have look at Gradle issue #16402.
Deprecate command-line options that describe the build layout
The -b and -c command-line options are effectively used to describe a non-standard build layout to Gradle. This is problematic because it means that a specific combination of options must be used whenever Gradle is used on that build, for example whenever invoked from the IDE, CI, command-line or some other tool. These command-line options also have some potentially surprising behaviours, such as running a settings script present in the target directory.
We don't think there are any use cases that are strong enough to justify keeping these options, and we should remove them (via deprecation). If we discover there are some use cases, we might consider replacing the options with more self-describing contracts, for example conventions for build script names.

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

why spring boot not use application.properties in test resources first?

I have a special properties file in test resources directory
└── test
├── java
│ └── com
│ └── inter3i
│ ├── dao
│ │ └── FooMapperTest.java
└── resources
└── application.properties
in this application.properties file I specify the MySQL URL.
spring.datasource.url=jdbc:mysql://139.224.xxx.xxx/foo?useSSL=false
then I execute a test
mvn test -Dtest=com.foo.reportapi.dao.FooMapperTest
but it is failed because
org.springframework.transaction.CannotCreateTransactionException: Could not open JDBC Connection for transaction; nested exception is com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: Communications link failure
The last packet sent successfully to the server was 0 milliseconds ago. The driver has not received any packets from the server.
at org.springframework.jdbc.datasource.DataSourceTransactionManager.doBegin(DataSourceTransactionManager.java:289) ~[spring-jdbc-4.3.10.RELEASE.jar:4.3.10.RELEASE]
but actually the MySQL URK is OK, why does it have this error? From wireshark I know it actually connected to another URL
spring.datasource.url=jdbc:mysql://192.168.0.25/foo
which configured in application-default.properties
src
├── main
│ └── resources
│ ├── application-default.properties
So why is it so counterintuitive? I think test classes should use application.properties in test resources first.
In addition I have to use wireshark to find which URL it is connecting to, how could I get Spring Boot to output MySQL URL info explicitly?
As jonrsharpe already mentioned, a specific profile has precedence over the application.properties file - here you find the documentation of the PropertySource order:
https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-external-config.html
You can fix it in serveral ways:
rename main/resources/application-default.properties to main/resources/application.properties
rename test/resources/application.properties to test/resources/application-default.properties
rename test/resources/application.properties to test/resources/application-default-integrationtest.properties and enable the profile with the following annotation on your test class: #ActiveProfiles({"integrationtest"})
I would recommend #3 because it does not depend on classpath priority of main and test elements and states clearly what file is used.
Now to the logging-part of your question.
If you increase the spring log level to "debug" you can see which config files are loaded. You can log a specific property in your own code:
#Component
#Slf4j
public class LogSpringDatasourceUrlProperty {
#Autowired
public LogSpringDatasourceUrlProperty(#Value("${spring.datasource.url}") String jdbcUrl){
log.info( "application uses '{}' as jdbcUrl", jdbcUrl );
}
}

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

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" ?

Should performance/integration tests be considered modules in a multi-module Maven project?

In a Maven multi-module project, should I consider the integration/performance tests projects also as modules?
multi-module-project
  ├── module-war
├── some-other-module
└── etc...
Should I include?
└── performance-tests
ADD:
What if these tests take hours to finish?
What if they require real servers running, like a JBoss cluster?
I would suggest in case of a web application to have a separate module as you suggested. I see performance tests as a kind of integration tests. Like this:
multi-module-project
├── module-war
├── some-other-module
└── integration-tests
└── performance-tests
└── etc...
EDIT:
As mentioned in the comments: "You can control the execution of the integration test by a profile"

Resources