I don't know if I am missing something but I could not find anything that says how to do a test suite like in JUnit. Can someone help me? I saw that documentation offers grouping tests, but when I run from Gradle, the logs are really large, and not very useful
You can group your tests using Tags, see https://kotest.io/docs/framework/tags.html.
For example, to group tests by operating system you could define the following tags:
object Linux : Tag()
object Windows: Tag()
Test cases can then be marked with tags using the config function:
import io.kotest.specs.StringSpec
class MyTest : StringSpec() {
init {
"should run on Windows".config(tags = setOf(Windows)) {
// ...
}
"should run on Linux".config(tags = setOf(Linux)) {
// ...
}
"should run on Windows and Linux".config(tags = setOf(Windows, Linux)) {
// ...
}
}
}
Then you can tell Gradle to run only tests with specific Tags, see https://kotest.io/docs/framework/tags.html#running-with-tags
Example: To run only test tagged with Linux, but not tagged with Database, you would invoke Gradle like this:
gradle test -Dkotest.tags="Linux & !Database"
Tags can also be included/excluded in runtime (for example, if you're running a project configuration instead of properties) through the RuntimeTagExtension:
RuntimeTagExpressionExtension.expression = "Linux & !Database"
Using ktor (1.4, can upgrade if needed) for a server side application, vanilla initialization:
fun main(args: Array<String>): Unit = io.ktor.server.netty.EngineMain.main(args)
...
fun Application.module() {
... stuff
}
I would like the underlying Netty engine to use a CachedThreadPool to process requests. Quite a few of my requests take substantial time to process (e.g. running long queries against a database), which I assume will block the thread processing the request and potentially make the server unresponsive.
How do I do that? Any other options? Do I need to make other changes (e.g. to the coroutine dispatchers) to make sure this has the desired effect?
I think it should be something like this
val env: ApplicationEngineEnvironment = ....
val server = embeddedServer(Netty, env) {
configureBootstrap = {
group(NioEventLoopGroup(..., CachedThreadPool(..)))
}
}
server.start(wait = true)
I'm new to micronaut and server side programming in general. The micronaut documentation, unfortunately, does not make a lot of sense to me, as I do not have a Java background. A lot of the terms like "ApplicationContext" make sense in english, but I have no idea how to use them in practice.
Trying to start with a very basic app that prints different configurations ("localhost", "dev", "prod") depending on the environment it is in.
Here's my controller
#Controller("/")
class EnvironmentController {
// this should return "localhost", "DEV", "PROD" depending on the environment
#Get("/env")
#Produces(MediaType.TEXT_PLAIN)
fun env() = "???" // what should I put here ?
// this should return the correct mongodb connection string for the environment
#Get("/mongo")
#Produces(MediaType.TEXT_PLAIN)
fun mongo() = "???" // what should I put here ?
}
Here's the application.yml. Ideally I'd have 1 yml file for each environment
micronaut:
application:
name: myApp
server:
port: 8090
environment: localhost
mongodb:
uri: 'mongodb://localhost:27017'
Application.kt is untouched with the rest of the files generated by the mn cli tool. How can I set per environment parameters, or pass the yml file as a parameter when starting micronaut?
Are there any conventions around this?
You can specify an environment with -Dmicronaut.environments, or by specifying them in the context builder Micronaut.run in your Application class.
https://docs.micronaut.io/latest/guide/index.html#environments
Then for example application-env.yml will be loaded.
https://docs.micronaut.io/latest/guide/index.html#propertySource
The docs are pretty clear on this
By default Micronaut only looks for application.yml. Then, for tests,dev and prod, it loads application.yml and overrides any values there with the ones defined in application-test.yml, application-dev.yml and application-prod.yml
If you want to enable any other environment, you need to do it manually
public static void main(String[] args) {
Micronaut.build(args)
.mainClass(Application.class)
.defaultEnvironments("dev")
.start();
}
https://docs.micronaut.io/latest/guide/index.html#_default_environment
I'm unable to test my code that uses a native WebSocket. This is the body of the test function:
val webSocket = WebSocket("ws://localhost:8888")
window.setTimeout({
assertEquals(WebSocket.OPEN, webSocket.readyState)
}, 1000)
I'm using Karma with Mocha test runner. The following code executes without any errors, but the setTimeout is actually ignored and never executed.
Mocha seems to support setTimeout-based tests with the --delay. However, when I use the flag with client: { mocha: { delay: true } } Karma configuration, the tests just freeze and fail, outputting the following cause message:
Disconnected, because no message in 60000 ms.
What is the correct way to execute tests with setTimeout? If this is tricky, is there any other way I can perform assertions on the WebSocket after it's fully connected? I don't use any Mocha-specific features yet, so I don't mind changing the framework.
Returning Promise from your #Test function should do the trick.
Something like:
#Test fun testWebSocket() = Promise<Unit> { resolve, reject ->
val webSocket = WebSocket("ws://localhost:8888")
window.setTimeout({
assertEquals(WebSocket.OPEN, webSocket.readyState)
resolve(Unit)
}, 1000)
}
If you want to test async code, you need to tell the test framework when the test is done.
See this answer.
I want to log in the console or in a file, all the queries that Grails does, to check performance.
I had configured this without success.
Any idea would help.
Setting
datasource {
...
logSql = true
}
in DataSource.groovy (as per these instructions) was enough to get it working in my environment. It seems that parts of the FAQ are out of date (e.g. the many-to-many columns backwards question) so this might also be something that changed in the meantime.
I find it more useful to do the following, which is to enable Hibernate's logging to log the SQL along with bind variables (so you can see the values passed into your calls, and easily replicate the SQL in your editor or otherwise).
In your Config.groovy, add the following to your log4j block:
log4j = {
// Enable Hibernate SQL logging with param values
trace 'org.hibernate.type'
debug 'org.hibernate.SQL'
//the rest of your logging config
// ...
}
For grails 3.*
Option #1 add the following to logback.groovy
logger("org.hibernate.SQL", DEBUG, ["STDOUT"], false)
logger("org.hibernate.type.descriptor.sql.BasicBinder", TRACE, ["STDOUT"], false)
or
Option #2 add the following to dataSource in the application.yml. However this approach does not log the parameter values
environments:
local:
dataSource:
logSql: true
formatSql: true
Try this:
log4j = {
...
debug 'org.hibernate.SQL'
trace 'org.hibernate.type.descriptor.sql.BasicBinder'
}
It avoids the performance problems of trace logging the Hibernate type package. This works with Hibernate 3.6 and above. I got this from: https://burtbeckwith.com/blog/?p=1604
Solution is only for development, not production.
All the answers above work and are correct. But they do not show the complete query in a nice human readable way. If want to see the final (without any ?, ?) query you have two options.
A) proxy your jdbc connection with log4jdbc or p6Spy.
B) look at it on database level. For example really easy to do with mysql.
Find out where you general_log_file is. Active general log if no activated already.
mysql command line> show variables like "%general_log%";
mysql command line> set global general_log = true;
Now everything is logged to you log file. Mac / linux example to show nice stream of your queries.
tail -f path_to_log_file
Next works for me:
grails-app/conf/application.yml
# ...
hibernate:
format_sql: true # <<<<<<< ADD THIS <<<<<<<
cache:
queries: false
use_second_level_cache: true
# ...
environments:
development:
dataSource:
logSql: true // <<<<<<< ADD THIS <<<<<<<
dbCreate: create-drop
url: jdbc:h2:mem:...
# ...
grails-app/conf/logback.groovy
// ...
appender('STDOUT', ConsoleAppender) {
encoder(PatternLayoutEncoder) {
pattern = "%level %logger - %msg%n"
}
}
// >>>>>>> ADD IT >>>>>>>
logger 'org.hibernate.type.descriptor.sql.BasicBinder', TRACE, ['STDOUT']
logger 'org.hibernate.SQL', TRACE, ['STDOUT']
// <<<<<<< ADD IT <<<<<<<
root(ERROR, ['STDOUT'])
def targetDir = BuildSettings.TARGET_DIR
// ...
Source: http://sergiodelamo.es/log-sql-grails-3-app/
Pure for reference only, but I use p6spy to log the SQL queries. It's a small intermediate jdbc driver. The exact query is logged as it would be send to the server (with parameters included).
include it in your project:
runtime 'p6spy:p6spy:3.0.0'
Change your datasource driver:
driverClassName: com.p6spy.engine.spy.P6SpyDriver
And your jdbc url:
url: jdbc:p6spy:mysql://
Configure it using spy.properties (in grails-app/conf).
driverlist=org.h2.Driver,com.mysql.jdbc.Driver
autoflush=true
appender=com.p6spy.engine.spy.appender.StdoutLogger
databaseDialectDateFormat=yyyy-MM-dd
logMessageFormat=com.p6spy.engine.spy.appender.MultiLineFormat
Don't forget to disable this for production!
I know this was asked and answered long back .But I just happened to see this question and couldn't stop myself in answering or sharing our sql logging implementation approach in our project.
Hope it be of some help.
Currently it is in development environment.
We are using "log4jdbc Driver Spy " to log sql.
Configuration:
In your BuildConfig.groovy:
add below dependencies:
dependencies {
.....
runtime 'org.lazyluke:log4jdbc-remix:0.2.7'
}
And in your DataSource or other config related :[wherever you have defined the data source related configuration] ,
Add :
datasources{
.....
driverClassName: "net.sf.log4jdbc.DriverSpy",
url: "jdbc:log4jdbc:oracle:thin:#(DESCRIPTION =(ADDRESS_LIST = (ADDRESS = (PROTOCOL = TCP)(HOST = XXXXX.XX>XXX)(PORT = 1521))) (CONNECT_DATA = (SID = XXXX)(SERVER =DEDICATED)))",
....
}
log4j = {
info 'jdbc.sqlonly' //, 'jdbc.resultsettable'
}
From my personal experience I found it quite useful and helpful while debugging.
Also more information you can find in this site. https://code.google.com/p/log4jdbc-remix/
King Regards
If you have the console plugin installed, you can get sql logging with this little code snippet.
// grails 2.3
def logger=ctx.sessionFactory.settings.sqlStatementLogger
// grails 3.3
def logger = ctx.sessionFactory.currentSession.jdbcCoordinator.statementPreparer.jdbcServices.sqlStatementLogger
logger.logToStdout=true
try {
<code that will log sql queries>
}
finally {
logger.logToStdout = false
}
This is a variation on many of the solutions above, but allows you to tweak the value at runtime. And just like the other solutions that deal with logToStdout it only shows the queries and not the bind values.
The idea was stolen from a burtbeckwith post I read some years ago that I can't find right now. It has been edited to work with grails 3.3.
A similar technique can be used to turn on logging for specific integration tests:
class SomeIntegrationSpec extends IntegrationSpec {
def sessionFactory
def setup() {
sessionFactory.settings.sqlStatementLogger.logToStdout = true
}
def cleanup() {
sessionFactory.settings.sqlStatementLogger.logToStdout = false
}
void "some test"() {
...
}
This will turn on sql logging for just the tests in this one file.
For a particular Block of code we can also create a method that accept a closure. eg.
static def executeBlockAndGenerateSqlLogs(Closure closure) {
Logger sqlLogger = Logger.getLogger("org.hibernate.SQL");
Level currentLevel = sqlLogger.level
sqlLogger.setLevel(Level.TRACE)
def result = closure.call()
sqlLogger.setLevel(currentLevel)
result }
executeBlockAndGenerateSqlLogs{DomainClazz.findByPropertyName("property value")}
logback.xml
Grails 5 and above only accepts logback.xml. Add the following inside the configuration tag:
<logger name="org.hibernate.SQL" level="DEBUG" additivity="false">
<appender-ref ref="STDOUT" />
</logger>
<logger name="org.hibernate.type.descriptor.sql.BasicBinder" level="TRACE" additivity="false">
<appender-ref ref="STDOUT" />
</logger>
application.yml
To better visualize SQL queries, add the following:
dataSource:
formatSql: true
If you want logback configuration for development only, you can add the following to the block environments > development with logging configuration in conf/logback-dev.xml:
logging:
config: classpath: logback-dev.xml