GAE推送队列任务不在测试中运行,产生孤立的dev_appserver进程

时间:2018-05-04 16:03:03

标签: google-app-engine go google-cloud-platform task-queue

我注意到我的任务工作者从未在测试中运行,并且测试中的排队/出队逻辑几乎完全解耦,这使我甚至无法验证任务是否已正确排队。

考虑以下最小例子:

的app.yaml:

runtime: go
api_version: go1

handlers:
 - url: /worker/.*
   script: _go_app
   login: admin
 - url: /.*
   script: _go_app

worker / settle.go(package worker

func SettleWorker(w http.ResponseWriter, r *http.Request) {
        ctx := appengine.NewContext(r)
        log.Infof(ctx, "Worker was successfully invoked")
}

service / main.go(package service

func TestHandler(w http.ResponseWriter, r *http.Request) {
        ctx := appengine.NewContext(r)
        t := taskqueue.NewPOSTTask("/worker/wrongpath", map[string][]string{"name": {"BLAH"}})
        task, err := taskqueue.Add(ctx, t, "")
        if err != nil {
                http.Error(w, "Error", http.StatusBadRequest)
                return
        }
        log.Infof(ctx, "Successfully posted task to worker: %+v", task)
}

func init() {
        http.HandleFunc("/worker/settle", worker.SettleWorker)
        http.HandleFunc("/test", TestHandler)
}

service / main_test.go(package service_test

func TestTestHandler(t *testing.T) {
        inst, err := aetest.NewInstance(nil)
        if err != nil {
                t.Fatal(err.Error())
        }
        req, err := inst.NewRequest("GET", "/", nil)
        if err != nil {
                t.Fatal(err.Error())
        }
        resp := httptest.NewRecorder()
        http.HandlerFunc(service.TestHandler).ServeHTTP(resp, req)
}

请注意,传递给taskqueue.Add("/worker/wrongpath")的路径实际上没有注册的处理程序。乍一看,当我使用goapp test bitwyrm/service -v测试时,这似乎没有引起任何问题,但工作人员实际上并没有运行。我看到了快乐的日志记录语句,并且从TestHandler返回了状态代码200,但是没有出现来自SettleWorker的日志记录语句。

如果路径正确(即设置为“/ worker / settle”),则会发生同样的事情。所以我无法编写测试来断言测试正在排队。

更糟糕的是,由于某些原因,运行此测试还会留下一个孤立的dev_appserver.py进程(无论使用哪个路径)。反复运行这个最终会使我的计算机充满孤立的测试进程,最终导致通过goapp test调用的dev服务器遇到数据库锁定问题,这意味着我无法在不手动杀死所有孤立测试的情况下运行我的测试套件流程。典型的堆栈跟踪:

...successful test output...
INFO     2018-05-04 09:02:10,762 stub_util.py:357] Applying all pending transactions and saving the datastore
INFO     2018-05-04 09:02:13,827 stub_util.py:360] Saving search indexes
Exception in thread Thread-1:
Traceback (most recent call last):
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/threading.py", line 810, in __bootstrap_inner
    self.run()
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/threading.py", line 763, in run
    self.__target(*self.__args, **self.__kwargs)
  File "/Users/ursa/Code/google-cloud-sdk/platform/google_appengine/google/appengine/api/taskqueue/taskqueue_stub.py", line 2182, in MainLoop
    self._ProcessQueues()
  File "/Users/ursa/Code/google-cloud-sdk/platform/google_appengine/google/appengine/api/taskqueue/taskqueue_stub.py", line 2127, in _ProcessQueues
    response_code = self.task_executor.ExecuteTask(task, queue)
  File "/Users/ursa/Code/google-cloud-sdk/platform/google_appengine/google/appengine/api/taskqueue/taskqueue_stub.py", line 2059, in ExecuteTask
    '0.1.0.2')
  File "/Users/ursa/Code/google-cloud-sdk/platform/google_appengine/google/appengine/tools/devappserver2/dispatcher.py", line 776, in add_request
    inst)
  File "/Users/ursa/Code/google-cloud-sdk/platform/google_appengine/google/appengine/tools/devappserver2/dispatcher.py", line 862, in _handle_request
    request_type=request_type)
  File "/Users/ursa/Code/google-cloud-sdk/platform/google_appengine/google/appengine/tools/devappserver2/module.py", line 818, in _handle_request
    module=self._module_configuration.module_name)
  File "/Users/ursa/Code/google-cloud-sdk/platform/google_appengine/google/appengine/api/apiproxy_stub.py", line 186, in WrappedMethod
    return method(self, *args, **kwargs)
  File "/Users/ursa/Code/google-cloud-sdk/platform/google_appengine/google/appengine/api/logservice/logservice_stub.py", line 181, in start_request
    host, start_time, method, resource, http_version, module))
OperationalError: database is locked

请注意,这一切似乎在测试之外工作正常 - 当我使用Paw和dev_appserver.py在dev中使用这个http处理程序时,正确的路径会触发worker,而错误的路径会看到403响应的记录重试(你期望的两种行为)。

我已经花了足够的时间尝试调试它,我假设它是dev_appserver.pyaetest中的实际错误,但我坚信确保它不是应用程序的错误在指责工具之前。我在这里做错了什么是显而易见的吗?

1 个答案:

答案 0 :(得分:0)

我本应该参与创建“幻影”流程 - 事实证明我只是忘记在我创建的Close()上打电话给aetest.Instance

实例化错误检查后的以下行为我解决了问题:

defer inst.Close()