diff --git a/grails-app/conf/BuildConfig.groovy b/grails-app/conf/BuildConfig.groovy index 28a935f..6f5a324 100644 --- a/grails-app/conf/BuildConfig.groovy +++ b/grails-app/conf/BuildConfig.groovy @@ -2,6 +2,13 @@ grails.project.class.dir = "target/classes" grails.project.test.class.dir = "target/test-classes" grails.project.test.reports.dir = "target/test-reports" +grails.war.resources = { stagingDir -> + //delete test classes + delete(verbose: true) { + fileset dir: stagingDir, includes: 'test/**/*.class' + } +} + grails.project.fork = [ // configure settings for compilation JVM, note that if you alter the Groovy version forked compilation is required // compile: [maxMemory: 256, minMemory: 64, debug: false, maxPerm: 256, daemon:true], @@ -79,6 +86,7 @@ grails.project.dependency.resolution = { test { dependencies { compile "com.h2database:h2:1.4.195" + compile "org.springframework.boot:spring-boot-test:2.1.1.RELEASE" } } } diff --git a/scripts/_Events.groovy b/scripts/_Events.groovy new file mode 100644 index 0000000..d2fda25 --- /dev/null +++ b/scripts/_Events.groovy @@ -0,0 +1,3 @@ +eventCompileStart = { + projectCompiler.srcDirectories << "${basedir}/test/" +} diff --git a/test/integration/org/grails/ignite/ConfigurationIntegrationSpec.groovy b/test/integration/org/grails/ignite/ConfigurationIntegrationSpec.groovy index a9210c3..d17267e 100644 --- a/test/integration/org/grails/ignite/ConfigurationIntegrationSpec.groovy +++ b/test/integration/org/grails/ignite/ConfigurationIntegrationSpec.groovy @@ -1,6 +1,7 @@ package org.grails.ignite import grails.test.spock.IntegrationSpec +import org.apache.ignite.Ignite import org.apache.ignite.cache.CacheAtomicityMode import org.apache.ignite.cache.CacheMode import org.apache.ignite.cache.CacheWriteSynchronizationMode @@ -10,11 +11,17 @@ class ConfigurationIntegrationSpec extends IntegrationSpec { def grid def sessionFactory - void "test cache configuration"() { - setup: - assert grid.name() != null // force creation of grid - assert grid.underlyingIgnite != null + void "test grid creation"() { + when: + grid + then: + grid.name() != null + grid.underlyingIgnite != null + grid instanceof Ignite + } + + void "test cache configuration"() { when: def caches = grid.configuration().cacheConfiguration.collectEntries { [(it.name): it] } @@ -31,10 +38,6 @@ class ConfigurationIntegrationSpec extends IntegrationSpec { } void "test l2 cache configuration"() { - setup: - assert grid.name() != null // force creation of grid - assert grid.underlyingIgnite != null - when: def caches = grid.configuration().cacheConfiguration.collectEntries { [(it.name): it] } diff --git a/test/integration/org/grails/ignite/DistributedSchedulerIntegrationSpec.groovy b/test/integration/org/grails/ignite/DistributedSchedulerIntegrationSpec.groovy new file mode 100644 index 0000000..5ae4bd3 --- /dev/null +++ b/test/integration/org/grails/ignite/DistributedSchedulerIntegrationSpec.groovy @@ -0,0 +1,110 @@ +package org.grails.ignite + +import grails.test.spock.IntegrationSpec +import java.util.concurrent.TimeUnit +import resources.MockRunnable + +class DistributedSchedulerIntegrationSpec extends IntegrationSpec { + + DistributedSchedulerService distributedSchedulerService + + def setup() { + } + + def cleanup() { + } + + void "schedules at a fixed rate"() { + setup: + def runnable = new MockRunnable() + distributedSchedulerService.startScheduler() + + when: + distributedSchedulerService.scheduleAtFixedRate(runnable, 0, 100, TimeUnit.MILLISECONDS, 0) + sleep(1000) + + then: + runnable.callCount >= 2 + def avg = runnable.delayTimes[1..-1].with { + sum() / size() + } + avg >= 50 && avg <= 150 + } + + void "schedules with a fixed delay"() { + setup: + def runnable = new MockRunnable() + distributedSchedulerService.startScheduler() + + when: + distributedSchedulerService.scheduleWithFixedDelay(runnable, 0, 50, TimeUnit.MILLISECONDS, 0) + sleep(120) + + then: + runnable.callCount >= 2 + runnable.delayTimes[1..-1].each { assert it >= 50 } + } + + void "schedules a single time"() { + setup: + def runnable = new MockRunnable() + distributedSchedulerService.startScheduler() + + when: + distributedSchedulerService.schedule(runnable, 0, TimeUnit.MILLISECONDS, 0) + sleep(120) + + then: + runnable.callCount == 1 + } + + void "schedules using a cron expression"() { + setup: + def runnable = new MockRunnable() + distributedSchedulerService.startScheduler() + def cronExp = "* * * * *" + + when: + IgniteCronDistributedRunnableScheduledFuture future = (IgniteCronDistributedRunnableScheduledFuture) distributedSchedulerService.scheduleWithCron( + runnable, cronExp, 0, "name" + ) + + then: + future.cronTaskId + future.toDataMap().cronExpression == cronExp + } + + void "schedules an anonymous class"() { + setup: + def runnable = new Runnable () { + public boolean called = false + + public void run () { + called = true + } + } + distributedSchedulerService.startScheduler() + + when: + distributedSchedulerService.schedule(runnable, 0, TimeUnit.MILLISECONDS, 0) + sleep(120) + + then: + runnable.called + } + + //because Groovy 2.x doesn't support lambdas (use Groovy 3) + void "schedules a closure"() { + setup: + def called = false + Runnable runnable = { called = true } as Runnable + distributedSchedulerService.startScheduler() + + when: + distributedSchedulerService.schedule(runnable, 0, TimeUnit.MILLISECONDS, 0) + sleep(120) + + then: + called + } +} diff --git a/test/integration/org/grails/ignite/MessagingIntegrationSpec.groovy b/test/integration/org/grails/ignite/MessagingIntegrationSpec.groovy index 7080019..02b3502 100644 --- a/test/integration/org/grails/ignite/MessagingIntegrationSpec.groovy +++ b/test/integration/org/grails/ignite/MessagingIntegrationSpec.groovy @@ -1,11 +1,16 @@ package org.grails.ignite import grails.test.spock.IntegrationSpec +import org.junit.Rule +import org.springframework.boot.test.rule.OutputCapture class MessagingIntegrationSpec extends IntegrationSpec { def messagingService + @Rule + OutputCapture capture = new OutputCapture() + def setup() { } @@ -15,26 +20,24 @@ class MessagingIntegrationSpec extends IntegrationSpec { void "test something"() { setup: def exceptionThrown = false + def testStrings = [ + "world test 123232", + "goodbye test 5353535" + ] when: messagingService.registerReceiver(queue: 'hello', new ExpressionEvaluatingMessageReceiver('println')) - messagingService.sendMessage(queue: 'hello', "world") - messagingService.sendMessage(queue: 'hello', "goodbye") + messagingService.sendMessage(queue: 'hello', testStrings[0]) + messagingService.sendMessage(queue: 'hello', testStrings[1]) - messagingService.registerReceiver(topic: 'hello', new ExpressionEvaluatingMessageReceiver('iGotTheMessage')) + messagingService.registerReceiver(topic: 'hello', new ExpressionEvaluatingMessageReceiver('is')) messagingService.sendMessage(topic: 'hello', "world") - try {// will throw exception - messagingService.sendMessage(queue: 'noreceiver', "goodbye") - } catch (RuntimeException r) { - exceptionThrown = true - } + //will log warning + messagingService.sendMessage(queue: 'noreceiver', "goodbye") then: - exceptionThrown - } - - private boolean iGotTheMessage(message) { - println "iGotTheMessage: ${message}" + testStrings.each { capture.toString().contains(it) } + capture.toString().contains("WARN ignite.IgniteMessagingQueueReceiverWrapper - No receiver configured for queue noreceiver") } } diff --git a/test/integration/resources/MockRunnable.groovy b/test/integration/resources/MockRunnable.groovy new file mode 100644 index 0000000..02ad5a8 --- /dev/null +++ b/test/integration/resources/MockRunnable.groovy @@ -0,0 +1,31 @@ +package resources + +/* + * I tried using both Spock to mock a runnable, but I couldn't get it to serialize correctly + * I also tried using Mockito but couldn't get it work either. However, it is likely that + * my ultimate solution of compiling the test classes would have worked with Mockito + */ +class MockRunnable implements Runnable, Serializable { + + private Long callCount = 0 + private ArrayList delayTimes = [] + private lastCallTime = System.currentTimeMillis() + + @Override + public void run () { + //increment call count + callCount++ + Long callTime = System.currentTimeMillis() + //store call time + delayTimes << callTime - lastCallTime + lastCallTime = callTime + } + + public Long getCallCount() { + return callCount + } + + public ArrayList getDelayTimes() { + return delayTimes + } +}