Browse files

functional tests

  • Loading branch information...
1 parent 18fb279 commit d7a2bb2c2c0fab3721636697373e0d024176ec67 Burt Beckwith committed Apr 24, 2012
View
168 scripts/CreateCacheEhcacheTestApps.groovy
@@ -0,0 +1,168 @@
+includeTargets << grailsScript('_GrailsBootstrap')
+
+functionalTestPluginVersion = '1.2.7'
+projectfiles = new File(basedir, 'webtest/projectFiles')
+grailsHome = null
+dotGrails = null
+grailsVersion = null
+projectDir = null
+appName = null
+pluginVersion = null
+pluginZip = null
+testprojectRoot = null
+deleteAll = false
+
+target(createCacheEhcacheTestApps: 'Creates test apps for functional tests') {
+
+ def configFile = new File(basedir, 'testapps.config.groovy')
+ if (!configFile.exists()) {
+ error "$configFile.path not found"
+ }
+
+ new ConfigSlurper().parse(configFile.text).each { name, config ->
+ printMessage "\nCreating app based on configuration $name: ${config.flatten()}\n"
+ init name, config
+ createApp()
+ installPlugins()
+ copyProjectFiles()
+ copyTests()
+ }
+}
+
+private void createApp() {
+
+ ant.mkdir dir: projectDir
+
+ deleteDir testprojectRoot
+ deleteDir "$dotGrails/projects/$appName"
+
+ callGrails(grailsHome, projectDir, 'dev', 'create-app') {
+ ant.arg value: appName
+ }
+}
+
+private void installPlugins() {
+
+ File buildConfig = new File(testprojectRoot, 'grails-app/conf/BuildConfig.groovy')
+ String contents = buildConfig.text
+ contents = contents.replace('grails.project.class.dir = "target/classes"', "grails.project.work.dir = 'target'")
+ contents = contents.replace('grails.project.test.class.dir = "target/test-classes"', '')
+ contents = contents.replace('grails.project.test.reports.dir = "target/test-reports"', '')
+
+ buildConfig.withWriter { it.writeLine contents }
+
+ File configGroovy = new File(testprojectRoot, 'grails-app/conf/Config.groovy')
+ contents = configGroovy.text
+ contents += '''
+
+grails.cache.config = {
+ cache {
+ name 'message'
+ eternal false
+ overflowToDisk true
+ maxElementsInMemory 10000
+ maxElementsOnDisk 10000000
+ }
+}
+
+'''
+
+ configGroovy.withWriter { it.writeLine contents }
+
+ callGrails(grailsHome, testprojectRoot, 'dev', 'install-plugin') {
+ ant.arg value: "functional-test $functionalTestPluginVersion"
+ }
+
+ callGrails(grailsHome, testprojectRoot, 'dev', 'install-plugin') {
+ ant.arg value: pluginZip.absolutePath
+ }
+
+ // trigger plugin initialization
+ callGrails(grailsHome, testprojectRoot, 'dev', 'compile')
+}
+
+private void copyProjectFiles() {
+
+ ant.copy(todir: "$testprojectRoot/grails-app/controllers") {
+ fileset(dir: projectfiles.path) {
+ include name: '*Controller.groovy'
+ }
+ }
+
+ ant.copy(todir: "$testprojectRoot/grails-app/services") {
+ fileset(dir: projectfiles.path) {
+ include name: '*Service.groovy'
+ }
+ }
+
+ ant.copy file: "$projectfiles.path/LogEntry.groovy", todir: "$testprojectRoot/grails-app/domain"
+
+ ant.copy file: "$projectfiles.path/Message.groovy", todir: "$testprojectRoot/src/groovy"
+}
+
+private void copyTests() {
+ ant.copy(todir: "$testprojectRoot/test/functional") {
+ fileset(dir: "$basedir/webtest/tests")
+ }
+}
+
+private void deleteDir(String path) {
+ if (new File(path).exists() && !deleteAll) {
+ String code = "confirm.delete.$path"
+ ant.input message: "$path exists, ok to delete?", addproperty: code, validargs: 'y,n,a'
+ def result = ant.antProject.properties[code]
+ if ('a'.equalsIgnoreCase(result)) {
+ deleteAll = true
+ }
+ else if (!'y'.equalsIgnoreCase(result)) {
+ printMessage "\nNot deleting $path"
+ exit 1
+ }
+ }
+
+ ant.delete dir: path
+}
+
+private void init(String name, config) {
+
+ pluginVersion = config.pluginVersion
+ if (!pluginVersion) {
+ error "pluginVersion wasn't specified for config '$name'"
+ }
+
+ pluginZip = new File(basedir, "grails-cache-ehcache-${pluginVersion}.zip")
+ if (!pluginZip.exists()) {
+ error "plugin $pluginZip.absolutePath not found"
+ }
+
+ grailsHome = config.grailsHome
+ if (!new File(grailsHome).exists()) {
+ error "Grails home $grailsHome not found"
+ }
+
+ projectDir = config.projectDir
+ appName = 'cache-ehcache-test-' + name
+ testprojectRoot = "$projectDir/$appName"
+
+ grailsVersion = config.grailsVersion
+ dotGrails = config.dotGrails + '/' + grailsVersion
+}
+
+private void error(String message) {
+ errorMessage "\nERROR: $message"
+ exit 1
+}
+
+private void callGrails(String grailsHome, String dir, String env, String action, extraArgs = null) {
+ ant.exec(executable: "$grailsHome/bin/grails", dir: dir, failonerror: 'true') {
+ ant.env key: 'GRAILS_HOME', value: grailsHome
+ ant.arg value: env
+ ant.arg value: action
+ extraArgs?.call()
+ }
+}
+
+printMessage = { String message -> event('StatusUpdate', [message]) }
+errorMessage = { String message -> event('StatusError', [message]) }
+
+setDefaultTarget 'createCacheEhcacheTestApps'
View
4 webtest/projectFiles/LogEntry.groovy
@@ -0,0 +1,4 @@
+class LogEntry {
+ String message
+ Date dateCreated
+}
View
8 webtest/projectFiles/Message.groovy
@@ -0,0 +1,8 @@
+class Message {
+ String title
+ String body
+
+ String toString() {
+ "$title: $body"
+ }
+}
View
31 webtest/projectFiles/MessageService.groovy
@@ -0,0 +1,31 @@
+import java.util.concurrent.ConcurrentHashMap
+
+import javax.annotation.PostConstruct
+
+import org.springframework.cache.annotation.CacheEvict
+import org.springframework.cache.annotation.Cacheable
+
+class MessageService {
+
+ private final Map<String, Message> messages = new ConcurrentHashMap<String, Message>()
+
+ @Cacheable('message')
+ Message getMessage(String title) {
+ println 'Fetching message'
+ return messages.get(title)
+ }
+
+ @CacheEvict(value='message', key='message.title')
+ void save(Message message) {
+ println "Saving message $message"
+ messages.put(message.title, message)
+ }
+
+ Collection<Message> findAll() { messages.values() }
+
+ @PostConstruct
+ void addSomeDefaultMessages() {
+ save new Message(title: 'Hello', body: 'Hello World')
+ save new Message(title: 'Appointment', body: 'Remember the milk!')
+ }
+}
View
45 webtest/projectFiles/TestController.groovy
@@ -0,0 +1,45 @@
+import grails.converters.JSON
+
+import org.springframework.cache.annotation.CacheEvict
+import org.springframework.cache.annotation.Cacheable
+
+class TestController {
+
+ def grailsCacheManager
+
+ @Cacheable('message')
+ def index() {
+ new LogEntry(message: 'Called index() action').save(failOnError: true, flush: true)
+ render 'index'
+ }
+
+ @CacheEvict(value='message', allEntries=true)
+ def evict() {
+ new LogEntry(message: 'Called evict() action').save(failOnError: true, flush: true)
+ render 'evict'
+ }
+
+ def clearLogEntries() {
+ LogEntry.list()*.delete()
+ render 'deleted all LogEntry instances'
+ }
+
+ def logEntryCount() {
+ render LogEntry.count() as String
+ }
+
+ def mostRecentLogEntry() {
+ def entry = LogEntry.listOrderById(order: 'desc', max: 1)[0]
+ if (entry) {
+ def map = [id: entry.id, message: entry.message, dateCreated: entry.dateCreated.time]
+ render map as JSON
+ return
+ }
+ render 'none'
+ }
+
+ def clearCache() {
+ grailsCacheManager.getCache('message').evict()
+ render 'cleared cache'
+ }
+}
View
94 webtest/tests/CacheTests.groovy
@@ -0,0 +1,94 @@
+import functionaltestplugin.FunctionalTestCase
+import grails.converters.JSON
+
+class CacheTests extends FunctionalTestCase {
+
+ @Override
+ protected void setUp() {
+ super.setUp()
+
+ get '/test/evict'
+ assertContent 'evict'
+
+ get '/test/clearCache'
+ assertContent 'cleared cache'
+
+ get '/test/clearLogEntries'
+ assertContent 'deleted all LogEntry instances'
+ }
+
+ void testCacheAndEvict() {
+
+ // check that there are no log entries
+ get '/test/logEntryCount'
+ assertContent '0'
+
+ get '/test/mostRecentLogEntry'
+ assertContent 'none'
+
+ // get the index action which should trigger caching
+
+ get '/test/index'
+ assertContent 'index'
+
+ get '/test/logEntryCount'
+ assertContent '1'
+
+ get '/test/mostRecentLogEntry'
+
+ def json = JSON.parse(response.contentAsString)
+
+ assertEquals 'Called index() action', json.message
+ long id = json.id
+ long dateCreated = json.dateCreated
+
+ // get the index action again, should be cached
+
+ get '/test/index'
+ assertContent 'index'
+
+ get '/test/logEntryCount'
+ assertContent '1'
+
+ get '/test/mostRecentLogEntry'
+ json = JSON.parse(response.contentAsString)
+
+ assertEquals 'Called index() action', json.message
+ assertEquals id, json.id
+ assertEquals dateCreated, json.dateCreated
+
+ // evict
+
+ get '/test/evict'
+ assertContent 'evict'
+
+ get '/test/logEntryCount'
+ assertContent '2'
+
+ get '/test/mostRecentLogEntry'
+ json = JSON.parse(response.contentAsString)
+
+ assertEquals 'Called evict() action', json.message
+ assertEquals id + 1, json.id
+ assertTrue dateCreated < json.dateCreated
+
+ // save the values to compare
+ id++
+ dateCreated = json.dateCreated
+
+ // get the index action again, should not be cached
+
+ get '/test/index'
+ assertContent 'index'
+
+ get '/test/logEntryCount'
+ assertContent '3'
+
+ get '/test/mostRecentLogEntry'
+ json = JSON.parse(response.contentAsString)
+
+ assertEquals 'Called index() action', json.message
+ assertEquals id + 1, json.id
+ assertTrue dateCreated < json.dateCreated
+ }
+}

0 comments on commit d7a2bb2

Please sign in to comment.