Module: AppEngine::Testing

Defined in:
lib/appengine-apis/testing.rb

Overview

Local testing support for Google App Engine

If you run your code on Google’s servers or under dev_appserver, the api’s are already configured.

To run outside this environment, you need to install a test environment and api stubs.

Defined Under Namespace

Classes: TestEnv

Class Method Summary collapse

Class Method Details

.app_dirObject

The application directory, or ‘.’ if not set. Composite index definitions are written to “#app_dir/WEB-INF/”.



121
122
123
124
# File 'lib/appengine-apis/testing.rb', line 121

def app_dir
  file = factory.getApplicationDirectory
  file && file.path
end

.app_dir=(dir) ⇒ Object

Sets the application directory. Should be called before creating stubs.

Composite index definitions are written to “#app_dir/WEB-INF/”.



130
131
132
# File 'lib/appengine-apis/testing.rb', line 130

def app_dir=(dir)
  factory.setApplicationDirectory(java.io.File.new(dir))
end

.boot(app_dir = nil) ⇒ Object

Loads stub API implementations if no API implementation is currently configured.

Sets up a datastore saved to disk in app_dir. app_dir defaults to ENV or ‘.’ if not specified.

Does nothing is APIs are already configured (e.g. in production).

As a shortcut you can use

require 'appengine-apis/local_boot'


184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
# File 'lib/appengine-apis/testing.rb', line 184

def boot(app_dir=nil)
  if AppEngine::ApiProxy.current_environment &&
      AppEngine::ApiProxy.getDelegate
    return
  end
  app_dir ||= ENV['APPLICATION_ROOT'] || '.'
  unless AppEngine::ApiProxy.current_environment
    env = install_test_env
    appid = get_app_id(app_dir)
    env.appid = appid if appid
  end
  unless AppEngine::ApiProxy.getDelegate
    self.app_dir = app_dir
    install_api_stubs
  end
end

.factoryObject

:nodoc:



110
111
112
113
114
115
116
117
# File 'lib/appengine-apis/testing.rb', line 110

def factory  # :nodoc:
  @factory ||= begin
    Java.ComGoogleAppengineToolsDevelopment.ApiProxyLocalFactory.new
  rescue
    require 'appengine-sdk'
    AppEngine::SDK.load_local_apiproxy_factory.new
  end
end

.get_app_id(app_dir) ⇒ Object

Looks for app.yaml or WEB-INF/appengine-web.xml in app_dir and parses the application id.



203
204
205
206
207
208
209
210
211
212
213
# File 'lib/appengine-apis/testing.rb', line 203

def get_app_id(app_dir)
  require 'appengine-rack'
  app_id = AppEngine::Rack.app.id
  return app_id if app_id
  aeweb_path = File.join(app_dir, 'WEB-INF', 'appengine-web.xml')
  if File.exist?(aeweb_path)
    require 'rexml/document'
    aeweb = REXML::Document.new(File.new(aeweb_path))
    return aeweb.root.elements['application'].text
  end
end

.install_api_stubsObject

Install stub apis. The datastore will be written to the disk inside #app_dir.

You could potentially use this to run under a ruby web server instead of dev_appserver. In that case you will need to install and configure a test environment for each request.



160
161
162
163
164
165
166
167
168
169
170
171
# File 'lib/appengine-apis/testing.rb', line 160

def install_api_stubs
  current_delegate = ApiProxy.getDelegate
  current_delegate.stop if current_delegate.respond_to? :stop

  self.app_dir = '.' if app_dir.nil?
  delegate = factory.create
  ApiProxy::setDelegate(delegate)
  at_exit do
    delegate.stop
  end
  delegate
end

.install_test_datastoreObject

Install stub apis and force all datastore operations to use an in-memory datastore.

You may call this multiple times to reset to a new in-memory datastore.



138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
# File 'lib/appengine-apis/testing.rb', line 138

def install_test_datastore
  delegate = install_api_stubs
  lds = Java.ComGoogleAppengineApiDatastoreDev.LocalDatastoreService
  
  delegate.set_property(
      lds::NO_STORAGE_PROPERTY, "true")
  delegate.set_property(
      lds::MAX_QUERY_LIFETIME_PROPERTY,
      java.lang.Integer::MAX_VALUE.to_s)
  delegate.set_property(
      lds::MAX_TRANSACTION_LIFETIME_PROPERTY,
      java.lang.Integer::MAX_VALUE.to_s)
  ApiProxy::setDelegate(delegate)
  delegate
end

.install_test_envObject

Install a test environment for the current thread.

You must call this before making any api calls.

Note that Google’s production and local environments are single threaded. You may run into problems if you use multiple threads.



104
105
106
107
108
# File 'lib/appengine-apis/testing.rb', line 104

def install_test_env
  env = TestEnv.new
  ApiProxy::setEnvironmentForCurrentThread(env)
  env
end