mirror of
https://github.com/elicpeter/nyx.git
synced 2026-07-06 20:42:10 +02:00
refactor(dynamic): extend framework-specific fallbacks with Spring HandlerExecutionChain, Go gqlgen, Django handler/middleware chain, Celery task registry, and Sidekiq client handling; enhance coverage and test logic
This commit is contained in:
parent
fd39304eed
commit
71fade1d83
5 changed files with 356 additions and 24 deletions
|
|
@ -140,6 +140,18 @@ fn go_string_literal(s: &str) -> String {
|
||||||
format!("\"{escaped}\"")
|
format!("\"{escaped}\"")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn go_identifier_expr(name: &str) -> Option<String> {
|
||||||
|
let mut chars = name.chars();
|
||||||
|
let first = chars.next()?;
|
||||||
|
if !(first == '_' || first.is_ascii_alphabetic()) {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
if !chars.all(|c| c == '_' || c.is_ascii_alphanumeric()) {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
Some(format!("entry.{name}"))
|
||||||
|
}
|
||||||
|
|
||||||
/// Sorted, deduped tab-prefixed import lines covering the driver's
|
/// Sorted, deduped tab-prefixed import lines covering the driver's
|
||||||
/// `fmt` + `os` plus everything in [`SHIM_IMPORTS`].
|
/// `fmt` + `os` plus everything in [`SHIM_IMPORTS`].
|
||||||
fn chain_step_imports() -> String {
|
fn chain_step_imports() -> String {
|
||||||
|
|
@ -2613,6 +2625,96 @@ fn emit_graphql_resolver_harness(
|
||||||
) -> HarnessSource {
|
) -> HarnessSource {
|
||||||
let shim = probe_shim();
|
let shim = probe_shim();
|
||||||
let go_mod = generate_go_mod_for_spec(GoShape::Generic, spec);
|
let go_mod = generate_go_mod_for_spec(GoShape::Generic, spec);
|
||||||
|
let handler_expr = go_identifier_expr(handler).unwrap_or_else(|| "nil".to_owned());
|
||||||
|
let use_gqlgen_runtime = spec
|
||||||
|
.framework
|
||||||
|
.as_ref()
|
||||||
|
.map(|binding| binding.adapter == "graphql-gqlgen")
|
||||||
|
.unwrap_or(false);
|
||||||
|
let runtime_imports = if use_gqlgen_runtime {
|
||||||
|
r#" "bytes"
|
||||||
|
"encoding/json"
|
||||||
|
"net/http/httptest"
|
||||||
|
|
||||||
|
"github.com/99designs/gqlgen/graphql"
|
||||||
|
gqlhandler "github.com/99designs/gqlgen/graphql/handler"
|
||||||
|
"github.com/vektah/gqlparser/v2"
|
||||||
|
"github.com/vektah/gqlparser/v2/ast"
|
||||||
|
"github.com/vektah/gqlparser/v2/gqlerror"
|
||||||
|
"#
|
||||||
|
} else {
|
||||||
|
""
|
||||||
|
};
|
||||||
|
let runtime_call = if use_gqlgen_runtime {
|
||||||
|
"\tif nyxTryGqlgenHandler(cb, payload) {\n\t\treturn\n\t}\n"
|
||||||
|
} else {
|
||||||
|
""
|
||||||
|
};
|
||||||
|
let runtime_helpers = if use_gqlgen_runtime {
|
||||||
|
format!(
|
||||||
|
r##"
|
||||||
|
type nyxExecutableSchema struct {{
|
||||||
|
schema *ast.Schema
|
||||||
|
resolver reflect.Value
|
||||||
|
payload string
|
||||||
|
field string
|
||||||
|
}}
|
||||||
|
|
||||||
|
func (s *nyxExecutableSchema) Schema() *ast.Schema {{
|
||||||
|
return s.schema
|
||||||
|
}}
|
||||||
|
|
||||||
|
func (s *nyxExecutableSchema) Complexity(typeName, fieldName string, childComplexity int, args map[string]interface{{}}) (int, bool) {{
|
||||||
|
return 1, true
|
||||||
|
}}
|
||||||
|
|
||||||
|
func (s *nyxExecutableSchema) Exec(ctx context.Context) graphql.ResponseHandler {{
|
||||||
|
return func(ctx context.Context) *graphql.Response {{
|
||||||
|
value, err := nyxInvokeResolverValue(s.resolver, s.payload)
|
||||||
|
if err != nil {{
|
||||||
|
return &graphql.Response{{Errors: gqlerror.List{{gqlerror.Errorf(err.Error())}}}}
|
||||||
|
}}
|
||||||
|
data, err := json.Marshal(map[string]interface{{}}{{s.field: fmt.Sprint(value)}})
|
||||||
|
if err != nil {{
|
||||||
|
return &graphql.Response{{Errors: gqlerror.List{{gqlerror.Errorf(err.Error())}}}}
|
||||||
|
}}
|
||||||
|
return &graphql.Response{{Data: json.RawMessage(data)}}
|
||||||
|
}}
|
||||||
|
}}
|
||||||
|
|
||||||
|
func nyxTryGqlgenHandler(cb reflect.Value, payload string) bool {{
|
||||||
|
schema, err := gqlparser.LoadSchema(&ast.Source{{
|
||||||
|
Name: "nyx.graphql",
|
||||||
|
Input: "schema {{ query: Query }}\ntype Query {{ {field}(id: String, input: String): String }}",
|
||||||
|
}})
|
||||||
|
if err != nil {{
|
||||||
|
fmt.Fprintf(os.Stderr, "NYX_GQLGEN_SCHEMA_FALLBACK: %v\n", err)
|
||||||
|
return false
|
||||||
|
}}
|
||||||
|
server := gqlhandler.NewDefaultServer(&nyxExecutableSchema{{
|
||||||
|
schema: schema, resolver: cb, payload: payload, field: "{field}",
|
||||||
|
}})
|
||||||
|
body, _ := json.Marshal(map[string]interface{{}}{{
|
||||||
|
"query": "query($value: String) {{ {field}(id: $value, input: $value) }}",
|
||||||
|
"variables": map[string]interface{{}}{{"value": payload}},
|
||||||
|
}})
|
||||||
|
req := httptest.NewRequest("POST", "/query", bytes.NewReader(body))
|
||||||
|
req.Header.Set("Content-Type", "application/json")
|
||||||
|
rec := httptest.NewRecorder()
|
||||||
|
server.ServeHTTP(rec, req)
|
||||||
|
if rec.Code < 200 || rec.Code >= 300 {{
|
||||||
|
fmt.Fprintf(os.Stderr, "NYX_GQLGEN_HANDLER_FALLBACK: status=%d body=%s\n", rec.Code, rec.Body.String())
|
||||||
|
return false
|
||||||
|
}}
|
||||||
|
fmt.Print(rec.Body.String())
|
||||||
|
return true
|
||||||
|
}}
|
||||||
|
"##,
|
||||||
|
field = field
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
String::new()
|
||||||
|
};
|
||||||
let source = format!(
|
let source = format!(
|
||||||
r##"// Nyx dynamic harness — GraphQL resolver (Phase 21 / Track M.3).
|
r##"// Nyx dynamic harness — GraphQL resolver (Phase 21 / Track M.3).
|
||||||
package main
|
package main
|
||||||
|
|
@ -2622,6 +2724,7 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
"reflect"
|
"reflect"
|
||||||
|
{runtime_imports}
|
||||||
|
|
||||||
"nyx-harness/entry"
|
"nyx-harness/entry"
|
||||||
)
|
)
|
||||||
|
|
@ -2640,37 +2743,67 @@ func main() {{
|
||||||
payload := nyxPayload()
|
payload := nyxPayload()
|
||||||
fmt.Println("__NYX_GRAPHQL_RESOLVER__: " + "{type_name}" + "." + "{field}")
|
fmt.Println("__NYX_GRAPHQL_RESOLVER__: " + "{type_name}" + "." + "{field}")
|
||||||
fmt.Println("__NYX_SINK_HIT__")
|
fmt.Println("__NYX_SINK_HIT__")
|
||||||
cb, ok := entry.NyxResolvers["{handler}"]
|
cb := reflect.ValueOf({handler_expr})
|
||||||
if !ok {{
|
if !cb.IsValid() || cb.Kind() != reflect.Func {{
|
||||||
fmt.Fprintln(os.Stderr, "NYX_RESOLVER_NOT_FOUND: " + "{handler}")
|
fmt.Fprintln(os.Stderr, "NYX_RESOLVER_NOT_FOUND: " + "{handler}")
|
||||||
os.Exit(78)
|
os.Exit(78)
|
||||||
}}
|
}}
|
||||||
v := reflect.ValueOf(cb)
|
{runtime_call}
|
||||||
args := make([]reflect.Value, v.Type().NumIn())
|
|
||||||
for i := 0; i < v.Type().NumIn(); i++ {{
|
|
||||||
want := v.Type().In(i)
|
|
||||||
if want.Kind() == reflect.String {{
|
|
||||||
args[i] = reflect.ValueOf(payload)
|
|
||||||
}} else if want.String() == "context.Context" {{
|
|
||||||
args[i] = reflect.ValueOf(context.Background())
|
|
||||||
}} else {{
|
|
||||||
args[i] = reflect.Zero(want)
|
|
||||||
}}
|
|
||||||
}}
|
|
||||||
defer func() {{
|
defer func() {{
|
||||||
if r := recover(); r != nil {{
|
if r := recover(); r != nil {{
|
||||||
fmt.Fprintf(os.Stderr, "NYX_EXCEPTION: panic: %v\n", r)
|
fmt.Fprintf(os.Stderr, "NYX_EXCEPTION: panic: %v\n", r)
|
||||||
}}
|
}}
|
||||||
}}()
|
}}()
|
||||||
out := v.Call(args)
|
value, err := nyxInvokeResolverValue(cb, payload)
|
||||||
if len(out) > 0 {{
|
if err != nil {{
|
||||||
fmt.Println(out[0].Interface())
|
fmt.Fprintf(os.Stderr, "NYX_EXCEPTION: %v\n", err)
|
||||||
|
return
|
||||||
|
}}
|
||||||
|
if value != nil {{
|
||||||
|
fmt.Println(value)
|
||||||
}}
|
}}
|
||||||
}}
|
}}
|
||||||
|
|
||||||
|
func nyxInvokeResolverValue(v reflect.Value, payload string) (interface{{}}, error) {{
|
||||||
|
contextType := reflect.TypeOf((*context.Context)(nil)).Elem()
|
||||||
|
errorType := reflect.TypeOf((*error)(nil)).Elem()
|
||||||
|
args := make([]reflect.Value, v.Type().NumIn())
|
||||||
|
for i := 0; i < v.Type().NumIn(); i++ {{
|
||||||
|
want := v.Type().In(i)
|
||||||
|
if want.Kind() == reflect.String {{
|
||||||
|
args[i] = reflect.ValueOf(payload)
|
||||||
|
}} else if want.Implements(contextType) {{
|
||||||
|
args[i] = reflect.ValueOf(context.Background())
|
||||||
|
}} else if contextType.AssignableTo(want) {{
|
||||||
|
args[i] = reflect.ValueOf(context.Background())
|
||||||
|
}} else {{
|
||||||
|
args[i] = reflect.Zero(want)
|
||||||
|
}}
|
||||||
|
}}
|
||||||
|
out := v.Call(args)
|
||||||
|
var value interface{{}}
|
||||||
|
for _, item := range out {{
|
||||||
|
if item.Type().Implements(errorType) {{
|
||||||
|
if (item.Kind() == reflect.Interface || item.Kind() == reflect.Pointer) && !item.IsNil() {{
|
||||||
|
return nil, item.Interface().(error)
|
||||||
|
}}
|
||||||
|
continue
|
||||||
|
}}
|
||||||
|
if value == nil && item.IsValid() {{
|
||||||
|
value = item.Interface()
|
||||||
|
}}
|
||||||
|
}}
|
||||||
|
return value, nil
|
||||||
|
}}
|
||||||
|
{runtime_helpers}
|
||||||
"##,
|
"##,
|
||||||
handler = handler,
|
handler = handler,
|
||||||
|
handler_expr = handler_expr,
|
||||||
type_name = type_name,
|
type_name = type_name,
|
||||||
field = field,
|
field = field,
|
||||||
|
runtime_imports = runtime_imports,
|
||||||
|
runtime_call = runtime_call,
|
||||||
|
runtime_helpers = runtime_helpers,
|
||||||
);
|
);
|
||||||
HarnessSource {
|
HarnessSource {
|
||||||
source,
|
source,
|
||||||
|
|
|
||||||
|
|
@ -4687,9 +4687,6 @@ public class NyxHarness {{
|
||||||
System.exit(78);
|
System.exit(78);
|
||||||
}}
|
}}
|
||||||
m.setAccessible(true);
|
m.setAccessible(true);
|
||||||
if (nyxTrySpringHandlerInterceptor(instance, m, payload)) {{
|
|
||||||
return;
|
|
||||||
}}
|
|
||||||
Class<?>[] params = m.getParameterTypes();
|
Class<?>[] params = m.getParameterTypes();
|
||||||
Object[] mArgs = new Object[params.length];
|
Object[] mArgs = new Object[params.length];
|
||||||
for (int i = 0; i < params.length; i++) {{
|
for (int i = 0; i < params.length; i++) {{
|
||||||
|
|
@ -4810,6 +4807,9 @@ public class NyxHarness {{
|
||||||
System.exit(78);
|
System.exit(78);
|
||||||
}}
|
}}
|
||||||
m.setAccessible(true);
|
m.setAccessible(true);
|
||||||
|
if (nyxTrySpringHandlerExecutionChain(instance, m, payload)) {{
|
||||||
|
return;
|
||||||
|
}}
|
||||||
Class<?>[] params = m.getParameterTypes();
|
Class<?>[] params = m.getParameterTypes();
|
||||||
Object[] mArgs = new Object[params.length];
|
Object[] mArgs = new Object[params.length];
|
||||||
for (int i = 0; i < params.length; i++) {{
|
for (int i = 0; i < params.length; i++) {{
|
||||||
|
|
@ -4835,6 +4835,57 @@ public class NyxHarness {{
|
||||||
return "";
|
return "";
|
||||||
}}
|
}}
|
||||||
|
|
||||||
|
static boolean nyxTrySpringHandlerExecutionChain(Object instance, Method m, String payload) {{
|
||||||
|
if (!m.getName().equals("preHandle") || m.getParameterTypes().length < 3) {{
|
||||||
|
return false;
|
||||||
|
}}
|
||||||
|
try {{
|
||||||
|
Class<?> chainClass = Class.forName("org.springframework.web.servlet.HandlerExecutionChain");
|
||||||
|
Class<?> interceptorClass = Class.forName("org.springframework.web.servlet.HandlerInterceptor");
|
||||||
|
if (!interceptorClass.isAssignableFrom(instance.getClass())) {{
|
||||||
|
return false;
|
||||||
|
}}
|
||||||
|
Object interceptors = java.lang.reflect.Array.newInstance(interceptorClass, 1);
|
||||||
|
java.lang.reflect.Array.set(interceptors, 0, instance);
|
||||||
|
Object chain = chainClass
|
||||||
|
.getConstructor(Object.class, interceptors.getClass())
|
||||||
|
.newInstance(new Object(), interceptors);
|
||||||
|
Method getInterceptors = chainClass.getMethod("getInterceptors");
|
||||||
|
Object chainInterceptors = getInterceptors.invoke(chain);
|
||||||
|
int count = chainInterceptors == null ? 0 : java.lang.reflect.Array.getLength(chainInterceptors);
|
||||||
|
if (count == 0) {{
|
||||||
|
return false;
|
||||||
|
}}
|
||||||
|
Object request = null;
|
||||||
|
Object response = null;
|
||||||
|
for (Class<?> p : m.getParameterTypes()) {{
|
||||||
|
String name = p.getName();
|
||||||
|
if (request == null && name.endsWith("HttpServletRequest")) {{
|
||||||
|
request = nyxServletProxy(p, payload);
|
||||||
|
}} else if (response == null && name.endsWith("HttpServletResponse")) {{
|
||||||
|
response = nyxServletProxy(p, payload);
|
||||||
|
}}
|
||||||
|
}}
|
||||||
|
if (request == null || response == null) {{
|
||||||
|
return false;
|
||||||
|
}}
|
||||||
|
Object interceptor = java.lang.reflect.Array.get(chainInterceptors, 0);
|
||||||
|
Method preHandle = interceptor.getClass().getMethod(
|
||||||
|
"preHandle",
|
||||||
|
m.getParameterTypes()[0],
|
||||||
|
m.getParameterTypes()[1],
|
||||||
|
m.getParameterTypes()[2]
|
||||||
|
);
|
||||||
|
preHandle.invoke(interceptor, request, response, new Object());
|
||||||
|
return true;
|
||||||
|
}} catch (ClassNotFoundException missingSpring) {{
|
||||||
|
return false;
|
||||||
|
}} catch (Throwable e) {{
|
||||||
|
System.err.println("NYX_SPRING_CHAIN_FALLBACK: " + e.getClass().getName() + ": " + e.getMessage());
|
||||||
|
return false;
|
||||||
|
}}
|
||||||
|
}}
|
||||||
|
|
||||||
static boolean nyxTrySpringHandlerInterceptor(Object instance, Method m, String payload) {{
|
static boolean nyxTrySpringHandlerInterceptor(Object instance, Method m, String payload) {{
|
||||||
Class<?>[] params = m.getParameterTypes();
|
Class<?>[] params = m.getParameterTypes();
|
||||||
if (params.length < 3 || !m.getName().equals("preHandle")) {{
|
if (params.length < 3 || !m.getName().equals("preHandle")) {{
|
||||||
|
|
|
||||||
|
|
@ -1536,8 +1536,64 @@ def _nyx_try_celery_eager(task, body):
|
||||||
print(f"NYX_CELERY_EAGER_FALLBACK: {{type(_e).__name__}}: {{_e}}", file=sys.stderr, flush=True)
|
print(f"NYX_CELERY_EAGER_FALLBACK: {{type(_e).__name__}}: {{_e}}", file=sys.stderr, flush=True)
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
def _nyx_try_celery_registered_task(handler_name, task, body):
|
||||||
|
try:
|
||||||
|
from celery import current_app
|
||||||
|
except Exception:
|
||||||
|
return False
|
||||||
|
try:
|
||||||
|
app = getattr(task, "app", None) or current_app
|
||||||
|
if app is None or not hasattr(app, "tasks"):
|
||||||
|
return False
|
||||||
|
if hasattr(app, "conf"):
|
||||||
|
try:
|
||||||
|
app.conf.task_always_eager = True
|
||||||
|
app.conf.task_eager_propagates = False
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
candidates = [
|
||||||
|
handler_name,
|
||||||
|
getattr(task, "name", None),
|
||||||
|
getattr(_entry_mod, "__name__", "") + "." + handler_name,
|
||||||
|
]
|
||||||
|
registered = None
|
||||||
|
for name in candidates:
|
||||||
|
if not name:
|
||||||
|
continue
|
||||||
|
try:
|
||||||
|
registered = app.tasks.get(name)
|
||||||
|
except Exception:
|
||||||
|
registered = None
|
||||||
|
if registered is not None:
|
||||||
|
break
|
||||||
|
if registered is None:
|
||||||
|
suffix = "." + handler_name
|
||||||
|
try:
|
||||||
|
for task_name, candidate in app.tasks.items():
|
||||||
|
if str(task_name).endswith(suffix):
|
||||||
|
registered = candidate
|
||||||
|
break
|
||||||
|
except Exception:
|
||||||
|
registered = None
|
||||||
|
if registered is None:
|
||||||
|
return False
|
||||||
|
if hasattr(registered, "signature"):
|
||||||
|
sig = registered.signature(args=(body,))
|
||||||
|
result = sig.apply(throw=False)
|
||||||
|
else:
|
||||||
|
result = registered.apply(args=(body,), throw=False)
|
||||||
|
value = getattr(result, "result", None)
|
||||||
|
if value is not None:
|
||||||
|
print(str(value), flush=True)
|
||||||
|
return True
|
||||||
|
except SystemExit:
|
||||||
|
raise
|
||||||
|
except Exception as _e:
|
||||||
|
print(f"NYX_CELERY_REGISTRY_FALLBACK: {{type(_e).__name__}}: {{_e}}", file=sys.stderr, flush=True)
|
||||||
|
return False
|
||||||
|
|
||||||
try:
|
try:
|
||||||
if not _nyx_try_celery_eager(_h, payload):
|
if not _nyx_try_celery_registered_task({handler:?}, _h, payload) and not _nyx_try_celery_eager(_h, payload):
|
||||||
_result = _h(payload)
|
_result = _h(payload)
|
||||||
if _result is not None:
|
if _result is not None:
|
||||||
try:
|
try:
|
||||||
|
|
@ -1842,7 +1898,54 @@ try:
|
||||||
print(f"NYX_DJANGO_MIDDLEWARE_FALLBACK: {{type(_e).__name__}}: {{_e}}", file=sys.stderr, flush=True)
|
print(f"NYX_DJANGO_MIDDLEWARE_FALLBACK: {{type(_e).__name__}}: {{_e}}", file=sys.stderr, flush=True)
|
||||||
return False
|
return False
|
||||||
|
|
||||||
if not _nyx_try_django_middleware(_h, payload):
|
def _nyx_try_django_handler_chain(factory, body):
|
||||||
|
try:
|
||||||
|
import types
|
||||||
|
from django.conf import settings
|
||||||
|
module_name = "_nyx_phase21_middleware"
|
||||||
|
module = types.ModuleType(module_name)
|
||||||
|
setattr(module, "NyxMiddleware", factory)
|
||||||
|
module.urlpatterns = []
|
||||||
|
sys.modules[module_name] = module
|
||||||
|
middleware_path = module_name + ".NyxMiddleware"
|
||||||
|
if not settings.configured:
|
||||||
|
settings.configure(
|
||||||
|
DEFAULT_CHARSET="utf-8",
|
||||||
|
SECRET_KEY="nyx-dynamic-harness",
|
||||||
|
ROOT_URLCONF=module_name,
|
||||||
|
ALLOWED_HOSTS=["testserver", "localhost", "127.0.0.1"],
|
||||||
|
INSTALLED_APPS=[],
|
||||||
|
MIDDLEWARE=[middleware_path],
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
try:
|
||||||
|
settings.MIDDLEWARE = [middleware_path]
|
||||||
|
settings.ROOT_URLCONF = module_name
|
||||||
|
except Exception:
|
||||||
|
return False
|
||||||
|
import django
|
||||||
|
django.setup()
|
||||||
|
from django.core.handlers.base import BaseHandler
|
||||||
|
from django.test import RequestFactory
|
||||||
|
request = RequestFactory().post("/nyx", data={{"q": body}})
|
||||||
|
request._body = str(body).encode("utf-8", "replace")
|
||||||
|
handler = BaseHandler()
|
||||||
|
handler.load_middleware()
|
||||||
|
response = handler.get_response(request)
|
||||||
|
body_bytes = getattr(response, "content", None)
|
||||||
|
if body_bytes:
|
||||||
|
try:
|
||||||
|
print(body_bytes.decode("utf-8", "replace"), flush=True)
|
||||||
|
except Exception:
|
||||||
|
print(str(body_bytes), flush=True)
|
||||||
|
return True
|
||||||
|
except SystemExit:
|
||||||
|
raise
|
||||||
|
except Exception as _e:
|
||||||
|
print(f"NYX_DJANGO_HANDLER_CHAIN_FALLBACK: {{type(_e).__name__}}: {{_e}}", file=sys.stderr, flush=True)
|
||||||
|
return False
|
||||||
|
|
||||||
|
if not _nyx_try_django_handler_chain(_h, payload) and not _nyx_try_django_middleware(_h, payload):
|
||||||
_req = _NyxRequest(payload)
|
_req = _NyxRequest(payload)
|
||||||
# Try class-shaped middleware (instantiate with a get_response stub).
|
# Try class-shaped middleware (instantiate with a get_response stub).
|
||||||
try:
|
try:
|
||||||
|
|
|
||||||
|
|
@ -765,7 +765,12 @@ if Object.const_defined?({handler:?})
|
||||||
require 'sidekiq/testing'
|
require 'sidekiq/testing'
|
||||||
if cls.respond_to?(:perform_async)
|
if cls.respond_to?(:perform_async)
|
||||||
Sidekiq::Testing.inline! do
|
Sidekiq::Testing.inline! do
|
||||||
cls.perform_async($nyx_payload)
|
begin
|
||||||
|
require 'sidekiq/client'
|
||||||
|
Sidekiq::Client.push('class' => cls, 'args' => [$nyx_payload])
|
||||||
|
rescue LoadError, StandardError
|
||||||
|
cls.perform_async($nyx_payload)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
exit 0
|
exit 0
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -680,6 +680,9 @@ fn scheduled_job_python_harness_carries_sentinel_and_handler() {
|
||||||
assert!(h.source.contains("__NYX_SCHEDULED_JOB__"));
|
assert!(h.source.contains("__NYX_SCHEDULED_JOB__"));
|
||||||
assert!(h.source.contains("\"tick\""));
|
assert!(h.source.contains("\"tick\""));
|
||||||
assert!(h.source.contains("*/5 * * * *"));
|
assert!(h.source.contains("*/5 * * * *"));
|
||||||
|
assert!(h.source.contains("_nyx_try_celery_registered_task"));
|
||||||
|
assert!(h.source.contains("current_app"));
|
||||||
|
assert!(h.source.contains("app.tasks"));
|
||||||
assert!(h.source.contains("_nyx_try_celery_eager"));
|
assert!(h.source.contains("_nyx_try_celery_eager"));
|
||||||
assert!(h.source.contains("task.apply"));
|
assert!(h.source.contains("task.apply"));
|
||||||
}
|
}
|
||||||
|
|
@ -714,6 +717,10 @@ fn scheduled_job_java_harness_carries_sentinel_and_handler() {
|
||||||
assert!(h.source.contains("\"execute\""));
|
assert!(h.source.contains("\"execute\""));
|
||||||
assert!(h.source.contains("nyxTryQuartz"));
|
assert!(h.source.contains("nyxTryQuartz"));
|
||||||
assert!(h.source.contains("org.quartz.JobBuilder"));
|
assert!(h.source.contains("org.quartz.JobBuilder"));
|
||||||
|
assert!(
|
||||||
|
!h.source
|
||||||
|
.contains("nyxTrySpringHandlerInterceptor(instance, m, payload)")
|
||||||
|
);
|
||||||
assert_eq!(h.command, vec!["java", "-cp", ".:lib/*", "NyxHarness"]);
|
assert_eq!(h.command, vec!["java", "-cp", ".:lib/*", "NyxHarness"]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -729,6 +736,7 @@ fn scheduled_job_ruby_harness_carries_sentinel_and_handler() {
|
||||||
assert!(h.source.contains("__NYX_SCHEDULED_JOB__"));
|
assert!(h.source.contains("__NYX_SCHEDULED_JOB__"));
|
||||||
assert!(h.source.contains("TickWorker"));
|
assert!(h.source.contains("TickWorker"));
|
||||||
assert!(h.source.contains("sidekiq/testing"));
|
assert!(h.source.contains("sidekiq/testing"));
|
||||||
|
assert!(h.source.contains("Sidekiq::Client.push"));
|
||||||
assert!(h.source.contains("perform_async"));
|
assert!(h.source.contains("perform_async"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -873,7 +881,34 @@ fn graphql_resolver_go_harness_carries_sentinel_and_field() {
|
||||||
let h = lang::emit(&spec).expect("emit ok");
|
let h = lang::emit(&spec).expect("emit ok");
|
||||||
assert!(h.source.contains("__NYX_GRAPHQL_RESOLVER__"));
|
assert!(h.source.contains("__NYX_GRAPHQL_RESOLVER__"));
|
||||||
assert!(h.source.contains("ResolveUser"));
|
assert!(h.source.contains("ResolveUser"));
|
||||||
assert!(h.source.contains("entry.NyxResolvers"));
|
assert!(h.source.contains("reflect.ValueOf(entry.ResolveUser)"));
|
||||||
|
assert!(!h.source.contains("entry.NyxResolvers"));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn graphql_resolver_go_gqlgen_harness_uses_handler_runtime() {
|
||||||
|
let spec = framework_bound_spec(
|
||||||
|
Lang::Go,
|
||||||
|
EvEntryKind::GraphQLResolver {
|
||||||
|
type_name: "Query".into(),
|
||||||
|
field: "user".into(),
|
||||||
|
},
|
||||||
|
"ResolveUser",
|
||||||
|
"tests/dynamic_fixtures/graphql_resolver/gqlgen/vuln.go",
|
||||||
|
"graphql-gqlgen",
|
||||||
|
);
|
||||||
|
let h = lang::emit(&spec).expect("emit ok");
|
||||||
|
assert!(
|
||||||
|
h.source
|
||||||
|
.contains("github.com/99designs/gqlgen/graphql/handler")
|
||||||
|
);
|
||||||
|
assert!(h.source.contains("gqlhandler.NewDefaultServer"));
|
||||||
|
assert!(h.source.contains("httptest.NewRecorder"));
|
||||||
|
assert!(h.source.contains("nyxExecutableSchema"));
|
||||||
|
assert!(h.source.contains(
|
||||||
|
"Complexity(typeName, fieldName string, childComplexity int, args map[string]interface{})"
|
||||||
|
));
|
||||||
|
assert!(!h.source.contains("entry.NyxResolvers"));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|
@ -945,6 +980,9 @@ fn middleware_python_harness_carries_sentinel_and_handler() {
|
||||||
let h = lang::emit(&spec).expect("emit ok");
|
let h = lang::emit(&spec).expect("emit ok");
|
||||||
assert!(h.source.contains("__NYX_MIDDLEWARE__"));
|
assert!(h.source.contains("__NYX_MIDDLEWARE__"));
|
||||||
assert!(h.source.contains("\"audit\""));
|
assert!(h.source.contains("\"audit\""));
|
||||||
|
assert!(h.source.contains("_nyx_try_django_handler_chain"));
|
||||||
|
assert!(h.source.contains("BaseHandler"));
|
||||||
|
assert!(h.source.contains("handler.load_middleware"));
|
||||||
assert!(h.source.contains("_nyx_try_django_middleware"));
|
assert!(h.source.contains("_nyx_try_django_middleware"));
|
||||||
assert!(h.source.contains("RequestFactory"));
|
assert!(h.source.contains("RequestFactory"));
|
||||||
}
|
}
|
||||||
|
|
@ -979,6 +1017,8 @@ fn middleware_java_harness_carries_sentinel_and_handler() {
|
||||||
let h = lang::emit(&spec).expect("emit ok");
|
let h = lang::emit(&spec).expect("emit ok");
|
||||||
assert!(h.source.contains("__NYX_MIDDLEWARE__"));
|
assert!(h.source.contains("__NYX_MIDDLEWARE__"));
|
||||||
assert!(h.source.contains("\"preHandle\""));
|
assert!(h.source.contains("\"preHandle\""));
|
||||||
|
assert!(h.source.contains("nyxTrySpringHandlerExecutionChain"));
|
||||||
|
assert!(h.source.contains("HandlerExecutionChain"));
|
||||||
assert!(h.source.contains("nyxTrySpringHandlerInterceptor"));
|
assert!(h.source.contains("nyxTrySpringHandlerInterceptor"));
|
||||||
assert!(h.source.contains("HttpServletRequest"));
|
assert!(h.source.contains("HttpServletRequest"));
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue