Package freenet.node.simulator

Source Code of freenet.node.simulator.LongTermMHKTest

package freenet.node.simulator;

import static java.util.concurrent.TimeUnit.HOURS;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.MalformedURLException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.List;
import java.util.TimeZone;

import freenet.client.ClientMetadata;
import freenet.client.FetchException;
import freenet.client.FetchException.FetchExceptionMode;
import freenet.client.HighLevelSimpleClient;
import freenet.client.InsertBlock;
import freenet.client.InsertException;
import freenet.crypt.RandomSource;
import freenet.keys.FreenetURI;
import freenet.node.Node;
import freenet.node.NodeStarter;
import freenet.node.Version;
import freenet.support.Logger;
import freenet.support.Logger.LogLevel;
import freenet.support.PooledExecutor;
import freenet.support.api.Bucket;
import freenet.support.api.RandomAccessBucket;
import freenet.support.io.Closer;
import freenet.support.io.FileUtil;

/** Simulates MHKs. Creates 4 CHKs, inserts the first one 3 times, and inserts the
* others 1 time each. Pulls them all after 1, 3, 7, 15, 31 etc days and computes
* success rates for the 1 versus the 3 combined. I am convinced the 3 combined will
* be much more successful, but evanbd isn't.
* @author Matthew Toseland <toad@amphibian.dyndns.org> (0xE43DA450)
*
*/
public class LongTermMHKTest extends LongTermTest {
 
  private static final int TEST_SIZE = 64 * 1024;

  private static final int EXIT_DIFFERENT_URI = 262;

  private static final int DARKNET_PORT1 = 5010;
  private static final int OPENNET_PORT1 = 5011;
 
  /** Delta - the number of days we wait before fetching. */
  private static final int DELTA = 7;

