blob: 9d07f615752c3cc54b05a599790c0b5d5da65ae5 [file] [log] [blame]
#
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You under the Apache License, Version 2.0
# (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
import logging
import socket
import apisix.runner.utils.common as runner_utils
from apisix.runner.server.handle import Handle as RunnerServerHandle
from apisix.runner.server.logger import Logger as RunnerServerLogger
from apisix.runner.server.server import RPCRequest as RunnerRPCRequest
from A6.HTTPReqCall import Req as A6HTTPReqCallReq
from A6.PrepareConf import Req as A6PrepareConfReq
from A6.PrepareConf import Resp as A6PrepareConfResp
from A6 import TextEntry as A6TextEntry
from A6 import Method as A6Method
from A6.Err.Resp import Resp as ErrResp
from A6.HTTPReqCall.Resp import Resp as HCResp
from A6.HTTPReqCall.Action import Action as HCAction
from A6.Err.Code import Code as ErrCode
from A6.HTTPReqCall.Stop import Stop as HCStop
from A6.HTTPReqCall.Rewrite import Rewrite as HCRewrite
def default_request():
sock = socket.socket()
logger = RunnerServerLogger(logging.INFO)
return RunnerRPCRequest(sock, logger)
def default_plugin_buffer(name: str = "stop", enable_conf: bool = True):
builder = runner_utils.new_builder()
conf = 0
if enable_conf:
name = builder.CreateString(name)
value = builder.CreateString('{"body":"Hello Python Runner"}')
A6TextEntry.Start(builder)
A6TextEntry.AddName(builder, name)
A6TextEntry.AddValue(builder, value)
conf_data = A6TextEntry.End(builder)
A6PrepareConfReq.ReqStartConfVector(builder, 1)
builder.PrependUOffsetTRelative(conf_data)
conf = builder.EndVector()
A6PrepareConfReq.Start(builder)
A6PrepareConfReq.AddConf(builder, conf)
req = A6PrepareConfReq.End(builder)
builder.Finish(req)
return builder.Output()
def default_call_buffer(token: int = 0, id: int = 1):
builder = runner_utils.new_builder()
# request path
path = builder.CreateString("/hello/python/runner")
# request ip
src_ip = bytes(bytearray([127, 0, 0, 1]))
src_ip = builder.CreateByteVector(src_ip)
# request args
arg_k = builder.CreateString("hello")
arg_v = builder.CreateString("world")
A6TextEntry.Start(builder)
A6TextEntry.AddName(builder, arg_k)
A6TextEntry.AddValue(builder, arg_v)
args = A6TextEntry.End(builder)
A6HTTPReqCallReq.StartArgsVector(builder, 1)
builder.PrependUOffsetTRelative(args)
args_vec = builder.EndVector()
# request headers
head_k = builder.CreateString("hello")
head_v = builder.CreateString("world")
A6TextEntry.Start(builder)
A6TextEntry.AddName(builder, head_k)
A6TextEntry.AddValue(builder, head_v)
headers = A6TextEntry.End(builder)
A6HTTPReqCallReq.StartHeadersVector(builder, 1)
builder.PrependUOffsetTRelative(headers)
headers_vec = builder.EndVector()
A6HTTPReqCallReq.Start(builder)
A6HTTPReqCallReq.AddId(builder, id)
A6HTTPReqCallReq.AddMethod(builder, A6Method.Method.GET)
A6HTTPReqCallReq.AddPath(builder, path)
A6HTTPReqCallReq.AddSrcIp(builder, src_ip)
A6HTTPReqCallReq.AddArgs(builder, args_vec)
A6HTTPReqCallReq.AddHeaders(builder, headers_vec)
A6HTTPReqCallReq.AddConfToken(builder, token)
req = A6HTTPReqCallReq.End(builder)
builder.Finish(req)
return builder.Output()
def test_dispatch_unknown():
r = default_request()
r.request.ty = runner_utils.RPC_UNKNOWN
handle = RunnerServerHandle(r)
response = handle.dispatch()
err = ErrResp.GetRootAsResp(response.Output())
assert err.Code() == ErrCode.BAD_REQUEST
def test_dispatch_config():
buf = default_plugin_buffer("stop", False)
r = default_request()
r.request.ty = runner_utils.RPC_PREPARE_CONF
r.request.data = buf
handle = RunnerServerHandle(r)
response = handle.dispatch()
err = ErrResp.GetRootAsResp(response.Output())
assert err.Code() == ErrCode.CONF_TOKEN_NOT_FOUND
buf = default_plugin_buffer("stop")
r.request.ty = runner_utils.RPC_PREPARE_CONF
r.request.data = buf
handle = RunnerServerHandle(r)
response = handle.dispatch()
resp = A6PrepareConfResp.Resp.GetRootAs(response.Output())
assert resp.ConfToken() != 0
def test_dispatch_call():
r = default_request()
r.request.ty = runner_utils.RPC_PREPARE_CONF
r.request.data = default_plugin_buffer("stop")
handle = RunnerServerHandle(r)
response = handle.dispatch()
resp = A6PrepareConfResp.Resp.GetRootAs(response.Output())
assert resp.ConfToken() != 0
buf = default_call_buffer(resp.ConfToken())
r.request.ty = runner_utils.RPC_HTTP_REQ_CALL
r.request.data = buf
handle = RunnerServerHandle(r)
response = handle.dispatch()
resp = HCResp.GetRootAsResp(response.Output())
assert resp.Id() > 0
assert resp.ActionType() == HCAction.Stop
stop = HCStop()
stop.Init(resp.Action().Bytes, resp.Action().Pos)
assert stop.BodyLength() == len("Hello, Python Runner of APISIX")
assert stop.Status() == 201
r.request.ty = runner_utils.RPC_PREPARE_CONF
r.request.data = default_plugin_buffer("rewrite")
handle = RunnerServerHandle(r)
response = handle.dispatch()
resp = A6PrepareConfResp.Resp.GetRootAs(response.Output())
assert resp.ConfToken() != 0
conf_token = resp.ConfToken()
r.request.ty = runner_utils.RPC_HTTP_REQ_CALL
r.request.data = default_call_buffer(conf_token)
handle = RunnerServerHandle(r)
response = handle.dispatch()
resp = HCResp.GetRootAsResp(response.Output())
assert resp.Id() > 0
assert resp.ActionType() == HCAction.Rewrite
rewrite = HCRewrite()
rewrite.Init(resp.Action().Bytes, resp.Action().Pos)
assert rewrite.Path() == b'/a6/python/runner'
r.request.ty = runner_utils.RPC_HTTP_REQ_CALL
r.request.data = default_call_buffer(conf_token, 0)
handle = RunnerServerHandle(r)
response = handle.dispatch()
resp = ErrResp.GetRootAs(response.Output())
assert resp.Code() == ErrCode.BAD_REQUEST
r.request.data = default_call_buffer()
handle = RunnerServerHandle(r)
response = handle.dispatch()
reps = ErrResp.GetRootAs(response.Output())
assert reps.Code() == ErrCode.CONF_TOKEN_NOT_FOUND