mirror of
https://github.com/httprunner/httprunner.git
synced 2026-05-13 07:39:44 +08:00
refactor: plugin code structure
This commit is contained in:
@@ -9,7 +9,7 @@ import (
|
||||
|
||||
"github.com/httprunner/hrp/internal/boomer"
|
||||
"github.com/httprunner/hrp/internal/ga"
|
||||
pluginInternal "github.com/httprunner/hrp/plugin/inner"
|
||||
pluginInternal "github.com/httprunner/hrp/plugin/go"
|
||||
)
|
||||
|
||||
func NewBoomer(spawnCount int, spawnRate float64) *HRPBoomer {
|
||||
|
||||
@@ -33,4 +33,4 @@ Copyright 2021 debugtalk
|
||||
* [hrp run](hrp_run.md) - run API test
|
||||
* [hrp startproject](hrp_startproject.md) - create a scaffold project
|
||||
|
||||
###### Auto generated by spf13/cobra on 4-Mar-2022
|
||||
###### Auto generated by spf13/cobra on 5-Mar-2022
|
||||
|
||||
@@ -39,4 +39,4 @@ hrp boom [flags]
|
||||
|
||||
* [hrp](hrp.md) - One-stop solution for HTTP(S) testing.
|
||||
|
||||
###### Auto generated by spf13/cobra on 4-Mar-2022
|
||||
###### Auto generated by spf13/cobra on 5-Mar-2022
|
||||
|
||||
@@ -23,4 +23,4 @@ hrp har2case $har_path... [flags]
|
||||
|
||||
* [hrp](hrp.md) - One-stop solution for HTTP(S) testing.
|
||||
|
||||
###### Auto generated by spf13/cobra on 4-Mar-2022
|
||||
###### Auto generated by spf13/cobra on 5-Mar-2022
|
||||
|
||||
@@ -34,4 +34,4 @@ hrp run $path... [flags]
|
||||
|
||||
* [hrp](hrp.md) - One-stop solution for HTTP(S) testing.
|
||||
|
||||
###### Auto generated by spf13/cobra on 4-Mar-2022
|
||||
###### Auto generated by spf13/cobra on 5-Mar-2022
|
||||
|
||||
@@ -16,4 +16,4 @@ hrp startproject $project_name [flags]
|
||||
|
||||
* [hrp](hrp.md) - One-stop solution for HTTP(S) testing.
|
||||
|
||||
###### Auto generated by spf13/cobra on 4-Mar-2022
|
||||
###### Auto generated by spf13/cobra on 5-Mar-2022
|
||||
|
||||
@@ -13,7 +13,8 @@ import (
|
||||
"github.com/rs/zerolog/log"
|
||||
|
||||
"github.com/httprunner/hrp/internal/builtin"
|
||||
pluginInternal "github.com/httprunner/hrp/plugin/inner"
|
||||
pluginInternal "github.com/httprunner/hrp/plugin/go"
|
||||
pluginUtils "github.com/httprunner/hrp/plugin/utils"
|
||||
)
|
||||
|
||||
func newParser() *parser {
|
||||
@@ -252,7 +253,7 @@ func (p *parser) callFunc(funcName string, arguments ...interface{}) (interface{
|
||||
fn := reflect.ValueOf(function)
|
||||
|
||||
// call with builtin function
|
||||
return pluginInternal.CallFunc(fn, arguments...)
|
||||
return pluginUtils.CallFunc(fn, arguments...)
|
||||
}
|
||||
|
||||
// merge two variables mapping, the first variables have higher priority
|
||||
|
||||
@@ -7,6 +7,8 @@ import (
|
||||
"runtime"
|
||||
|
||||
"github.com/rs/zerolog/log"
|
||||
|
||||
pluginUtils "github.com/httprunner/hrp/plugin/utils"
|
||||
)
|
||||
|
||||
// GoPlugin implements golang official plugin
|
||||
@@ -61,7 +63,7 @@ func (p *GoPlugin) Call(funcName string, args ...interface{}) (interface{}, erro
|
||||
return nil, fmt.Errorf("function %s not found", funcName)
|
||||
}
|
||||
fn := p.cachedFunctions[funcName]
|
||||
return CallFunc(fn, args...)
|
||||
return pluginUtils.CallFunc(fn, args...)
|
||||
}
|
||||
|
||||
func (p *GoPlugin) Quit() error {
|
||||
@@ -9,7 +9,7 @@ import (
|
||||
"google.golang.org/grpc"
|
||||
|
||||
"github.com/httprunner/hrp/internal/json"
|
||||
"github.com/httprunner/hrp/plugin/proto"
|
||||
"github.com/httprunner/hrp/plugin/go/proto"
|
||||
)
|
||||
|
||||
// functionGRPCClient runs on the host side, it implements FuncCaller interface
|
||||
@@ -1,6 +1,6 @@
|
||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-go v1.26.0
|
||||
// protoc-gen-go v1.27.1
|
||||
// protoc v3.19.4
|
||||
// source: plugin/proto/debugtalk.proto
|
||||
|
||||
@@ -228,10 +228,9 @@ var file_plugin_proto_debugtalk_proto_rawDesc = []byte{
|
||||
0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2f, 0x0a, 0x04, 0x43, 0x61, 0x6c, 0x6c, 0x12, 0x12, 0x2e,
|
||||
0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x43, 0x61, 0x6c, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
|
||||
0x74, 0x1a, 0x13, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x43, 0x61, 0x6c, 0x6c, 0x52, 0x65,
|
||||
0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x28, 0x5a, 0x26, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62,
|
||||
0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x68, 0x74, 0x74, 0x70, 0x72, 0x75, 0x6e, 0x6e, 0x65, 0x72, 0x2f,
|
||||
0x68, 0x72, 0x70, 0x2f, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f,
|
||||
0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||
0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x11, 0x5a, 0x0f, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e,
|
||||
0x2f, 0x67, 0x6f, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f,
|
||||
0x33,
|
||||
}
|
||||
|
||||
var (
|
||||
@@ -1,4 +1,8 @@
|
||||
// Code generated by protoc-gen-go-grpc. DO NOT EDIT.
|
||||
// versions:
|
||||
// - protoc-gen-go-grpc v1.2.0
|
||||
// - protoc v3.19.4
|
||||
// source: plugin/proto/debugtalk.proto
|
||||
|
||||
package proto
|
||||
|
||||
@@ -9,7 +9,8 @@ import (
|
||||
"github.com/hashicorp/go-plugin"
|
||||
"github.com/rs/zerolog/log"
|
||||
|
||||
pluginInternal "github.com/httprunner/hrp/plugin/inner"
|
||||
pluginInternal "github.com/httprunner/hrp/plugin/go"
|
||||
pluginUtils "github.com/httprunner/hrp/plugin/utils"
|
||||
)
|
||||
|
||||
// functionsMap stores plugin functions
|
||||
@@ -37,7 +38,7 @@ func (p *functionPlugin) Call(funcName string, args ...interface{}) (interface{}
|
||||
return nil, fmt.Errorf("function %s not found", funcName)
|
||||
}
|
||||
|
||||
return pluginInternal.CallFunc(fn, args...)
|
||||
return pluginUtils.CallFunc(fn, args...)
|
||||
}
|
||||
|
||||
var functions = make(functionsMap)
|
||||
|
||||
@@ -1,10 +1,62 @@
|
||||
|
||||
## Updating the Protocol
|
||||
# Updating the Protocol
|
||||
|
||||
If you update the protocol buffers file, you can regenerate the file using the following command from the project root directory. You do not need to run this if you're just using the plugin.
|
||||
|
||||
For Go:
|
||||
## For Go
|
||||
|
||||
### Install dependencies
|
||||
|
||||
ref: https://www.grpc.io/docs/languages/go/quickstart/
|
||||
|
||||
Install the protocol compiler plugins for Go using the following commands:
|
||||
|
||||
```bash
|
||||
$ protoc --go_out=. --go_opt=paths=source_relative --go-grpc_out=. --go-grpc_opt=paths=source_relative plugin/proto/debugtalk.proto
|
||||
$ go install google.golang.org/protobuf/cmd/protoc-gen-go@latest
|
||||
$ go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@latest
|
||||
```
|
||||
|
||||
Update your PATH so that the protoc compiler can find the plugins:
|
||||
|
||||
```bash
|
||||
$ export PATH="$PATH:$(go env GOPATH)/bin"
|
||||
```
|
||||
|
||||
### Generate gRPC code
|
||||
|
||||
```bash
|
||||
$ protoc --go_out=. --go-grpc_out=. plugin/proto/debugtalk.proto
|
||||
```
|
||||
|
||||
This will generate two go files in `plugin/go/proto` folder:
|
||||
|
||||
- debugtalk.pb.go
|
||||
- debugtalk_grpc.pb.go
|
||||
|
||||
## For Python
|
||||
|
||||
### Install dependencies
|
||||
|
||||
ref: https://www.grpc.io/docs/languages/python/quickstart/
|
||||
|
||||
Install gRPC:
|
||||
|
||||
```bash
|
||||
$ pip3 install grpcio
|
||||
```
|
||||
|
||||
Install gRPC tools:
|
||||
|
||||
```bash
|
||||
$ pip3 install grpcio-tools
|
||||
```
|
||||
|
||||
### Generate gRPC code
|
||||
|
||||
```bash
|
||||
$ python3 -m grpc_tools.protoc -I plugin/proto --python_out=plugin/python/ --grpc_python_out=plugin/python/ plugin/proto/debugtalk.proto
|
||||
```
|
||||
|
||||
This will generate two python files in `plugin/python` folder:
|
||||
|
||||
- debugtalk_pb2.py
|
||||
- debugtalk_pb2_grpc.py
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
syntax = "proto3";
|
||||
package proto;
|
||||
|
||||
option go_package = "github.com/httprunner/hrp/plugin/proto";
|
||||
option go_package = "plugin/go/proto";
|
||||
|
||||
message Empty {}
|
||||
|
||||
|
||||
68
plugin/python/debugtalk_pb2.py
Normal file
68
plugin/python/debugtalk_pb2.py
Normal file
@@ -0,0 +1,68 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Generated by the protocol buffer compiler. DO NOT EDIT!
|
||||
# source: debugtalk.proto
|
||||
"""Generated protocol buffer code."""
|
||||
from google.protobuf import descriptor as _descriptor
|
||||
from google.protobuf import descriptor_pool as _descriptor_pool
|
||||
from google.protobuf import message as _message
|
||||
from google.protobuf import reflection as _reflection
|
||||
from google.protobuf import symbol_database as _symbol_database
|
||||
# @@protoc_insertion_point(imports)
|
||||
|
||||
_sym_db = _symbol_database.Default()
|
||||
|
||||
|
||||
|
||||
|
||||
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x0f\x64\x65\x62ugtalk.proto\x12\x05proto\"\x07\n\x05\x45mpty\"!\n\x10GetNamesResponse\x12\r\n\x05names\x18\x01 \x03(\t\")\n\x0b\x43\x61llRequest\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0c\n\x04\x61rgs\x18\x02 \x01(\x0c\"\x1d\n\x0c\x43\x61llResponse\x12\r\n\x05value\x18\x01 \x01(\x0c\x32o\n\tDebugTalk\x12\x31\n\x08GetNames\x12\x0c.proto.Empty\x1a\x17.proto.GetNamesResponse\x12/\n\x04\x43\x61ll\x12\x12.proto.CallRequest\x1a\x13.proto.CallResponseB\x11Z\x0fplugin/go/protob\x06proto3')
|
||||
|
||||
|
||||
|
||||
_EMPTY = DESCRIPTOR.message_types_by_name['Empty']
|
||||
_GETNAMESRESPONSE = DESCRIPTOR.message_types_by_name['GetNamesResponse']
|
||||
_CALLREQUEST = DESCRIPTOR.message_types_by_name['CallRequest']
|
||||
_CALLRESPONSE = DESCRIPTOR.message_types_by_name['CallResponse']
|
||||
Empty = _reflection.GeneratedProtocolMessageType('Empty', (_message.Message,), {
|
||||
'DESCRIPTOR' : _EMPTY,
|
||||
'__module__' : 'debugtalk_pb2'
|
||||
# @@protoc_insertion_point(class_scope:proto.Empty)
|
||||
})
|
||||
_sym_db.RegisterMessage(Empty)
|
||||
|
||||
GetNamesResponse = _reflection.GeneratedProtocolMessageType('GetNamesResponse', (_message.Message,), {
|
||||
'DESCRIPTOR' : _GETNAMESRESPONSE,
|
||||
'__module__' : 'debugtalk_pb2'
|
||||
# @@protoc_insertion_point(class_scope:proto.GetNamesResponse)
|
||||
})
|
||||
_sym_db.RegisterMessage(GetNamesResponse)
|
||||
|
||||
CallRequest = _reflection.GeneratedProtocolMessageType('CallRequest', (_message.Message,), {
|
||||
'DESCRIPTOR' : _CALLREQUEST,
|
||||
'__module__' : 'debugtalk_pb2'
|
||||
# @@protoc_insertion_point(class_scope:proto.CallRequest)
|
||||
})
|
||||
_sym_db.RegisterMessage(CallRequest)
|
||||
|
||||
CallResponse = _reflection.GeneratedProtocolMessageType('CallResponse', (_message.Message,), {
|
||||
'DESCRIPTOR' : _CALLRESPONSE,
|
||||
'__module__' : 'debugtalk_pb2'
|
||||
# @@protoc_insertion_point(class_scope:proto.CallResponse)
|
||||
})
|
||||
_sym_db.RegisterMessage(CallResponse)
|
||||
|
||||
_DEBUGTALK = DESCRIPTOR.services_by_name['DebugTalk']
|
||||
if _descriptor._USE_C_DESCRIPTORS == False:
|
||||
|
||||
DESCRIPTOR._options = None
|
||||
DESCRIPTOR._serialized_options = b'Z\017plugin/go/proto'
|
||||
_EMPTY._serialized_start=26
|
||||
_EMPTY._serialized_end=33
|
||||
_GETNAMESRESPONSE._serialized_start=35
|
||||
_GETNAMESRESPONSE._serialized_end=68
|
||||
_CALLREQUEST._serialized_start=70
|
||||
_CALLREQUEST._serialized_end=111
|
||||
_CALLRESPONSE._serialized_start=113
|
||||
_CALLRESPONSE._serialized_end=142
|
||||
_DEBUGTALK._serialized_start=144
|
||||
_DEBUGTALK._serialized_end=255
|
||||
# @@protoc_insertion_point(module_scope)
|
||||
99
plugin/python/debugtalk_pb2_grpc.py
Normal file
99
plugin/python/debugtalk_pb2_grpc.py
Normal file
@@ -0,0 +1,99 @@
|
||||
# Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT!
|
||||
"""Client and server classes corresponding to protobuf-defined services."""
|
||||
import grpc
|
||||
|
||||
import debugtalk_pb2 as debugtalk__pb2
|
||||
|
||||
|
||||
class DebugTalkStub(object):
|
||||
"""Missing associated documentation comment in .proto file."""
|
||||
|
||||
def __init__(self, channel):
|
||||
"""Constructor.
|
||||
|
||||
Args:
|
||||
channel: A grpc.Channel.
|
||||
"""
|
||||
self.GetNames = channel.unary_unary(
|
||||
'/proto.DebugTalk/GetNames',
|
||||
request_serializer=debugtalk__pb2.Empty.SerializeToString,
|
||||
response_deserializer=debugtalk__pb2.GetNamesResponse.FromString,
|
||||
)
|
||||
self.Call = channel.unary_unary(
|
||||
'/proto.DebugTalk/Call',
|
||||
request_serializer=debugtalk__pb2.CallRequest.SerializeToString,
|
||||
response_deserializer=debugtalk__pb2.CallResponse.FromString,
|
||||
)
|
||||
|
||||
|
||||
class DebugTalkServicer(object):
|
||||
"""Missing associated documentation comment in .proto file."""
|
||||
|
||||
def GetNames(self, request, context):
|
||||
"""Missing associated documentation comment in .proto file."""
|
||||
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
|
||||
context.set_details('Method not implemented!')
|
||||
raise NotImplementedError('Method not implemented!')
|
||||
|
||||
def Call(self, request, context):
|
||||
"""Missing associated documentation comment in .proto file."""
|
||||
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
|
||||
context.set_details('Method not implemented!')
|
||||
raise NotImplementedError('Method not implemented!')
|
||||
|
||||
|
||||
def add_DebugTalkServicer_to_server(servicer, server):
|
||||
rpc_method_handlers = {
|
||||
'GetNames': grpc.unary_unary_rpc_method_handler(
|
||||
servicer.GetNames,
|
||||
request_deserializer=debugtalk__pb2.Empty.FromString,
|
||||
response_serializer=debugtalk__pb2.GetNamesResponse.SerializeToString,
|
||||
),
|
||||
'Call': grpc.unary_unary_rpc_method_handler(
|
||||
servicer.Call,
|
||||
request_deserializer=debugtalk__pb2.CallRequest.FromString,
|
||||
response_serializer=debugtalk__pb2.CallResponse.SerializeToString,
|
||||
),
|
||||
}
|
||||
generic_handler = grpc.method_handlers_generic_handler(
|
||||
'proto.DebugTalk', rpc_method_handlers)
|
||||
server.add_generic_rpc_handlers((generic_handler,))
|
||||
|
||||
|
||||
# This class is part of an EXPERIMENTAL API.
|
||||
class DebugTalk(object):
|
||||
"""Missing associated documentation comment in .proto file."""
|
||||
|
||||
@staticmethod
|
||||
def GetNames(request,
|
||||
target,
|
||||
options=(),
|
||||
channel_credentials=None,
|
||||
call_credentials=None,
|
||||
insecure=False,
|
||||
compression=None,
|
||||
wait_for_ready=None,
|
||||
timeout=None,
|
||||
metadata=None):
|
||||
return grpc.experimental.unary_unary(request, target, '/proto.DebugTalk/GetNames',
|
||||
debugtalk__pb2.Empty.SerializeToString,
|
||||
debugtalk__pb2.GetNamesResponse.FromString,
|
||||
options, channel_credentials,
|
||||
insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
|
||||
|
||||
@staticmethod
|
||||
def Call(request,
|
||||
target,
|
||||
options=(),
|
||||
channel_credentials=None,
|
||||
call_credentials=None,
|
||||
insecure=False,
|
||||
compression=None,
|
||||
wait_for_ready=None,
|
||||
timeout=None,
|
||||
metadata=None):
|
||||
return grpc.experimental.unary_unary(request, target, '/proto.DebugTalk/Call',
|
||||
debugtalk__pb2.CallRequest.SerializeToString,
|
||||
debugtalk__pb2.CallResponse.FromString,
|
||||
options, channel_credentials,
|
||||
insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
|
||||
46
plugin/python/plugin.py
Normal file
46
plugin/python/plugin.py
Normal file
@@ -0,0 +1,46 @@
|
||||
from concurrent import futures
|
||||
import sys
|
||||
import time
|
||||
|
||||
import grpc
|
||||
|
||||
import debugtalk_pb2
|
||||
import debugtalk_pb2_grpc
|
||||
|
||||
from grpc_health.v1.health import HealthServicer
|
||||
from grpc_health.v1 import health_pb2, health_pb2_grpc
|
||||
|
||||
class DebugTalkServicer(debugtalk_pb2_grpc.DebugTalkServicer):
|
||||
"""Implementation of DebugTalk service."""
|
||||
|
||||
def GetNames(self, request, context):
|
||||
result = debugtalk_pb2.GetNamesResponse()
|
||||
return result
|
||||
|
||||
def Call(self, request, context):
|
||||
return
|
||||
|
||||
def serve():
|
||||
# We need to build a health service to work with go-plugin
|
||||
health = HealthServicer()
|
||||
health.set("plugin", health_pb2.HealthCheckResponse.ServingStatus.Value('SERVING'))
|
||||
|
||||
# Start the server.
|
||||
server = grpc.server(futures.ThreadPoolExecutor(max_workers=10))
|
||||
debugtalk_pb2_grpc.add_DebugTalkServicer_to_server(DebugTalkServicer(), server)
|
||||
health_pb2_grpc.add_HealthServicer_to_server(health, server)
|
||||
server.add_insecure_port('127.0.0.1:1234')
|
||||
server.start()
|
||||
|
||||
# Output information
|
||||
print("1|1|tcp|127.0.0.1:1234|grpc")
|
||||
sys.stdout.flush()
|
||||
|
||||
try:
|
||||
while True:
|
||||
time.sleep(60 * 60 * 24)
|
||||
except KeyboardInterrupt:
|
||||
server.stop(0)
|
||||
|
||||
if __name__ == '__main__':
|
||||
serve()
|
||||
@@ -1,4 +1,4 @@
|
||||
package pluginInternal
|
||||
package pluginUtils
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
@@ -1,4 +1,4 @@
|
||||
package pluginInternal
|
||||
package pluginUtils
|
||||
|
||||
import (
|
||||
"errors"
|
||||
Reference in New Issue
Block a user