  public static void main(String[] args) {
    if (args.length < 1 || args.length > 2) {
      System.err.println("Usage: java freenet.node.simulator.LongTermPushPullTest <unique identifier>");
      System.exit(1);
    }
    String uid = args[0];
   
    boolean dumpOnly = args.length == 2 && "--dump".equalsIgnoreCase(args[1]);
   
    List<String> csvLine = new ArrayList<String>();
    System.out.println("DATE:" + dateFormat.format(today.getTime()));
    csvLine.add(dateFormat.format(today.getTime()));

    System.out.println("Version:" + Version.buildNumber());
    csvLine.add(String.valueOf(Version.buildNumber()));

    int exitCode = 0;
    Node node = null;
    Node node2 = null;
    FileInputStream fis = null;
    File file = new File("mhk-test-"+uid + ".csv");
    long t1, t2;

    HighLevelSimpleClient client = null;
   
    try {
     
      // INSERT STUFF
     
      final File dir = new File("longterm-mhk-test-" + uid);
      if(!dumpOnly) {
      FileUtil.removeAll(dir);
      RandomSource random = NodeStarter.globalTestInit(dir.getPath(), false, LogLevel.ERROR, "", false);
      File seednodes = new File("seednodes.fref");
      if (!seednodes.exists() || seednodes.length() == 0 || !seednodes.canRead()) {
        System.err.println("Unable to read seednodes.fref, it doesn't exist, or is empty");
        System.exit(EXIT_NO_SEEDNODES);
      }

      final File innerDir = new File(dir, Integer.toString(DARKNET_PORT1));
      innerDir.mkdir();
      fis = new FileInputStream(seednodes);
      FileUtil.writeTo(fis, new File(innerDir, "seednodes.fref"));
      fis.close();

      // Create one node
      node = NodeStarter.createTestNode(DARKNET_PORT1, OPENNET_PORT1, dir.getPath(), false, Node.DEFAULT_MAX_HTL,
              0, random, new PooledExecutor(), 1000, 4 * 1024 * 1024, true, true, true, true, true, true, true,
              12 * 1024, true, true, false, false, null);
      Logger.getChain().setThreshold(LogLevel.ERROR);

      // Start it
      node.start(true);
      t1 = System.currentTimeMillis();
      if (!TestUtil.waitForNodes(node)) {
        exitCode = EXIT_FAILED_TARGET;
        return;
      }
       
      t2 = System.currentTimeMillis();
      System.out.println("SEED-TIME:" + (t2 - t1));
      csvLine.add(String.valueOf(t2 - t1));

      // Create four CHKs
     
      RandomAccessBucket single = randomData(node);
      RandomAccessBucket[] mhks = new RandomAccessBucket[3];
     
      for(int i=0;i<mhks.length;i++) mhks[i] = randomData(node);
     
      client = node.clientCore.makeClient((short) 0, false, false);

      System.err.println("Inserting single block 3 times");
     
      InsertBlock block = new InsertBlock(single, new ClientMetadata(), FreenetURI.EMPTY_CHK_URI);
     
      FreenetURI uri = null;
     
      int successes = 0;
     
      for(int i=0;i<3;i++) {
        System.err.println("Inserting single block, try #"+i);
        try {
          t1 = System.currentTimeMillis();
          FreenetURI thisURI = client.insert(block, false, null);
          if(uri != null && !thisURI.equals(uri)) {
            System.err.println("URI "+i+" is "+thisURI+" but previous is "+uri);
            System.exit(EXIT_DIFFERENT_URI);
          }
          uri = thisURI;
          t2 = System.currentTimeMillis();
         
          System.out.println("PUSH-TIME-" + i + ":" + (t2 - t1)+" for "+uri+" for single block");
          csvLine.add(String.valueOf(t2 - t1));
          csvLine.add(uri.toASCIIString());
          successes++;
        } catch (InsertException e) {
          e.printStackTrace();
          csvLine.add(InsertException.getShortMessage(e.getMode()));
          csvLine.add("N/A");
          System.out.println("INSERT FAILED: "+e+" for insert "+i+" for single block");
        }
      }
     
      if(successes == 3)
        System.err.println("All inserts succeeded for single block: "+successes);
      else if(successes != 0)
        System.err.println("Some inserts succeeded for single block: "+successes);
      else
        System.err.println("NO INSERTS SUCCEEDED FOR SINGLE BLOCK: "+successes);
     
      uri = null;
     
      // Insert 3 blocks
     
      for(int i=0;i<3;i++) {
        System.err.println("Inserting MHK #"+i);
        uri = null;
        block = new InsertBlock(mhks[i], new ClientMetadata(), FreenetURI.EMPTY_CHK_URI);
        try {
          t1 = System.currentTimeMillis();
          FreenetURI thisURI = client.insert(block, false, null);
          uri = thisURI;
          t2 = System.currentTimeMillis();
         
          System.out.println("PUSH-TIME-" + i + ":" + (t2 - t1)+" for "+uri+" for MHK #"+i);
          csvLine.add(String.valueOf(t2 - t1));
          csvLine.add(uri.toASCIIString());
          successes++;
        } catch (InsertException e) {
          e.printStackTrace();
          csvLine.add(InsertException.getShortMessage(e.getMode()));
          csvLine.add("N/A");
          System.out.println("INSERT FAILED: "+e+" for MHK #"+i);
        }
      }
     
      if(successes == 3)
        System.err.println("All inserts succeeded for MHK: "+successes);
      else if(successes != 0)
        System.err.println("Some inserts succeeded for MHK: "+successes);
      else
        System.err.println("NO INSERTS SUCCEEDED FOR MHK: "+successes);
     
      uri = null;
      }
     
      // PARSE FILE AND FETCH OLD STUFF IF APPROPRIATE
     
      boolean match = false;
     
      FreenetURI singleURI = null;
      FreenetURI[] mhkURIs = new FreenetURI[3];
      fis = new FileInputStream(file);
      BufferedReader br = new BufferedReader(new InputStreamReader(fis, ENCODING));
      String line = null;
      int linesTooShort = 0, linesBroken = 0, linesNoNumber = 0, linesNoURL = 0, linesNoFetch = 0;
      int total = 0, singleKeysSucceeded = 0, mhkSucceeded = 0;
      int totalSingleKeyFetches = 0, totalSingleKeySuccesses = 0;
      while((line = br.readLine()) != null) {
       
        singleURI = null;
        for(int i=0;i<mhkURIs.length;i++) mhkURIs[i] = null;
        //System.out.println("LINE: "+line);
        String[] split = line.split("!");
        Date date = dateFormat.parse(split[0]);
        GregorianCalendar calendar = new GregorianCalendar(TimeZone.getTimeZone("GMT"));
        calendar.setTime(date);
        System.out.println("Date: "+dateFormat.format(calendar.getTime()));
        GregorianCalendar target = (GregorianCalendar) today.clone();
        target.set(Calendar.HOUR_OF_DAY, 0);
        target.set(Calendar.MINUTE, 0);
        target.set(Calendar.MILLISECOND, 0);
        target.set(Calendar.SECOND, 0);
        target.add(Calendar.DAY_OF_MONTH, -DELTA);
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.MILLISECOND, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.getTime();
        target.getTime();
        try {
          if(split.length < 3) {
            linesTooShort++;
            continue;
          }
          int seedTime = Integer.parseInt(split[2]);
          System.out.println("Seed time: "+seedTime);
         
          int token = 3;
          if(split.length < 4) {
            linesTooShort++;
            continue;
          }
         
          for(int i=0;i<3;i++) {
            int insertTime = Integer.parseInt(split[token]);
            System.out.println("Single key insert "+i+" : "+insertTime);
            token++;
            FreenetURI thisURI = new FreenetURI(split[token]);
            if(singleURI == null)
              singleURI = thisURI;
            else {
              if(!singleURI.equals(thisURI)) {
                System.err.println("URI is not the same for all 3 inserts: was "+singleURI+" but "+i+" is "+thisURI);
                linesBroken++;
                continue;
              }
            }
            token++;
          }
          System.out.println("Single key URI: "+singleURI);
         
          for(int i=0;i<3;i++) {
            int insertTime = Integer.parseInt(split[token]);
            token++;
            mhkURIs[i] = new FreenetURI(split[token]);
            token++;
            System.out.println("MHK #"+i+" URI: "+mhkURIs[i]+" insert time "+insertTime);
          }
         
        } catch (NumberFormatException e) {
          System.err.println("Failed to parse row: "+e);
          linesNoNumber++;
          continue;
        } catch (MalformedURLException e) {
          System.err.println("Failed to parse row: "+e);
          linesNoURL++;
          continue;
        }
        if(Math.abs(target.getTimeInMillis() - calendar.getTimeInMillis()) < HOURS.toMillis(12)) {
          System.out.println("Found row for target date "+dateFormat.format(target.getTime())+" : "+dateFormat.format(calendar.getTime()));
          System.out.println("Version: "+split[1]);
          match = true;
          break;
        } else if(split.length > 3+6+6) {
          int token = 3 + 6 + 6;
          int singleKeyFetchTime = -1;
          boolean singleKeySuccess = false;
          for(int i=0;i<3;i++) {
            // Fetched 3 times
            if(!singleKeySuccess) {
              try {
                singleKeyFetchTime = Integer.parseInt(split[token]);
                singleKeySuccess = true;
                System.out.println("Fetched single key on try "+i+" on "+date+" in "+singleKeyFetchTime+"ms");
              } catch (NumberFormatException e) {
                System.out.println("Failed fetch single key on "+date+" try "+i+" : "+split[token]);
                singleKeyFetchTime = -1;
              }
            } // Else will be empty.
            token++;
          }
          boolean mhkSuccess = false;
          for(int i=0;i<3;i++) {
            totalSingleKeyFetches++;
            int mhkFetchTime = -1;
            try {
              mhkFetchTime = Integer.parseInt(split[token]);
              mhkSuccess = true;
              totalSingleKeySuccesses++;
              System.out.println("Fetched MHK #"+i+" on "+date+" in "+mhkFetchTime+"ms");
            } catch (NumberFormatException e) {
              System.out.println("Failed fetch MHK #"+i+" on "+date+" : "+split[token]);
            }
            token++;
          }
          total++;
          if(singleKeySuccess)
            singleKeysSucceeded++;
          if(mhkSuccess)
            mhkSucceeded++;
        } else linesNoFetch++;
      }
      System.out.println("Lines where insert failed or no fetch: too short: "+linesTooShort+" broken: "+linesBroken+" no number: "+linesNoNumber+" no url: "+linesNoURL+" no fetch "+linesNoFetch);
      System.out.println("Total attempts where insert succeeded and fetch executed: "+total);
      System.out.println("Single keys succeeded: "+singleKeysSucceeded);
      System.out.println("MHKs succeeded: "+mhkSucceeded);
      System.out.println("Single key individual fetches: "+totalSingleKeyFetches);
      System.out.println("Single key individual fetches succeeded: "+totalSingleKeySuccesses);
      System.out.println("Success rate for individual keys (from MHK inserts): "+((double)totalSingleKeySuccesses)/((double)totalSingleKeyFetches));
      System.out.println("Success rate for the single key triple inserted: "+((double)singleKeysSucceeded)/((double)total));
      System.out.println("Success rate for the MHK (success = any of the 3 different keys worked): "+((double)mhkSucceeded)/((double)total));
      fis.close();
      fis = null;
     
      // FETCH STUFF
     
     
      if((!dumpOnly) && match) {
       
        // FETCH SINGLE URI
       
        // Fetch the first one 3 times, since the MHK is 3 fetches also.
        // Technically this is 9 fetches because we multiply by 3 fetches per high-level fetch by default.
       
        boolean fetched = false;
        for(int i=0;i<3;i++) {
          if(fetched) {
            csvLine.add("");
            continue;
          }
          try {
            t1 = System.currentTimeMillis();
            client.fetch(singleURI);
            t2 = System.currentTimeMillis();
           
            System.out.println("PULL-TIME FOR SINGLE URI:" + (t2 - t1));
            csvLine.add(String.valueOf(t2 - t1));
            fetched = true;
          } catch (FetchException e) {
            if (e.getMode() != FetchExceptionMode.ALL_DATA_NOT_FOUND
                && e.getMode() != FetchExceptionMode.DATA_NOT_FOUND)
              e.printStackTrace();
            csvLine.add(FetchException.getShortMessage(e.getMode()));
            System.err.println("FAILED PULL FOR SINGLE URI: "+e);
          }
        }
       
        for(int i=0;i<mhkURIs.length;i++) {
          try {
            t1 = System.currentTimeMillis();
            client.fetch(mhkURIs[i]);
            t2 = System.currentTimeMillis();
           
            System.out.println("PULL-TIME FOR MHK #"+i+":" + (t2 - t1));
            csvLine.add(String.valueOf(t2 - t1));
          } catch (FetchException e) {
            if (e.getMode() != FetchExceptionMode.ALL_DATA_NOT_FOUND
                && e.getMode() != FetchExceptionMode.DATA_NOT_FOUND)
              e.printStackTrace();
            csvLine.add(FetchException.getShortMessage(e.getMode()));
            System.err.println("FAILED PULL FOR MHK #"+i+": "+e);
          }
        }
      }
     
    } catch (Throwable t) {
      t.printStackTrace();
      exitCode = EXIT_THREW_SOMETHING;
    } finally {
      try {
        if (node != null)
          node.park();
      } catch (Throwable tt) {
      }
      try {
        if (node2 != null)
          node2.park();
      } catch (Throwable tt) {
      }
      Closer.close(fis);

      if(!dumpOnly) {
        writeToStatusLog(file, csvLine);
      }
      System.exit(exitCode);
    }
  } 
 
  private static RandomAccessBucket randomData(Node node) throws IOException {
      RandomAccessBucket data = node.clientCore.tempBucketFactory.makeBucket(TEST_SIZE);
    OutputStream os = data.getOutputStream();
    try {
    byte[] buf = new byte[4096];
    for (long written = 0; written < TEST_SIZE;) {
      node.fastWeakRandom.nextBytes(buf);
      int toWrite = (int) Math.min(TEST_SIZE - written, buf.length);
      os.write(buf, 0, toWrite);
      written += toWrite;
    }
    } finally {
    os.close();
    }
    return data;
  }

}
TOP

Related Classes of freenet.node.simulator.LongTermMHKTest

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.