<div dir="ltr"><br><br><div class="gmail_quote">On Mon, Aug 4, 2008 at 10:21 PM, Ceki Gulcu <span dir="ltr">&lt;listid@qos.ch&gt;</span> wrote:<br><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
Joern,<br>
<br>
Thanks for your input. Instead of forcing the test to sleep, another approach is</blockquote><div><br>The sleep was just meant as a placeholder for the code that will take some time, i.e. the actual code of the test. So I constructed one case where the test will work for sure, and one test that would always fail because it takes longer than the expected amount of time.<br>
I probably should have added some comments :)<br><br></div><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;"><br>
to adjust the expected performance according to the capabilities of the host<br>
CPU. This is the approach adopted in BogoPerf. See<br>
<br>
<a href="http://svn.qos.ch/viewvc/logback/trunk/logback-classic/src/test/java/ch/qos/logback/classic/LoggerPerfTest.java" target="_blank">http://svn.qos.ch/viewvc/logback/trunk/logback-classic/src/test/java/ch/qos/logback/classic/LoggerPerfTest.java</a><br>

<a href="http://svn.qos.ch/viewvc/logback/trunk/logback-classic/src/test/java/ch/qos/logback/classic/util/BogoPerf.java" target="_blank">http://svn.qos.ch/viewvc/logback/trunk/logback-classic/src/test/java/ch/qos/logback/classic/util/BogoPerf.java</a><br>

