Задачи очереди отправки GAE не запускаются в тестах, порождают потерянные процессы dev_appserver - PullRequest
0 голосов
/ 04 мая 2018

Я заметил, что мои рабочие задачи никогда не запускаются в тестах, и в тестировании почти полностью отсутствует связь логики постановки / снятия с очереди, которая не позволяет мне даже проверить, что задача была поставлена ​​в правильную очередь.

Рассмотрим следующий минимальный пример:

app.yaml:

runtime: go
api_version: go1

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

работник / поселение.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, но рабочий фактически не работает. Я вижу, что счастливый оператор регистрации и код состояния 200 возвращается из TestHandler, но оператор регистрации из SettleWorker не отображается.

То же самое происходит, если путь правильный (т. Е. Установлен на "/ worker / урегулировать"). Поэтому я не могу написать тесты, чтобы утверждать, что тест ставится в правильном порядке.

Чтобы сделать это еще хуже, по какой-то причине выполнение этого теста также оставляет потерянный процесс dev_appserver.py (независимо от того, какой путь используется). Повторное выполнение этого в конечном итоге приводит к заполнению моего компьютера потерянными тестовыми процессами, что в конечном итоге приводит к проблемам с блокировкой базы данных, вызванным с помощью goapp test на сервере разработки, что означает, что я не могу запустить свой набор тестов, не убив вручную все потерянные тестовые процессы. Типичная трассировка стека:

...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

Обратите внимание, что все это работает нормально вне тестирования - когда я нажимаю на этот http-обработчик в dev, используя Paw и dev_appserver.py, правильный путь действительно запускает работника, а неправильный путь приводит к регистрации 403 ответов с серией попыток (оба поведения, которые вы ожидаете).

Я потратил достаточно времени, пытаясь отладить это, и я предполагаю, что это настоящая ошибка в dev_appserver.py или aetest, но я твердо верю, чтобы убедиться, что это не ошибка приложения, прежде чем обвинять инструменты , Я делаю что-то не так здесь, это очевидно?

1 Ответ

0 голосов
/ 05 мая 2018

Я должен был быть осведомлен о создании "фантомных" процессов - оказывается, я просто забыл вызвать Close() на aetest.Instance, который я создал.

Следующая строка после проверки ошибок при установке исправила вещи для меня:

defer inst.Close()
...