aetest - any way to get the currently running host and port?

227 views
Skip to first unread message

Mark Mandel

unread,
Jun 10, 2014, 1:38:21 AM6/10/14
to google-appengine-go
go version go1.2.1 (appengine-1.9.6) linux/amd64

I'm using aetest and I have some REST endpoints I would like to test out with real Http calls in my automated tests as full integration tests.

I cannot seem to find a way to get the current host and port of the currently running dev gae instance that aetest fires up.

I've tried every combination of appengine.ModuleHostname I can think of (current incarnation is below), and the best response I get back is:

2014/06/10 15:34:49 DEBUG: App ID: testapp
2014/06/10 15:34:49 DEBUG: Module Name: default
2014/06/10 15:34:49 DEBUG: Version: 1.2345
2014/06/10 15:34:49 DEBUG: DefaultVersionHostname:
2014/06/10 15:34:49 DEBUG: IsDevAppServer: true
2014/06/10 15:34:49 DEBUG: InstanceID: deadbeef
2014/06/10 15:34:49 ERROR: Could not get hosts: API error 1 (modules: INVALID_MODULE)

Which is not so useful.

Test code is as follows:

ctx.Debugf("App ID: %v", appengine.AppID(ctx))
module := appengine.ModuleName(ctx)
ctx.Debugf("Module Name: %v", module)
version := appengine.VersionID(ctx)
ctx.Debugf("Version: %v", version)
ctx.Debugf("DefaultVersionHostname: %v", appengine.DefaultVersionHostname(ctx))
ctx.Debugf("IsDevAppServer: %v", appengine.IsDevAppServer())
instance := appengine.InstanceID()
ctx.Debugf("InstanceID: %v", instance)

host, err := appengine.ModuleHostname(ctx, module, version, instance)

if(err != nil) {
ctx.Errorf("Could not get hosts: %v", err)
} else {
ctx.Debugf("Host: %v", host)
}

Any help would be appreciated!

Mark

--
E: mark....@gmail.com
T: http://www.twitter.com/neurotic
W: www.compoundtheory.com

2 Devs from Down Under Podcast

David Symonds

unread,
Jun 10, 2014, 2:12:08 AM6/10/14
to Mark Mandel, google-appengine-go
There isn't a way, but that's a very reasonable request. Please file a
request on the issue tracker.

Mark Mandel

unread,
Jun 10, 2014, 2:25:16 AM6/10/14
to David Symonds, google-appengine-go
Will do.

I was just trying to work around it by calling my http handler functions directly, using `http.NewRequest("GET", path, nil)` as my request.

This ends up causing a panic when I try and create a Context with it : appengine: NewContext passed an unknown http.Request in api_dev.go

func NewContext(req *http.Request) *context {
ctxsMu.Lock()
defer ctxsMu.Unlock()
c := ctxs[req]

if c == nil {
// Someone passed in an http.Request that is not in-flight.
// We panic here rather than panicking at a later point
// so that backtraces will be more sensible.
log.Panic("appengine: NewContext passed an unknown http.Request")
}
return c
}

Since the request didn't go through the app engine directly, and doesn't go through handleFilteredHTTP(), which means the result is nil.

Don't suppose there are any clever workarounds for that? so I can actually test my HTTP handlers? ;) Otherwise, I'm at a loss as to how I can do this.

Mark


On Tue, Jun 10, 2014 at 4:12 PM, David Symonds <dsym...@golang.org> wrote:
There isn't a way, but that's a very reasonable request. Please file a
request on the issue tracker.



Mark Mandel

unread,
Jun 10, 2014, 2:30:54 AM6/10/14
to David Symonds, google-appengine-go

Mark Mandel

unread,
Jun 10, 2014, 2:58:10 AM6/10/14
to David Symonds, google-appengine-go
I ended up working around this issue using http://www.gorillatoolkit.org/pkg/context to pass through the aetest'd context with the request, but it's not a great solution to the problem.

Mark

Matthew Zimmerman

unread,
Jun 10, 2014, 8:01:52 AM6/10/14
to Mark Mandel, David Symonds, google-appengine-go
The problem is though that your "app" isn't really your app. In other
words, your handlers and configuration in your .yaml file isn't used
to run your application when under aetest. If you simply export the
ModuleURL field in aetest, and you do just make a request to your app,
it's likely not going to be what you expected since the handlers are
wildly different.

Instead, I would recommend creating all of your http handlers to
accept an appengine.Context, *http.Request, and http.Response. That
way, you can pass them the aetest.Context and an
httptest.NewRecorder() and they're none the wiser.

http://stackoverflow.com/questions/19407343/how-can-i-unit-test-google-app-engine-go-http-handlers

-------------

type ContextHandler struct {
Real func(*appengine.Context, http.ResponseWriter, *http.Request)
}

func (f ContextHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
c := appengine.NewContext(r)
f.Real(c, w, r)
}

func myNewHandler(c appengine.Context, w http.ResponseWriter, r *http.Request) {
// do something
}

http.Handle("/myapi", ContextHandler(myNewHandler))

--------------

This works very conveniently when utilizing Matt Jibson's goon and appstats:
type ContextHandler func(*goon.Goon, http.ResponseWriter, *http.Request)

func (f ContextHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
c := appstats.NewContext(r)
f(goon.FromContext(c), w, r)
c.Save()
}

Then my http handlers can look like:
func logout(g *goon.Goon, w http.ResponseWriter, r *http.Request) {
// I no longer have to generate goon or appstats, I can just start
specific code to my handler
> --
> You received this message because you are subscribed to the Google Groups
> "google-appengine-go" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to google-appengin...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.

Mark Mandel

unread,
Jun 10, 2014, 8:20:49 AM6/10/14
to Matthew Zimmerman, David Symonds, google-appengine-go

I quite like that approach. However now I'm also thinking about using a higher order function that does something similar.

Thanks for the input.

Sent from my mobile doohickey

Mark Mandel

unread,
Jun 24, 2014, 7:07:01 PM6/24/14
to Matthew Zimmerman, David Symonds, google-appengine-go
I finally wrote up my solution to this problem in a blog post. I'm finding it working quite well for me:

As always, comments and feedback are welcome.
Reply all
Reply to author
Forward
0 new messages