<div><div></div><div class="Wj3C7c"></div></div></blockquote><div><br>I&#39;ll take a look for sure.<br><br>Joern. <br><br><br></div><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
<div><div class="Wj3C7c"><br>
Joern Huxhorn wrote:<br>
&gt; Ceki Gulcu wrote:<br>
&gt;&gt; Hello all,<br>
&gt;&gt;<br>
&gt;&gt; Logback contains a small number of time-sensitive tests. The time needed to<br>
&gt;&gt; execute these tests depend on the capabilities of the host CPU. For example, if<br>
&gt;&gt; on my machine a test executes in 1 millisecond, I would expect it to<br>
&gt;&gt; finish in say 1*10 milliseconds on most machine -- allowing for 10 fold variation.<br>
&gt;&gt;<br>
&gt;&gt; Does anyone know of a junit extension which can help me normalize the<br>
&gt;&gt; coefficient, 10 in the previous example, so that it adapts to the<br>
&gt;&gt; speed of the host CPU? There is also the problem of the JIT<br>
&gt;&gt; compiler...<br>
&gt;&gt;<br>
&gt;&gt; Any recommendations on the subject?<br>
&gt;&gt;<br>
&gt;&gt;<br>
&gt; Well, I don&#39;t have a real solution to your problem...<br>
&gt; The only performance-related JUnit framework I&#39;m aware of is<br>
&gt; <a href="http://clarkware.com/software/JUnitPerf.html" target="_blank">http://clarkware.com/software/JUnitPerf.html</a> but I think it&#39;s outdated<br>
&gt; and I never used it.<br>
&gt; It could be useful for load-testing, though.<br>
&gt;<br>
&gt; If you are using JUnit 4.x I&#39;d suggest something like the following:<br>
&gt;<br>
&gt; import org.junit.Test;<br>
&gt; import org.junit.BeforeClass;<br>
&gt; import org.junit.Before;<br>
&gt; import static junit.framework.Assert.assertEquals;<br>
&gt; import static junit.framework.Assert.fail;<br>
&gt;<br>
&gt; public class TimingTest<br>
&gt; {<br>
&gt;<br>
&gt; &nbsp; &nbsp; private static long referenceTime;<br>
&gt;<br>
&gt; &nbsp; &nbsp; @BeforeClass<br>
&gt; &nbsp; &nbsp; public static void initReferenceTime()<br>
&gt; &nbsp; &nbsp; {<br>
&gt; &nbsp; &nbsp; &nbsp; &nbsp; long time=System.currentTimeMillis();<br>
&gt;<br>
&gt; &nbsp; &nbsp; &nbsp; &nbsp; // lets waste some time...<br>
&gt; &nbsp; &nbsp; &nbsp; &nbsp; StringBuffer msg=new StringBuffer();<br>
&gt; &nbsp; &nbsp; &nbsp; &nbsp; for(int i=0;i&lt;10000;i++)<br>
&gt; &nbsp; &nbsp; &nbsp; &nbsp; {<br>
&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; msg.append(i);<br>
&gt; &nbsp; &nbsp; &nbsp; &nbsp; }<br>
&gt; &nbsp; &nbsp; &nbsp; &nbsp; System.out.println(msg.toString());<br>
&gt; &nbsp; &nbsp; &nbsp; &nbsp; referenceTime=System.currentTimeMillis()-time;<br>
&gt; &nbsp; &nbsp; &nbsp; &nbsp; System.out.println(&quot;ReferenceTime: &quot;+referenceTime+&quot; millis&quot;);<br>
&gt; &nbsp; &nbsp; }<br>
&gt;<br>
&gt; &nbsp; &nbsp; @Test(timeout = 1000)<br>
&gt; &nbsp; &nbsp; public void works()<br>
&gt; &nbsp; &nbsp; &nbsp; &nbsp; throws Exception<br>
&gt; &nbsp; &nbsp; {<br>
&gt; &nbsp; &nbsp; &nbsp; &nbsp; long time=System.currentTimeMillis();<br>
&gt; &nbsp; &nbsp; &nbsp; &nbsp; Thread.sleep(referenceTime*5);<br>
&gt; &nbsp; &nbsp; &nbsp; &nbsp; time=System.currentTimeMillis()-time;<br>
&gt; &nbsp; &nbsp; &nbsp; &nbsp; long maxTime=referenceTime*10;<br>
&gt; &nbsp; &nbsp; &nbsp; &nbsp; if(time&gt;maxTime)<br>
&gt; &nbsp; &nbsp; &nbsp; &nbsp; {<br>
&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; fail(&quot;Test was not expected to take more than &quot;+maxTime+&quot;<br>
&gt; millis but took &quot;+time+&quot; millis!&quot;);<br>
&gt; &nbsp; &nbsp; &nbsp; &nbsp; }<br>
&gt; &nbsp; &nbsp; }<br>
&gt;<br>
&gt; &nbsp; &nbsp; @Test(timeout = 1000)<br>
&gt; &nbsp; &nbsp; public void fails()<br>
&gt; &nbsp; &nbsp; &nbsp; &nbsp; throws Exception<br>
&gt; &nbsp; &nbsp; {<br>
&gt; &nbsp; &nbsp; &nbsp; &nbsp; long time=System.currentTimeMillis();<br>
&gt; &nbsp; &nbsp; &nbsp; &nbsp; Thread.sleep(referenceTime*15);<br>
&gt; &nbsp; &nbsp; &nbsp; &nbsp; time=System.currentTimeMillis()-time;<br>
&gt; &nbsp; &nbsp; &nbsp; &nbsp; long maxTime=referenceTime*10;<br>
&gt; &nbsp; &nbsp; &nbsp; &nbsp; if(time&gt;maxTime)<br>
&gt; &nbsp; &nbsp; &nbsp; &nbsp; {<br>
&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; fail(&quot;Test was not expected to take more than &quot;+maxTime+&quot;<br>
&gt; millis but took &quot;+time+&quot; millis!&quot;);<br>
&gt; &nbsp; &nbsp; &nbsp; &nbsp; }<br>
&gt; &nbsp; &nbsp; }<br>
&gt; }<br>
&gt;<br>
&gt;<br>
&gt; The problem with this approach, however, is that referenceTime isn&#39;t<br>
&gt; very stable. It fluctuates between 15ms and 40ms on my development<br>
&gt; system. I guess this fluctuation could be reduced by using an even<br>
&gt; higher number in the initReferenceTime loop.<br>
&gt; The time-wasting would have to be changed depending on the<br>
&gt; problem-domain of the real test, e.g. something like the above if String<br>
&gt; operations are performed in the actual code that is tested.<br>
&gt;<br>
&gt; The timeout I&#39;ve given in @Test is supposed to be a definitive upper<br>
&gt; level that should never be reached. This could be left out, though.<br>
&gt;<br>
&gt; I have some doubts what the Hotspot-JIT will be doing if the above<br>
&gt; initReferenceTime is used the same way in more than one class. I have<br>
&gt; some hope that it does NOT realize that it&#39;s the same code but I&#39;m not sure.<br>
&gt;<br>
&gt; The code above isn&#39;t perfect, neither is it especially elegant, but it&#39;s<br>
&gt; probably good enough for your use case if initReferenceTime and the<br>
&gt; factors are tuned a bit...<br>
&gt; I don&#39;t know.<br>
&gt;<br>
&gt; Joern.<br>
</div></div><div class="Ih2E3d">&gt; _______________________________________________<br>
&gt; logback-dev mailing list<br>
&gt; logback-dev@qos.ch<br>
&gt; <a href="http://qos.ch/mailman/listinfo/logback-dev" target="_blank">http://qos.ch/mailman/listinfo/logback-dev</a><br>
<br>
</div><font color="#888888">--<br>
Ceki Gülcü<br>
<br>
QOS.ch is looking to hire talented developers located in Switzerland<br>
to work on cutting-edge software projects. If you think you are<br>
qualified, then please contact ceki@qos.ch.<br>
</font><div><div></div><div class="Wj3C7c">_______________________________________________<br>
logback-dev mailing list<br>
logback-dev@qos.ch<br>
<a href="http://qos.ch/mailman/listinfo/logback-dev" target="_blank">http://qos.ch/mailman/listinfo/logback-dev</a><br>
</div></div></blockquote></div><br></div>