From 8981e025b95247516d8d3dfce22611f808ca5e98 Mon Sep 17 00:00:00 2001 From: Zac Spitzer Date: Tue, 24 Dec 2024 00:23:50 +0100 Subject: [PATCH] LDEV-5206 ExecutionLog improvements (#2458) --- .../java/lucee/runtime/PageSourceImpl.java | 14 ++ .../lucee/runtime/debug/DebuggerImpl.java | 37 +++-- .../runtime/engine/ConsoleExecutionLog.java | 32 ++-- .../runtime/engine/DebugExecutionLog.java | 7 +- .../lucee/runtime/engine/LogExecutionLog.java | 76 ++++++++++ .../bytecode/util/ExpressionUtil.java | 2 +- .../transformer/cfml/tag/CFMLTransformer.java | 8 +- .../transformer/util/PageSourceCode.java | 7 + .../java/resource/setting/sysprop-envvar.json | 5 + .../main/java/lucee/runtime/PageSource.java | 4 + test/tickets/LDEV5206.cfc | 142 ++++++++++++++++++ test/tickets/LDEV5206/Application.cfc | 7 + test/tickets/LDEV5206/ldev5206.cfc | 7 + test/tickets/LDEV5206/ldev5206.cfm | 10 ++ test/tickets/LDEV5206/ldev5206_tag.cfc | 9 ++ 15 files changed, 337 insertions(+), 30 deletions(-) create mode 100644 core/src/main/java/lucee/runtime/engine/LogExecutionLog.java create mode 100644 test/tickets/LDEV5206.cfc create mode 100644 test/tickets/LDEV5206/Application.cfc create mode 100644 test/tickets/LDEV5206/ldev5206.cfc create mode 100644 test/tickets/LDEV5206/ldev5206.cfm create mode 100644 test/tickets/LDEV5206/ldev5206_tag.cfc diff --git a/core/src/main/java/lucee/runtime/PageSourceImpl.java b/core/src/main/java/lucee/runtime/PageSourceImpl.java index 644627b4e0..501c40793c 100755 --- a/core/src/main/java/lucee/runtime/PageSourceImpl.java +++ b/core/src/main/java/lucee/runtime/PageSourceImpl.java @@ -90,6 +90,7 @@ public final class PageSourceImpl implements PageSource { private long lastAccess; private RefIntegerSync accessCount = new RefIntegerSync(); private boolean flush = false; + private int sourceOffset; // used to track when wrapping in cfscript tag private static class PageAndClassName { private Page page; @@ -1156,4 +1157,17 @@ public void resetLoaded() { Page p = pcn.page; if (p != null) p.setLoadType((byte) 0); } + + @Override + public void setSourceOffset(int sourceOffset) { + this.sourceOffset = sourceOffset; + } + + @Override + public int getSourceOffset() { + //lucee.aprint.o("sourceOffset:"+ sourceOffset); + return sourceOffset; + } + + } \ No newline at end of file diff --git a/core/src/main/java/lucee/runtime/debug/DebuggerImpl.java b/core/src/main/java/lucee/runtime/debug/DebuggerImpl.java index 0ce13d3bba..09fd72e59e 100644 --- a/core/src/main/java/lucee/runtime/debug/DebuggerImpl.java +++ b/core/src/main/java/lucee/runtime/debug/DebuggerImpl.java @@ -108,7 +108,7 @@ public final class DebuggerImpl implements Debugger { private static final Collection.Key GENERIC_DATA = KeyConstants._genericData; private static final Collection.Key PAGE_PARTS = KeyConstants._pageParts; - private static final int MAX_PARTS = 100; + private static final int MAX_PARTS = Caster.toIntValue(SystemUtil.getSystemPropOrEnvVar("lucee.debugging.maxPageParts", null), 0); private final Map entries = new HashMap(); private Map partEntries; @@ -236,7 +236,7 @@ public DebugEntryTemplatePart getEntry(PageContext pc, PageSource source, int st if (de != null) { de.countPP(); return de; - } + } } else { partEntries = new HashMap(); @@ -559,26 +559,33 @@ public Struct getDebuggingData(PageContext pc, boolean addAddionalInfo) throws D int qrySize = 0; Query qryPart = null; if (hasParts) { - String slowestTemplate = arrPages.get(0).getPath(); - List filteredPartEntries = new ArrayList(); java.util.Collection col = partEntries.values(); - for (DebugEntryTemplatePart detp: col) { + List filteredPartEntries = new ArrayList(); + DebugEntryTemplatePart[] parts = new DebugEntryTemplatePart[qrySize]; + if (MAX_PARTS == 0 || col.size() < MAX_PARTS){ + qrySize = col.size(); + parts = new DebugEntryTemplatePart[qrySize]; + filteredPartEntries.addAll(col); + parts = filteredPartEntries.toArray(parts); + } else { + // TODO add slowest templates till we reach MAX_PARTS, currently just grabs only the slowest template's parts + String slowestTemplate = arrPages.get(0).getPath(); + for (DebugEntryTemplatePart detp: col) { + if (detp.getPath().equals(slowestTemplate)) filteredPartEntries.add(detp); + } + qrySize = Math.min(filteredPartEntries.size(), MAX_PARTS); + parts = new DebugEntryTemplatePart[qrySize]; - if (detp.getPath().equals(slowestTemplate)) filteredPartEntries.add(detp); - } - qrySize = Math.min(filteredPartEntries.size(), MAX_PARTS); + Collections.sort(filteredPartEntries, DEBUG_ENTRY_TEMPLATE_PART_COMPARATOR); + + if (filteredPartEntries.size() > MAX_PARTS) parts = filteredPartEntries.subList(0, MAX_PARTS).toArray(parts); + else parts = filteredPartEntries.toArray(parts); + } qryPart = new QueryImpl(PAGE_PART_COLUMNS, qrySize, "query"); debugging.setEL(PAGE_PARTS, qryPart); int row = 0; - Collections.sort(filteredPartEntries, DEBUG_ENTRY_TEMPLATE_PART_COMPARATOR); - - DebugEntryTemplatePart[] parts = new DebugEntryTemplatePart[qrySize]; - - if (filteredPartEntries.size() > MAX_PARTS) parts = filteredPartEntries.subList(0, MAX_PARTS).toArray(parts); - else parts = filteredPartEntries.toArray(parts); - try { DebugEntryTemplatePart de; // PageSource ps; diff --git a/core/src/main/java/lucee/runtime/engine/ConsoleExecutionLog.java b/core/src/main/java/lucee/runtime/engine/ConsoleExecutionLog.java index db4b0ca542..03d42be107 100644 --- a/core/src/main/java/lucee/runtime/engine/ConsoleExecutionLog.java +++ b/core/src/main/java/lucee/runtime/engine/ConsoleExecutionLog.java @@ -21,41 +21,55 @@ import java.io.PrintWriter; import java.util.Map; -import lucee.commons.io.log.Log; -import lucee.commons.io.log.LogUtil; +import lucee.commons.io.res.util.ResourceSnippet; +import lucee.commons.io.res.util.ResourceSnippetsMap; import lucee.runtime.PageContext; +import lucee.runtime.PageSource; +import lucee.runtime.PageContextImpl; +import lucee.runtime.op.Caster; public class ConsoleExecutionLog extends ExecutionLogSupport { private PrintWriter pw; private PageContext pc; + private ResourceSnippetsMap snippetsMap = new ResourceSnippetsMap(1024, 128); + private boolean snippet = false; @Override protected void _init(PageContext pc, Map arguments) { this.pc = pc; - + if (Caster.toBooleanValue(arguments.get("snippet"), false)) snippet = true; if (pw == null) { // stream type String type = arguments.get("stream-type"); - if (type != null && type.trim().equalsIgnoreCase("error")) pw = new PrintWriter(System.err); + if (type.trim().equalsIgnoreCase("error")) pw = new PrintWriter(System.err); else pw = new PrintWriter(System.out); - } } @Override protected void _log(int startPos, int endPos, long startTime, long endTime) { - + PageSource ps = pc.getCurrentPageSource(null); + if (ps == null) return; long diff = endTime - startTime; - LogUtil.log(pc, Log.LEVEL_TRACE, Controler.class.getName(), - pc.getId() + ":" + pc.getCurrentPageSource().getDisplayPath() + ":" + positons(startPos, endPos) + " > " + timeLongToString(diff)); + String log = pc.getId() + ":" + ps.getDisplayPath() + ":"; + if (snippet) { + ResourceSnippet snippet = snippetsMap.getSnippet(ps, startPos, endPos, ((PageContextImpl) pc).getResourceCharset().name()); + log += positions(snippet.getEndLine(), snippet.getEndLine()) + " > " + timeLongToString(diff) + " [" + snippet.getContent() + "]"; + } else { + log += positions(startPos, endPos) + " > " + timeLongToString(diff); + } + pw.print(log + "\n"); + pw.flush(); } @Override protected void _release() { + //if (pw != null) pw.close(); + snippetsMap = null; } - private static String positons(int startPos, int endPos) { + private static String positions(int startPos, int endPos) { if (startPos == endPos) return startPos + ""; return startPos + ":" + endPos; } diff --git a/core/src/main/java/lucee/runtime/engine/DebugExecutionLog.java b/core/src/main/java/lucee/runtime/engine/DebugExecutionLog.java index cd4e517d73..e188356b5c 100644 --- a/core/src/main/java/lucee/runtime/engine/DebugExecutionLog.java +++ b/core/src/main/java/lucee/runtime/engine/DebugExecutionLog.java @@ -21,6 +21,7 @@ import java.util.Map; import lucee.runtime.PageContext; +import lucee.runtime.PageSource; import lucee.runtime.debug.DebugEntry; import lucee.runtime.util.PageContextUtil; @@ -37,12 +38,14 @@ protected void _init(PageContext pc, Map arguments) { protected void _log(int startPos, int endPos, long startTime, long endTime) { if (!PageContextUtil.debug(pc)) return; - + PageSource ps = pc.getCurrentPageSource(null); + if (ps == null) return; + long diff = endTime - startTime; if (unit == UNIT_MICRO) diff /= 1000; else if (unit == UNIT_MILLI) diff /= 1000000; - DebugEntry de = pc.getDebugger().getEntry(pc, pc.getCurrentPageSource(), startPos, endPos); + DebugEntry de = pc.getDebugger().getEntry(pc, ps, startPos, endPos); de.updateExeTime((int) diff); } diff --git a/core/src/main/java/lucee/runtime/engine/LogExecutionLog.java b/core/src/main/java/lucee/runtime/engine/LogExecutionLog.java new file mode 100644 index 0000000000..2c97d0de19 --- /dev/null +++ b/core/src/main/java/lucee/runtime/engine/LogExecutionLog.java @@ -0,0 +1,76 @@ +/** + * + * Copyright (c) 2014, the Railo Company Ltd. All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see . + * + **/ +package lucee.runtime.engine; + +import java.io.PrintWriter; +import java.util.Map; + +import lucee.commons.io.log.Log; +import lucee.commons.io.log.LogUtil; +import lucee.commons.io.res.util.ResourceSnippet; +import lucee.commons.io.res.util.ResourceSnippetsMap; +import lucee.commons.lang.StringUtil; +import lucee.runtime.PageContext; +import lucee.runtime.PageSource; +import lucee.runtime.PageContextImpl; +import lucee.runtime.op.Caster; + +public class LogExecutionLog extends ExecutionLogSupport { + + private PageContext pc; + private ResourceSnippetsMap snippetsMap = new ResourceSnippetsMap(1024, 128); + private boolean snippet = false; + private int logLevel; + private String logName; + + @Override + protected void _init(PageContext pc, Map arguments) { + this.pc = pc; + if (Caster.toBooleanValue(arguments.get("snippet"), false)) snippet = true; + String type = arguments.get("log-level"); + logLevel = LogUtil.toLevel(type, Log.LEVEL_TRACE); + logName = StringUtil.toString(arguments.get("log-name"), Controler.class.getName()); + } + + @Override + protected void _log(int startPos, int endPos, long startTime, long endTime) { + PageSource ps = pc.getCurrentPageSource(null); + if (ps == null) return; + long diff = endTime - startTime; + String log = pc.getId() + ":" + ps.getDisplayPath() + ":"; + if (snippet) { + ResourceSnippet snippet = snippetsMap.getSnippet(ps, startPos, endPos, ((PageContextImpl) pc).getResourceCharset().name()); + log += positions(snippet.getEndLine(), snippet.getEndLine()) + " > " + timeLongToString(diff) + " [" + snippet.getContent() + "]"; + } else { + log += positions(startPos, endPos) + " > " + timeLongToString(diff); + } + LogUtil.log(pc, logLevel, Controler.class.getName(), log); + } + + @Override + protected void _release() { + snippetsMap = null; + } + + private static String positions(int startPos, int endPos) { + if (startPos == endPos) return startPos + ""; + return startPos + ":" + endPos; + } + +} \ No newline at end of file diff --git a/core/src/main/java/lucee/transformer/bytecode/util/ExpressionUtil.java b/core/src/main/java/lucee/transformer/bytecode/util/ExpressionUtil.java index b2b1795ec1..33357dbab1 100755 --- a/core/src/main/java/lucee/transformer/bytecode/util/ExpressionUtil.java +++ b/core/src/main/java/lucee/transformer/bytecode/util/ExpressionUtil.java @@ -158,7 +158,7 @@ private static void call_Log(BytecodeContext bc, Method method, Position pos, St GeneratorAdapter adapter = bc.getAdapter(); adapter.loadArg(0); // adapter.checkCast(Types.PAGE_CONTEXT_IMPL); - adapter.push(pos.pos); + adapter.push(pos.pos - bc.getPageSource().getSourceOffset()); adapter.push(id); adapter.invokeVirtual(Types.PAGE_CONTEXT, method); } diff --git a/core/src/main/java/lucee/transformer/cfml/tag/CFMLTransformer.java b/core/src/main/java/lucee/transformer/cfml/tag/CFMLTransformer.java index 1ea9a5b8da..8d558f1d54 100755 --- a/core/src/main/java/lucee/transformer/cfml/tag/CFMLTransformer.java +++ b/core/src/main/java/lucee/transformer/cfml/tag/CFMLTransformer.java @@ -165,7 +165,8 @@ public Page transform(Factory factory, ConfigPro config, PageSource ps, TagLib[] // try inside a cfscript String text = "<" + scriptTag.getFullName() + ">" + original.getText() + "\n"; - sc = new PageSourceCode(ps, text, charset, writeLog); + int sourceOffset = ("<" + scriptTag.getFullName() + ">").length(); + sc = new PageSourceCode(ps, text, charset, writeLog, sourceOffset); } p = transform(factory, config, sc, tlibs, flibs, ps.getResource().lastModified(), dotUpper, returnValue, ignoreScopes); @@ -198,14 +199,15 @@ public Page transform(Factory factory, ConfigPro config, PageSource ps, TagLib[] // try inside a cfscript String text = "<" + scriptTag.getFullName() + ">" + original.getText() + "\n"; - sc = new PageSourceCode(ps, text, charset, writeLog); + int sourceOffset = ("<" + scriptTag.getFullName() + ">").length(); + sc = new PageSourceCode(ps, text, charset, writeLog, sourceOffset); try { while (true) { if (sc == null) { sc = new PageSourceCode(ps, charset, writeLog); text = "<" + scriptTag.getFullName() + ">" + sc.getText() + "\n"; - sc = new PageSourceCode(ps, text, charset, writeLog); + sc = new PageSourceCode(ps, text, charset, writeLog, sourceOffset); } try { _p = transform(factory, config, sc, tlibs, flibs, ps.getResource().lastModified(), dotUpper, returnValue, ignoreScopes); diff --git a/core/src/main/java/lucee/transformer/util/PageSourceCode.java b/core/src/main/java/lucee/transformer/util/PageSourceCode.java index d754813b5c..52397f51b4 100644 --- a/core/src/main/java/lucee/transformer/util/PageSourceCode.java +++ b/core/src/main/java/lucee/transformer/util/PageSourceCode.java @@ -44,6 +44,13 @@ public PageSourceCode(PageSource ps, String text, Charset charset, boolean write this.ps = ps; } + public PageSourceCode(PageSource ps, String text, Charset charset, boolean writeLog, int sourceOffset) { + super(null, text, writeLog); + this.charset = charset; + this.ps = ps; + ps.setSourceOffset(sourceOffset); + } + public static String toString(PageSource ps, Charset charset) throws IOException { String content; InputStream is = null; diff --git a/core/src/main/java/resource/setting/sysprop-envvar.json b/core/src/main/java/resource/setting/sysprop-envvar.json index fe31d2867f..644419d9b7 100644 --- a/core/src/main/java/resource/setting/sysprop-envvar.json +++ b/core/src/main/java/resource/setting/sysprop-envvar.json @@ -398,5 +398,10 @@ "sysprop": "lucee.threads.maxDefault", "envvar": "LUCEE_THREADS_MAXDEFAULT", "desc": "Sets the default max number of parallel threads, default 20" + }, + { + "sysprop": "lucee.debugging.maxPageParts", + "envvar": "LUCEE_DEBUGGING_MAXPAGEPARTS", + "desc": "Maximum number of debugging page parts (executionLogs to output), 0 to disable max limit" } ] \ No newline at end of file diff --git a/loader/src/main/java/lucee/runtime/PageSource.java b/loader/src/main/java/lucee/runtime/PageSource.java index b5c134bdb2..8da311bf72 100755 --- a/loader/src/main/java/lucee/runtime/PageSource.java +++ b/loader/src/main/java/lucee/runtime/PageSource.java @@ -182,4 +182,8 @@ public interface PageSource extends Serializable { */ public boolean executable(); + public abstract void setSourceOffset(int sourceOffset); + + public abstract int getSourceOffset(); + } \ No newline at end of file diff --git a/test/tickets/LDEV5206.cfc b/test/tickets/LDEV5206.cfc new file mode 100644 index 0000000000..4863478ccd --- /dev/null +++ b/test/tickets/LDEV5206.cfc @@ -0,0 +1,142 @@ +component extends = "org.lucee.cfml.test.LuceeTestCase" { + + function beforeAll(){ + variables.uri = createURI("LDEV5206"); + disableExecutionLog(); + }; + + function afterAll(){ + disableExecutionLog(); + }; + + function run( testResults, testBox ){ + describe( "LDEV-5206 ConsoleExecutionLog", function(){ + it( "test ConsoleExecutionLog", function(){ + enableExecutionLog("lucee.runtime.engine.ConsoleExecutionLog",{ + "stream-type": "out", + "unit": "milli", + //"min-time": 100, + "snippet": true + }); + systemOutput("", true); + systemOutput("Logging executionLog to console", true); + local.result = _InternalRequest( + template : "#uri#/ldev5206.cfm" + ); + }); + }); + + describe( "LDEV-5206 DebugExecutionLog", function(){ + it( "test DebugExecutionLog - cfm ", function(){ + var logs = getDebugLogs(); + expect( len( logs ) ).toBe( 1 ); + var log = logs[ 1 ]; + expect( log ).toHaveKey( "pageParts" ); + var pageParts = log.pageParts; + expect( pageParts ).toBeQuery(); + //systemOutput( pageParts.toString(), true ); + pageParts = _toPartsStruct( pageParts ); + //systemOutput( structKeyList(pageParts), true ); + //systemOutput( pageParts.toString(), true ); + + var key = "ldev5206.cfm:3:3"; + expect( pageParts ).toHaveKey( key ); + expect( pageParts[ key ].snippet ).toBe( "sleep(5)" ); + + key = "ldev5206.cfm:5:5"; + expect( pageParts ).toHaveKey( key ); + expect( pageParts[ key ].snippet ).toBe( "cfc = new ldev5206()" ); + }); + + xit( "LDEV-5212 test DebugExecutionLog - cfm parts member", function(){ + var logs = getDebugLogs(); + expect( len( logs ) ).toBe( 1 ); + var log = logs[ 1 ]; + expect( log ).toHaveKey( "pageParts" ); + var pageParts = log.pageParts; + expect( pageParts ).toBeQuery(); + pageParts = _toPartsStruct( pageParts ); + + key = "ldev5206.cfm:6:6"; + expect( pageParts ).toHaveKey( key ); + expect( pageParts[ key ].snippet ).toBe( "cfc.doSleep()" ); // LDEV-5207 only returns "cfc" + + key = "ldev5206.cfm:9:9"; + expect( pageParts ).toHaveKey( key ); + expect( pageParts[ key ].snippet ).toBe( "cfc.doSleep()" ); // LDEV-5207 only returns "cfc" + }); + + it( "test DebugExecutionLog - cfc parts ", function(){ + var logs = getDebugLogs(); + expect( len( logs ) ).toBe( 1 ); + var log = logs[ 1 ]; + expect( log ).toHaveKey( "pageParts" ); + var pageParts = log.pageParts; + expect( pageParts ).toBeQuery(); + pageParts = _toPartsStruct( pageParts ); + + key = "ldev5206_tag.cfc:6:6"; + expect( pageParts ).toHaveKey( key ); + expect( pageParts[ key ].snippet ).toBe( "sleep(5)" ); + + key = "ldev5206.cfc:5:5"; + expect( pageParts ).toHaveKey( key ); + expect( pageParts[ key ].snippet ).toBe( "sleep(5)" ); // LDEV-5207 + + }); + }); + + } + + private string function createURI( string calledName ){ + var baseURI = "/test/#listLast( getDirectoryFromPath( getCurrentTemplatePath() ), "\/" )#/"; + return baseURI & "" & calledName; + } + + private function enableExecutionLog( string class, struct args ){ + admin action="UpdateExecutionLog" type="server" password="#request.SERVERADMINPASSWORD#" + class="#arguments.class#" enabled= true + arguments=arguments.args; + admin action="updateDebug" type="server" password="#request.SERVERADMINPASSWORD#" debug="true" template="true"; // template needs to be enabled to produce debug logs + } + private function disableExecutionLog(class="lucee.runtime.engine.ConsoleExecutionLog"){ + admin action="updateDebug" type="server" password="#request.SERVERADMINPASSWORD#" debug="false"; + + admin action="UpdateExecutionLog" type="server" password="#request.SERVERADMINPASSWORD#" arguments={} + class="#arguments.class#" enabled=false; + admin action="PurgeDebugPool" type="server" password="#request.SERVERADMINPASSWORD#"; + } + + private function getLoggedDebugData(){ + var logs = []; + admin action="getLoggedDebugData" type="server" password="#request.SERVERADMINPASSWORD#" returnVariable="logs"; + return logs; + } + + private function _toPartsStruct( query pageParts ){ + var parts = duplicate( pageParts ); + var dir = getDirectoryFromPath( getCurrentTemplatePath() ) & "/ldev5206/"; + queryAddColumn( parts, "key" ); + var r = 0; + loop query=parts { + var r = parts.currentrow; + querySetCell( parts, "path", mid( parts.path[ r ], len( dir ) ), r ); // less verbose + querySetCell( parts, "key", parts.path[ r ] & ":" & parts.startLine[ r ] & ":" & parts.endLine[ r ], r ); + } + var st = QueryToStruct(parts, "key"); + return st; + } + + function getDebugLogs() cachedwithin="request" { + disableExecutionLog(); + enableExecutionLog( "lucee.runtime.engine.DebugExecutionLog",{ + "unit": "milli" + //"min-time": 100 + }); + local.result = _InternalRequest( + template : "#uri#/ldev5206.cfm", + url: "pagePoolClear=true" // TODO cfcs aren't recompiled like cfm templates? + ); + return getLoggedDebugData(); + } +} diff --git a/test/tickets/LDEV5206/Application.cfc b/test/tickets/LDEV5206/Application.cfc new file mode 100644 index 0000000000..a1c1fa72c9 --- /dev/null +++ b/test/tickets/LDEV5206/Application.cfc @@ -0,0 +1,7 @@ +component { + this.name='LDEV-5206'; + function onRequestStart(){ + if ( structKeyExists( url, "pagePoolClear" ) ) + pagePoolClear(); + } +} diff --git a/test/tickets/LDEV5206/ldev5206.cfc b/test/tickets/LDEV5206/ldev5206.cfc new file mode 100644 index 0000000000..02a4f5aedc --- /dev/null +++ b/test/tickets/LDEV5206/ldev5206.cfc @@ -0,0 +1,7 @@ +// test DebugExecutionLog refers to this code, update if changed +component { + this.name='LDEV-5206'; + function doSleep(){ + sleep(5); + } +} diff --git a/test/tickets/LDEV5206/ldev5206.cfm b/test/tickets/LDEV5206/ldev5206.cfm new file mode 100644 index 0000000000..bba4c0258b --- /dev/null +++ b/test/tickets/LDEV5206/ldev5206.cfm @@ -0,0 +1,10 @@ + + // test DebugExecutionLog refers to this code, update if changed + sleep(5); + echo("back from sleep"); + cfc = new ldev5206(); + cfc.doSleep(); + + cfc = new ldev5206_tag(); + cfc.doSleep(); + diff --git a/test/tickets/LDEV5206/ldev5206_tag.cfc b/test/tickets/LDEV5206/ldev5206_tag.cfc new file mode 100644 index 0000000000..7af5fe0f1b --- /dev/null +++ b/test/tickets/LDEV5206/ldev5206_tag.cfc @@ -0,0 +1,9 @@ + + + + + function doSleep(){ + sleep(5); + } + + \ No newline at end of file