<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <meta content="text/html; charset=ISO-8859-1"
      http-equiv="Content-Type">
  </head>
  <body text="#000000" bgcolor="#ffffff">
    I have done an initial commit in which I improved
    KnowledgeAgentTest, starting on the other test&nbsp; classes now. I made
    a jira for it:<br>
    <a class="moz-txt-link-freetext" href="https://jira.jboss.org/browse/JBRULES-2817">https://jira.jboss.org/browse/JBRULES-2817</a><br>
    <br>
    If you are doing anything over weekend, feel free to review/improve
    or move over the other tests. Also Creating a standalone unit test
    that is purely for ResourceScannerImpl would be a nice thing. That
    it tests purely the scan method, using mocks (mockito maybe?) to
    check the propagations and that it tests the interval scanners and
    confgurations there, meaning they don't need to be part of any other
    tests.<br>
    <br>
    We also need to move all of these deamon service threads to use the
    standardised Thread management api that edson did.<br>
    <br>
    Mark<br>
    On 04/12/2010 15:27, Mark Proctor wrote:
    <blockquote cite="mid:4CFA5DEA.3090909@codehaus.org" type="cite">
      <meta content="text/html; charset=ISO-8859-1"
        http-equiv="Content-Type">
      1) the scanner's time doesn't really need to be part of the unit
      tests, as that can be tested separately and we know it'll work. So
      we can just call scan() instead.&nbsp; See code in 2)<br>
      <br>
      2) I've also moved it to use a CountDownLatch on a
      afterChangeSetApplied event.<br>
      &nbsp;&nbsp;&nbsp; private void scan(KnowledgeAgent kagent) {<br>
      &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Calls the Resource Scanner and sets up a listener and a
      latch so we can wait until it's finished processing, instead of
      using timers<br>
      &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; final CountDownLatch latch = new CountDownLatch( 1 );<br>
      &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>
      &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; KnowledgeAgentEventListener l = new
      KnowledgeAgentEventListener() {<br>
      &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; ...<br>
      &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>
      &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public void
      afterChangeSetApplied(AfterChangeSetAppliedEvent event) {<br>
      &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; latch.countDown();<br>
      &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>
      &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; };&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>
      &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>
      &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; kagent.addEventListener( l );<br>
      &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>
      &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; this.scanner.scan();<br>
      &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>
      &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; try {<br>
      &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; latch.await( 10, TimeUnit.SECONDS );<br>
      &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } catch ( InterruptedException e ) {<br>
      &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; throw new RuntimeException( "Unable to wait for latch
      countdown", e);<br>
      &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>
      &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>
      &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if ( latch.getCount() &gt; 0 ) {&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>
      &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; throw new RuntimeException( "Event for KnowlegeBase
      update, due to scan, was never received" );<br>
      &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>
      &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>
      &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; kagent.removeEventListener( l );<br>
      &nbsp;&nbsp;&nbsp; }<br>
      <br>
      3) All file deletes go through the FileManager. I always do
      multiple attempts at deleting a file and throw an exception if it
      was not successfuly<br>
      &nbsp;&nbsp;&nbsp; public boolean deleteFile(File file) {<br>
      &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // This will attempt to delete a file 5 times, calling GC
      and Sleep between each iteration<br>
      &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Sometimes windows takes a while to release a lock on a
      file<br>
      &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if ( !file.delete() ) {<br>
      &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int count = 0;<br>
      &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; while ( !file.delete() &amp;&amp; count++ &lt; 5 ) {<br>
      &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.gc();<br>
      &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; try {<br>
      &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Thread.sleep( 250 );<br>
      &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } catch ( InterruptedException e ) {<br>
      &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; throw new RuntimeException( "This should never
      happen" );<br>
      &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>
      &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>
      &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>
      <br>
      &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return !file.exists();<br>
      <br>
      &nbsp;&nbsp;&nbsp; }<br>
      <br>
      3) File writting always waits 1000ms when the file already exists
      (http and linux round to nearest second) so it ensures
      lastmodified is always atleast 1000ms after lastread. See code in
      4)<br>
      <br>
      4) All file writting goes via the FileManager where I know attempt
      to write any file 5 times, calling GC and wait between each
      iteration.<br>
      &nbsp;&nbsp;&nbsp; public void write(File f,<br>
      &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String text) throws IOException {<br>
      &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if ( f.exists() ) {<br>
      &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // we want to make sure there is a time difference for
      lastModified and lastRead checks as Linux and http often round to
      seconds<br>
      &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //
      <a moz-do-not-send="true" class="moz-txt-link-freetext"
href="http://saloon.javaranch.com/cgi-bin/ubb/ultimatebb.cgi?ubb=get_topic&amp;f=1&amp;t=019789">http://saloon.javaranch.com/cgi-bin/ubb/ultimatebb.cgi?ubb=get_topic&amp;f=1&amp;t=019789</a><br>
      &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; try {<br>
      &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Thread.sleep( 1000 );<br>
      &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } catch ( Exception e ) {<br>
      &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; throw new RuntimeException( "Unable to sleep" );<br>
      &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>
      &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>
      <br>
      &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Attempt to write the file<br>
      &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; BufferedWriter output = new BufferedWriter( new
      FileWriter( f ) );<br>
      &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; output.write( text );<br>
      &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; output.close();<br>
      <br>
      &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Now check the file was written and re-attempt if it was
      not&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>
      &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Need to do this for testing, to ensure the texts are
      read the same way, otherwise sometimes you get tail \n sometimes
      you don't<br>
      &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String t1 = StringUtils.toString( new StringReader( text )
      );<br>
      <br>
      &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int count = 0;<br>
      &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; while ( !t1.equals( StringUtils.toString( new
      BufferedReader( new FileReader( f ) ) ) ) &amp;&amp; count &lt; 5
      ) {<br>
      &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // The file failed to write, try 5 times, calling GC
      and sleep between each iteration<br>
      &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Sometimes windows takes a while to release a lock
      on a file&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>
      &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.gc();<br>
      &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; try {<br>
      &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Thread.sleep( 250 );<br>
      &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } catch ( InterruptedException e ) {<br>
      &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; throw new RuntimeException( "This should never
      happen" );<br>
      &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>
      &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; output = new BufferedWriter( new FileWriter( f ) );<br>
      &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; output.write( text );<br>
      &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; output.close();<br>
      &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; count++;<br>
      &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>
      <br>
      &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if ( count == 5 ) {<br>
      &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; throw new IOException( "Unable to write to file:" +
      f.getCanonicalPath() );<br>
      &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>
      &nbsp;&nbsp;&nbsp; }<br>
      <br>
      So far between those things the code is now more robust, it's just
      taking time to move it all across :)<br>
      <br>
      We should probably make separate unit tests specifically for
      ResourceScannerImpl, on it's own separate from the rest of hte
      stack.<br>
      <br>
      Mark<br>
      On 04/12/2010 13:26, Esteban Aliverti wrote:
      <blockquote
        cite="mid:AANLkTik-Q_ioTsei0EXyhBhWGAjJQyjosaKKiJx5Qdf7@mail.gmail.com"
        type="cite">Mark, let me know if you need some help since this
        is one of the task in my (almost eternal) TODO list. You can
        take a look at&nbsp;KnowledgeAgentEventListenerTest.java. Using
        KnowledgeAgentEventListener, you can be notified when the rule
        base is recreated and there is no need to wait for x seconds
        anymore. &nbsp;
        <div> Take a look at the&nbsp;waitUntilChangeSetApplied() method
          there.</div>
        <div><br>
        </div>
        <div>Best,<br clear="all">
          <br>
          XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX<br>
          <br>
          Esteban Aliverti<br>
          - Developer @ <a moz-do-not-send="true"
            href="http://www.plugtree.com" target="_blank">http://www.plugtree.com

          </a><br>
          - Blog @ <a moz-do-not-send="true"
            href="http://ilesteban.wordpress.com" target="_blank">http://ilesteban.wordpress.com</a><br>
          <br>
          <br>
          <div class="gmail_quote">On Sat, Dec 4, 2010 at 6:38 AM, Mark
            Proctor <span dir="ltr">&lt;<a moz-do-not-send="true"
                href="mailto:mproctor@codehaus.org">mproctor@codehaus.org</a>&gt;</span>
            wrote:<br>
            <blockquote class="gmail_quote" style="margin: 0pt 0pt 0pt
              0.8ex; border-left: 1px solid rgb(204, 204, 204);
              padding-left: 1ex;"> The KnowlegeAgent tests have been
              fragile for a while, related to "wait"<br>
              code and file issues, particularly on windows. Something
              has changed<br>
              recently and now they aren't working on the linux hudson
              server either.<br>
              <br>
              So I'm now in the process of refactoring the tests to make
              them more<br>
              robust, and they will hopefully run faster too, as I'll
              use call backs<br>
              when something has finished instead of waiting for X
              seconds in the hope<br>
              that something has finished.<br>
              <br>
              Mark<br>
              <br>
              _______________________________________________<br>
              rules-dev mailing list<br>
              <a moz-do-not-send="true"
                href="mailto:rules-dev@lists.jboss.org">rules-dev@lists.jboss.org</a><br>
              <a moz-do-not-send="true"
                href="https://lists.jboss.org/mailman/listinfo/rules-dev"
                target="_blank">https://lists.jboss.org/mailman/listinfo/rules-dev</a><br>
            </blockquote>
          </div>
          <br>
        </div>
        <pre wrap=""><fieldset class="mimeAttachmentHeader"></fieldset>
_______________________________________________
rules-dev mailing list
<a moz-do-not-send="true" class="moz-txt-link-abbreviated" href="mailto:rules-dev@lists.jboss.org">rules-dev@lists.jboss.org</a>
<a moz-do-not-send="true" class="moz-txt-link-freetext" href="https://lists.jboss.org/mailman/listinfo/rules-dev">https://lists.jboss.org/mailman/listinfo/rules-dev</a>
</pre>
      </blockquote>
      <br>
      <pre wrap="">
<fieldset class="mimeAttachmentHeader"></fieldset>
_______________________________________________
rules-dev mailing list
<a class="moz-txt-link-abbreviated" href="mailto:rules-dev@lists.jboss.org">rules-dev@lists.jboss.org</a>
<a class="moz-txt-link-freetext" href="https://lists.jboss.org/mailman/listinfo/rules-dev">https://lists.jboss.org/mailman/listinfo/rules-dev</a>
</pre>
    </blockquote>
    <br>
  </body>
</html>