Package org.syncany.tests.database

Source Code of org.syncany.tests.database.DatabaseReconciliatorTest$TestResult

/*
* Syncany, www.syncany.org
* Copyright (C) 2011-2014 Philipp C. Heckel <philipp.heckel@gmail.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/
package org.syncany.tests.database;

import static org.junit.Assert.assertEquals;

import java.util.Map;
import java.util.TreeMap;

import org.junit.Test;
import org.syncany.database.DatabaseVersionHeader;
import org.syncany.operations.down.DatabaseBranch;
import org.syncany.operations.down.DatabaseBranches;
import org.syncany.operations.down.DatabaseReconciliator;
import org.syncany.tests.util.TestDatabaseUtil;

public class DatabaseReconciliatorTest
  @Test
  public void testUpdateDetectorConflict1AtMachineB() throws Exception
    System.out.println("CONFLICT 1");
    System.out.println("----------------");
   
    /// Input data ///
    String localMachineName = "B";
    DatabaseVersionHeader currentLocalVersion = null;
    DatabaseBranches allBranches = new DatabaseBranches();
    
    // A
    allBranches.put("A", TestDatabaseUtil.createBranch(new String[] {
      "A/(A1,C4)/T=8",
      "A/(A2,C4)/T=9",
      "A/(A3,C4)/T=10"               
    }));
   
    // B
    allBranches.put("B", TestDatabaseUtil.createBranch(new String[] {
      "C/(C1)/T=1",
      "C/(C2)/T=2",
      "C/(C3)/T=3",       
      "B/(B1,C3)/T=7"               
    }));
   
    // C
    allBranches.put("C", TestDatabaseUtil.createBranch(new String[] {
      "C/(C4)/T=5"
    }));   
       
    /// Expected results ///
    TestResult expectedTestResult = new TestResult();
   
    expectedTestResult.lastCommonHeader = TestDatabaseUtil.createFromString("C/(C3)/T=3");
    expectedTestResult.firstConflictingDatabaseVersionHeaders = TestDatabaseUtil.createMapWithMachineKey(new String[] {
      "A", "C/(C4)/T=5",
      "B", "B/(B1,C3)/T=7",
      "C", "C/(C4)/T=5"     
    });   
    expectedTestResult.winningFirstConflictingDatabaseVersionHeaders = TestDatabaseUtil.createMapWithMachineKey(new String[] {
      "A", "C/(C4)/T=5",
      "C", "C/(C4)/T=5"   
    });
    expectedTestResult.winnersWinnersLastDatabaseVersionHeader = TestDatabaseUtil.createMapWithMachineKey(new String[] {
      "A", "A/(A3,C4)/T=10"
    }).firstEntry();
       
    /// Perform test ///
    testFromMachinePerspective(localMachineName, currentLocalVersion, allBranches, expectedTestResult);
  }     
 
  @Test
  public void testUpdateDetectorConflict2AtMachineA() throws Exception
    System.out.println("CONFLICT 2");
    System.out.println("----------------");
   
    /// Input data ///
    String localMachineName = "A";

    DatabaseVersionHeader currentLocalVersion = null;
    DatabaseBranches allBranches = new DatabaseBranches();
   
    // A
    allBranches.put("A", TestDatabaseUtil.createBranch(new String[] {
      "C/(C1)/T=1",
      "C/(C2)/T=2",
      "C/(C3)/T=3",
      "C/(C4)/T=5",
      "A/(A1,C4)/T=8",
      "A/(A2,C4)/T=9",
      "A/(A3,C4)/T=10"               
    }));
   
    // B
    allBranches.put("B", TestDatabaseUtil.createBranch(new String[] {
      "B/(B1,C3)/T=7"               
    }));
       
    /// Expected results ///
    TestResult expectedTestResult = new TestResult();
   
    expectedTestResult.lastCommonHeader = TestDatabaseUtil.createFromString("C/(C3)/T=3");
    expectedTestResult.firstConflictingDatabaseVersionHeaders = TestDatabaseUtil.createMapWithMachineKey(new String[] {
      "A", "C/(C4)/T=5",
      "B", "B/(B1,C3)/T=7"
    });   
    expectedTestResult.winningFirstConflictingDatabaseVersionHeaders = TestDatabaseUtil.createMapWithMachineKey(new String[] {
      "A", "C/(C4)/T=5"
    });
    expectedTestResult.winnersWinnersLastDatabaseVersionHeader = TestDatabaseUtil.createMapWithMachineKey(new String[] {
      "A", "A/(A3,C4)/T=10"
    }).firstEntry();
       
    /// Perform test ///
    testFromMachinePerspective(localMachineName, currentLocalVersion, allBranches, expectedTestResult);
 
 
  @Test
  public void testUpdateDetectorConflict3AtMachineC() throws Exception
    System.out.println("CONFLICT 3");
    System.out.println("----------------");
   
    /// Input data ///
    String localMachineName = "C";

    DatabaseVersionHeader currentLocalVersion = null;
    DatabaseBranches allBranches = new DatabaseBranches();
   
    // A
    allBranches.put("A", TestDatabaseUtil.createBranch(new String[] {
      "A/(A1,C4)/T=8",
      "A/(A2,C4)/T=9",
      "A/(A3,C4)/T=10"               
    }));
   
    // B
    allBranches.put("B", TestDatabaseUtil.createBranch(new String[] {     
      "B/(B1,C3)/T=7"               
    }));
   
    // C
    allBranches.put("C", TestDatabaseUtil.createBranch(new String[] {
      "C/(C1)/T=1",
      "C/(C2)/T=2",
      "C/(C3)/T=3",       
      "C/(C4)/T=5"
    }));   

    /// Expected results ///x
    TestResult expectedTestResult = new TestResult();
   
    expectedTestResult.lastCommonHeader = TestDatabaseUtil.createFromString("C/(C3)/T=3");
    expectedTestResult.firstConflictingDatabaseVersionHeaders = TestDatabaseUtil.createMapWithMachineKey(new String[] {
      "A", "C/(C4)/T=5",
      "B", "B/(B1,C3)/T=7",
      "C", "C/(C4)/T=5"
    });   
    expectedTestResult.winningFirstConflictingDatabaseVersionHeaders = TestDatabaseUtil.createMapWithMachineKey(new String[] {
      "A", "C/(C4)/T=5",
      "C", "C/(C4)/T=5"
    });
    expectedTestResult.winnersWinnersLastDatabaseVersionHeader = TestDatabaseUtil.createMapWithMachineKey(new String[] {
      "A", "A/(A3,C4)/T=10"
    }).firstEntry();
       
    /// Perform test ///
    testFromMachinePerspective(localMachineName, currentLocalVersion, allBranches, expectedTestResult);
  }     
 
  @Test
  public void testUpdateDetectorConflict4AtMachineB() throws Exception
    System.out.println("CONFLICT 4");
    System.out.println("----------------");
   
    /// Input data ///
    String localMachineName = "B";

    DatabaseVersionHeader currentLocalVersion = null;
    DatabaseBranches allBranches = new DatabaseBranches();
   
    // A
    allBranches.put("A", TestDatabaseUtil.createBranch(new String[] {
      "A/(A4,C4)/T=11",
      "A/(A5,C4)/T=12", // db-a-5
      "A/(A6,C4)/T=19", // db-a-6
    }));
   
    // B
    allBranches.put("B", TestDatabaseUtil.createBranch(new String[] {     
      "C/(C1)/T=1",
      "C/(C2)/T=2",
      "C/(C3)/T=3",       
      "C/(C4)/T=5",
      "A/(A1,C4)/T=8",
      "A/(A2,C4)/T=9",
      "A/(A3,C4)/T=10",
      "B/(A3,B2,C4)/T=16",
      "B/(A3,B3,C4)/T=17",
      "B/(A3,B4,C4)/T=18",
      "B/(A3,B5,C4)/T=20",
    }));
   
    // C
    allBranches.put("C", TestDatabaseUtil.createBranch(new String[] {
      "C/(A3,C5)/T=13", // db-c-5
      "C/(A3,C6)/T=14",
      "C/(A3,C7)/T=15", // db-c-7
      "C/(A3,C8)/T=21", // db-c-8
    }));   

    /// Expected results ///
    TestResult expectedTestResult = new TestResult();
   
    expectedTestResult.lastCommonHeader = TestDatabaseUtil.createFromString("A/(A3,C4)/T=10");
    expectedTestResult.firstConflictingDatabaseVersionHeaders = TestDatabaseUtil.createMapWithMachineKey(new String[] {
      "A", "A/(A4,C4)/T=11",
      "B", "B/(A3,B2,C4)/T=16",
      "C", "C/(A3,C5)/T=13"
    });   
    expectedTestResult.winningFirstConflictingDatabaseVersionHeaders = TestDatabaseUtil.createMapWithMachineKey(new String[] {
      "A", "A/(A4,C4)/T=11"
    });
    expectedTestResult.winnersWinnersLastDatabaseVersionHeader = TestDatabaseUtil.createMapWithMachineKey(new String[] {
      "A", "A/(A6,C4)/T=19"
    }).firstEntry();
       
    /// Perform test ///
    testFromMachinePerspective(localMachineName, currentLocalVersion, allBranches, expectedTestResult);
  }     
 
  @Test
  public void testUpdateDetectorConflict5AtMachineA() throws Exception
    System.out.println("CONFLICT 5");
    System.out.println("----------------");
   
    /// Input data ///
    String localMachineName = "A";

    DatabaseVersionHeader currentLocalVersion = null;
    DatabaseBranches allBranches = new DatabaseBranches();
   
    // A
    allBranches.put("A", TestDatabaseUtil.createBranch(new String[] {
      "C/(C1)/T=1",
      "C/(C2)/T=2",
      "C/(C3)/T=3",       
      "C/(C4)/T=5",
      "A/(A1,C4)/T=8",
      "A/(A2,C4)/T=9",
      "A/(A3,C4)/T=10",
      "A/(A4,C4)/T=11",
      "A/(A5,C4)/T=12",
      "A/(A6,C4)/T=19",
    }));
   
    // B
    allBranches.put("B", TestDatabaseUtil.createBranch(new String[] {     
      "B/(A3,B2,C4)/T=16",
      "B/(A3,B3,C4)/T=17",
      "B/(A3,B4,C4)/T=18", // db-b-4
      "B/(A3,B5,C4)/T=20", // db-b-5
    }));
   
    // C
    allBranches.put("C", TestDatabaseUtil.createBranch(new String[] {
      "C/(A3,C5)/T=13", // db-c-5
      "C/(A3,C6)/T=14",
      "C/(A3,C7)/T=15", // db-c-7
      "C/(A3,C8)/T=21", // db-c-8
    }));   

    /// Expected results ///
    TestResult expectedTestResult = new TestResult();
   
    expectedTestResult.lastCommonHeader = TestDatabaseUtil.createFromString("A/(A3,C4)/T=10");
    expectedTestResult.firstConflictingDatabaseVersionHeaders = TestDatabaseUtil.createMapWithMachineKey(new String[] {
      "A", "A/(A4,C4)/T=11",
      "B", "B/(A3,B2,C4)/T=16",
      "C", "C/(A3,C5)/T=13"
    });   
    expectedTestResult.winningFirstConflictingDatabaseVersionHeaders = TestDatabaseUtil.createMapWithMachineKey(new String[] {
      "A", "A/(A4,C4)/T=11"
    });
    expectedTestResult.winnersWinnersLastDatabaseVersionHeader = TestDatabaseUtil.createMapWithMachineKey(new String[] {
      "A", "A/(A6,C4)/T=19"
    }).firstEntry();   
       
    /// Perform test ///
    testFromMachinePerspective(localMachineName, currentLocalVersion, allBranches, expectedTestResult);
  }       
 
  @Test
  public void testUpdateDetectorConflict6AtMachineC() throws Exception
    System.out.println("CONFLICT 6");
    System.out.println("----------------");
   
    /// Input data ///
    String localMachineName = "C";

    DatabaseVersionHeader currentLocalVersion = null;
    DatabaseBranches allBranches = new DatabaseBranches();
   
    // A
    allBranches.put("A", TestDatabaseUtil.createBranch(new String[] {
      "A/(A4,C4)/T=11",
      "A/(A5,C4)/T=12", // db-a-5
      "A/(A6,C4)/T=19", // db-a-6
    }));
   
    // B
    allBranches.put("B", TestDatabaseUtil.createBranch(new String[] {     
      "B/(A3,B2,C4)/T=16",
      "B/(A3,B3,C4)/T=17",
      "B/(A3,B4,C4)/T=18", // db-b-4
      "B/(A3,B5,C4)/T=20", // db-b-5
    }));
   
    // C
    allBranches.put("C", TestDatabaseUtil.createBranch(new String[] {
      "C/(C1)/T=1",
      "C/(C2)/T=2",
      "C/(C3)/T=3",       
      "C/(C4)/T=5",
      "A/(A1,C4)/T=8",
      "A/(A2,C4)/T=9",
      "A/(A3,C4)/T=10",       
      "C/(A3,C5)/T=13",
      "C/(A3,C6)/T=14",
      "C/(A3,C7)/T=15",
      "C/(A3,C8)/T=21",
    }));   

    /// Expected results ///
    TestResult expectedTestResult = new TestResult();
   
    expectedTestResult.lastCommonHeader = TestDatabaseUtil.createFromString("A/(A3,C4)/T=10");
    expectedTestResult.firstConflictingDatabaseVersionHeaders = TestDatabaseUtil.createMapWithMachineKey(new String[] {
      "A", "A/(A4,C4)/T=11",
      "B", "B/(A3,B2,C4)/T=16",
      "C", "C/(A3,C5)/T=13"
    });   
    expectedTestResult.winningFirstConflictingDatabaseVersionHeaders = TestDatabaseUtil.createMapWithMachineKey(new String[] {
      "A", "A/(A4,C4)/T=11"
    });
    expectedTestResult.winnersWinnersLastDatabaseVersionHeader = TestDatabaseUtil.createMapWithMachineKey(new String[] {
      "A", "A/(A6,C4)/T=19"
    }).firstEntry();   
       
    /// Perform test ///
    testFromMachinePerspective(localMachineName, currentLocalVersion, allBranches, expectedTestResult);
  }       
 
  @Test
  public void testUpdateDetectorConflict7AtMachineC() throws Exception
    System.out.println("CONFLICT 7");
    System.out.println("----------------");
   
    /// Input data ///
    String localMachineName = "C";
   
    DatabaseVersionHeader currentLocalVersion = null;

    DatabaseBranches allBranches = new DatabaseBranches();
   
    // B
    allBranches.put("B", TestDatabaseUtil.createBranch(new String[] {
      // TODO [lowest] Fix pruning of machine histories -- Is this still an issue?
      // Explanation: Note, this is the full 'B' history, but it does not include
      // the 'pruned' histories or invalid parts of pruned histories.
      // Here: db-b-1 is completely invalid! In other cases, only parts of
      // an old history might be invalid!
       
      "C/(C1)/T=1",
      "C/(C2)/T=2",
      "C/(C3)/T=3",       
      "C/(C4)/T=5",
      "A/(A1,C4)/T=8",
      "A/(A2,C4)/T=9",
      "A/(A3,C4)/T=10",
      "A/(A3,B2,C4)/T=16",
      "A/(A3,B3,C4)/T=17",
      "A/(A3,B4,C4)/T=18", // db-b-4
      "A/(A3,B5,C4)/T=20", // db-b-5
      "B/(A3,B6,C4)/T=23", // db-b-6     
    }));
   
    // C
    allBranches.put("C", TestDatabaseUtil.createBranch(new String[] {
      "C/(C1)/T=1",
      "C/(C2)/T=2",
      "C/(C3)/T=3",       
      "C/(C4)/T=5",
      "A/(A1,C4)/T=8",
      "A/(A2,C4)/T=9",
      "A/(A3,C4)/T=10"
      "A/(A4,C4)/T=11",
      "A/(A5,C4)/T=12",
      "A/(A6,C4)/T=19",      
      "C/(A6,C9)/T=22",
    }));   

    /// Expected results ///
    TestResult expectedTestResult = new TestResult();
   
    expectedTestResult.lastCommonHeader = TestDatabaseUtil.createFromString("A/(A3,C4)/T=10");
    expectedTestResult.firstConflictingDatabaseVersionHeaders = TestDatabaseUtil.createMapWithMachineKey(new String[] {
      "B", "A/(A3,B2,C4)/T=16",
      "C", "A/(A4,C4)/T=11"
    });   
    expectedTestResult.winningFirstConflictingDatabaseVersionHeaders = TestDatabaseUtil.createMapWithMachineKey(new String[] {
      "C", "A/(A4,C4)/T=11"
    });
    expectedTestResult.winnersWinnersLastDatabaseVersionHeader = TestDatabaseUtil.createMapWithMachineKey(new String[] {
      "C", "C/(A6,C9)/T=22"
    }).firstEntry();   
       
    /// Perform test ///
    testFromMachinePerspective(localMachineName, currentLocalVersion, allBranches, expectedTestResult);
  }       
 
  @Test
  public void testWinnersWinner() throws Exception {
    System.out.println("Winners winner test");
    System.out.println("----------------");
   
    /// Input data ///
    String localMachineName = "B";
    DatabaseVersionHeader currentLocalVersion = TestDatabaseUtil.createFromString("A/(A1,C4)/T=8");
    DatabaseBranches allBranches = new DatabaseBranches();
   
    // A
    allBranches.put("A", TestDatabaseUtil.createBranch(new String[] {     
      "A/(A1,C4)/T=8",     // last common
      "A/(A2,C4)/T=9",     // first conflicting, wins
     
      "A/(A3,C4)/T=10",    // same as in B
      "A/(A4,C4)/T=11",    // second conflict, wins, winners winner
      "A/(A5,C4)/T=15"     // <<---- WINNERS WINNERS LAST DBV
    }));
   
    // B
    allBranches.put("B", TestDatabaseUtil.createBranch(new String[] {
      "B/(A3,B1,C4)/T=12", // second conflict, loses = winners loser
      "B/(A3,B2,C4)/T=14"   
    }));
   
    // C
    allBranches.put("C", TestDatabaseUtil.createBranch(new String[] {
      "C/(C1)/T=1",
      "C/(C2)/T=2",
      "C/(C3)/T=3",   
      "C/(C4)/T=4",   
      "C/(A1,C5)/T=10", // first conflicting, loses
    }));   
       
    /// Expected results ///
    TestResult expectedTestResult = new TestResult();
   
    expectedTestResult.lastCommonHeader = TestDatabaseUtil.createFromString("A/(A1,C4)/T=8");
    expectedTestResult.firstConflictingDatabaseVersionHeaders = TestDatabaseUtil.createMapWithMachineKey(new String[] {
      "A", "A/(A2,C4)/T=9",
      "B", "A/(A2,C4)/T=9",
      "C", "C/(A1,C5)/T=10"     
    });   
    expectedTestResult.winningFirstConflictingDatabaseVersionHeaders = TestDatabaseUtil.createMapWithMachineKey(new String[] {
      "A", "A/(A2,C4)/T=9",
      "B", "A/(A2,C4)/T=9",
    });   
    expectedTestResult.winnersWinnersLastDatabaseVersionHeader = TestDatabaseUtil.createMapWithMachineKey(new String[] {
      "A", "A/(A5,C4)/T=15"
    }).firstEntry();
       
    /// Perform test ///
    testFromMachinePerspective(localMachineName, currentLocalVersion, allBranches, expectedTestResult);
  }     
 
  @Test
  public void testWinningBranch() throws Exception
    System.out.println("Winners winner test");
    System.out.println("----------------");
   
    /// Input data ///
    String localMachineName = "D";
    DatabaseVersionHeader currentLocalVersion = TestDatabaseUtil.createFromString("A/(A1,C4)/T=8");
    DatabaseBranches allBranches = new DatabaseBranches();
   
    // A
    allBranches.put("A", TestDatabaseUtil.createBranch(new String[] {
      "A/(A2,C4)/T=9",     // first conflicting, wins
     
      "A/(A3,C4)/T=10",    // same as in B
      "A/(A4,C4)/T=11",    // second conflict, wins, winners winner
      "A/(A5,B1,C4)/T=14"     // <<---- WINNERS WINNERS LAST DBV
    }));
   
    // B
    allBranches.put("B", TestDatabaseUtil.createBranch(new String[] {
      "B/(A4,B1,C4)/T=12", // second conflict, loses = winners loser
      "B/(A4,B2,C4)/T=15"   
    }));
   
    // C
    allBranches.put("C", TestDatabaseUtil.createBranch(new String[] { 
      "C/(A1,C5)/T=10", // first conflicting, loses
    }));   
   
    allBranches.put("D", TestDatabaseUtil.createBranch(new String[] { 
        "C/(C1)/T=1",
        "C/(C2)/T=2",
        "C/(C3)/T=3"
        "C/(C4)/T=4"
        "A/(A1,C4)/T=8",     // last common - current DBV in B!
//        "A/(A2,C4)/T=9",     // new from here -> first conflicting, wins
//       
//        "A/(A3,C4)/T=10",    // same as in A
//        "B/(A4,B1,C4)/T=12", // second conflict, loses = winners loser
//        "B/(A4,B2,C4)/T=15"   
      }));   
       
    /// Expected results ///
    TestResult expectedTestResult = new TestResult();
   
    expectedTestResult.lastCommonHeader = TestDatabaseUtil.createFromString("A/(A1,C4)/T=8");
    expectedTestResult.firstConflictingDatabaseVersionHeaders = TestDatabaseUtil.createMapWithMachineKey(new String[] {
      "A", "A/(A2,C4)/T=9",
      "B", "A/(A2,C4)/T=9",
      "C", "C/(A1,C5)/T=10"     
    });   
    expectedTestResult.winningFirstConflictingDatabaseVersionHeaders = TestDatabaseUtil.createMapWithMachineKey(new String[] {
      "A", "A/(A2,C4)/T=9",
      "B", "A/(A2,C4)/T=9",
    });   
    expectedTestResult.winnersWinnersLastDatabaseVersionHeader = TestDatabaseUtil.createMapWithMachineKey(new String[] {
      "A", "A/(A5,B1,C4)/T=14"
    }).firstEntry();
       
    /// Perform test ///
    testFromMachinePerspective(localMachineName, currentLocalVersion, allBranches, expectedTestResult);
  }   
 
  @Test
  public void testOneLocalVersionDetermineLastCommon() throws Exception {
   
    /* Scenario: The local machine ("C") has only one local database version
     */
   
    /// Input data ///
    String localMachineName = "C";
    DatabaseVersionHeader currentLocalVersion = TestDatabaseUtil.createFromString("A/(A1)/T=1376074225169");
    DatabaseBranches allBranches = new DatabaseBranches();

    allBranches.put("A", TestDatabaseUtil.createBranch(new String[] {
      "A/(A1)/T=1376074225169",
      "A/(A2)/T=1376074225230",
    }));
   
    allBranches.put("C", TestDatabaseUtil.createBranch(new String[] {
      "A/(A1)/T=1376074225169",
    }));
       
    /// Expected results ///
    TestResult expectedTestResult = new TestResult();
   
    expectedTestResult.lastCommonHeader = TestDatabaseUtil.createFromString("A/(A1)/T=1376074225169");
    expectedTestResult.firstConflictingDatabaseVersionHeaders = TestDatabaseUtil.createMapWithMachineKey(new String[] {
      "A", "A/(A2)/T=1376074225230",
    });   
    expectedTestResult.winningFirstConflictingDatabaseVersionHeaders = TestDatabaseUtil.createMapWithMachineKey(new String[] {
      "A", "A/(A2)/T=1376074225230",
    });   
    expectedTestResult.winnersWinnersLastDatabaseVersionHeader = TestDatabaseUtil.createMapWithMachineKey(new String[] {
      "A", "A/(A2)/T=1376074225230"
    }).firstEntry();
       
    /// Perform test ///
    testFromMachinePerspective(localMachineName, currentLocalVersion, allBranches, expectedTestResult);
  }     
 
  @Test
  public void testTwoWinningVersionsWithSameTimestamp() throws Exception {
    /* Scenario: Three clients, to conflicting DBVs with the same timestamp
     *           --> A should win over B (alphabetical order)
     */
   
    /// Input data ///
    String localMachineName = "C";
    DatabaseVersionHeader currentLocalVersion = TestDatabaseUtil.createFromString("A/(A2)/T=1376074225230");
    DatabaseBranches allBranches = new DatabaseBranches();

    allBranches.put("A", TestDatabaseUtil.createBranch(new String[] {
      "A/(A1)/T=1376074225169",
      "A/(A2)/T=1376074225230",
      "A/(A3)/T=1376074225256",

      // Conflicts with A -> A3,B1; also: SAME timestamp!
      "A/(A4)/T=9999999999999",
    }));
   
    allBranches.put("B", TestDatabaseUtil.createBranch(new String[] {
      // Conflicts with B -> A4; also: SAME timestamp!
      "B/(A3,B1)/T=9999999999999"
    }));
   
    allBranches.put("C", TestDatabaseUtil.createBranch(new String[] {
      "A/(A1)/T=1376074225169",
      "A/(A2)/T=1376074225230",
    }));
       
    /// Expected results ///
    TestResult expectedTestResult = new TestResult();
   
    expectedTestResult.lastCommonHeader = TestDatabaseUtil.createFromString("A/(A2)/T=1376074225230");
    expectedTestResult.firstConflictingDatabaseVersionHeaders = TestDatabaseUtil.createMapWithMachineKey(new String[] {
      "A", "A/(A3)/T=1376074225256",
      "B", "A/(A3)/T=1376074225256",
    });   
    expectedTestResult.winningFirstConflictingDatabaseVersionHeaders = TestDatabaseUtil.createMapWithMachineKey(new String[] {
      "A", "A/(A3)/T=1376074225256",
      "B", "A/(A3)/T=1376074225256",
    });   
    expectedTestResult.winnersWinnersLastDatabaseVersionHeader = TestDatabaseUtil.createMapWithMachineKey(new String[] {
      "A", "A/(A4)/T=9999999999999"
    }).firstEntry();
       
    /// Perform test ///
    testFromMachinePerspective(localMachineName, currentLocalVersion, allBranches, expectedTestResult);
  }     

  @Test
  public void testStitchBranches() throws Exception {
    DatabaseBranches allBranches = new DatabaseBranches();
   
    allBranches.put("A", TestDatabaseUtil.createBranch(new String[] {
      "A/(A1)/T=1376074225169",
      "A/(A2)/T=1376074225230",
      "A/(A3)/T=1376074225256",
    }));
   
    allBranches.put("B", TestDatabaseUtil.createBranch(new String[] {
      "B/(A3,B1)/T=1376074225356"
    }));
   
    allBranches.put("C", TestDatabaseUtil.createBranch(new String[] {
      "C/(C1)/T=1376074225383",
      "C/(C2)/T=1376074225399",
      "C/(C3)/T=1376074225416",
    }));   
   
    DatabaseReconciliator databaseVersionUpdateDetector = new DatabaseReconciliator();
    DatabaseBranches actualStitchedRemoteBranches = databaseVersionUpdateDetector.stitchBranches(allBranches, "D", new DatabaseBranch());
   
    DatabaseBranches expectedStitchedBranches = new DatabaseBranches();
   
    expectedStitchedBranches.put("A", TestDatabaseUtil.createBranch(new String[] {
      "A/(A1)/T=1376074225169",
      "A/(A2)/T=1376074225230",
      "A/(A3)/T=1376074225256",
    }));
   
    expectedStitchedBranches.put("B", TestDatabaseUtil.createBranch(new String[] {
      "A/(A1)/T=1376074225169",
      "A/(A2)/T=1376074225230",
      "A/(A3)/T=1376074225256",
      "B/(A3,B1)/T=1376074225356"
    }));
   
    expectedStitchedBranches.put("C", TestDatabaseUtil.createBranch(new String[] {
      "C/(C1)/T=1376074225383",
      "C/(C2)/T=1376074225399",
      "C/(C3)/T=1376074225416",
    }));
   
    assertEquals("Stitched branches not equal.", expectedStitchedBranches.toString(), actualStitchedRemoteBranches.toString());
  }
 
  @Test
  public void testStitchBranches2() throws Exception {   
    DatabaseBranches allBranches = new DatabaseBranches();
   
    allBranches.put("A", TestDatabaseUtil.createBranch(new String[] {
      "A/(A1)/T=1",
      "A/(A2)/T=2",
      // --> B
      "A/(A3,B1)/T=4",
      "A/(A4,B1)/T=5",
      "A/(A5,B1)/T=6",
      // --> C
     
    }));
   
    allBranches.put("B", TestDatabaseUtil.createBranch(new String[] {
      "B/(A2,B1)/T=3",
      // --> A
      "B/(A5,B2,C2)/T=9",
      // --> C
    }));
   
    allBranches.put("C", TestDatabaseUtil.createBranch(new String[] {
      "C/(A5,B1,C1)/T=7",
      "C/(A5,B1,C2)/T=8",
      // --> B
      "C/(A5,B2,C3)/T=10",
    }));   
   
    DatabaseReconciliator databaseVersionUpdateDetector = new DatabaseReconciliator();
    DatabaseBranches actualStitchedRemoteBranches = databaseVersionUpdateDetector.stitchBranches(allBranches, "D", new DatabaseBranch());
   
    DatabaseBranches expectedStitchedBranches = new DatabaseBranches();
   
    expectedStitchedBranches.put("A", TestDatabaseUtil.createBranch(new String[] {
        "A/(A1)/T=1",
        "A/(A2)/T=2",
        "B/(A2,B1)/T=3",
        "A/(A3,B1)/T=4",
        "A/(A4,B1)/T=5",
        "A/(A5,B1)/T=6",
    }));
   
    expectedStitchedBranches.put("B", TestDatabaseUtil.createBranch(new String[] {
        "A/(A1)/T=1",
        "A/(A2)/T=2",
        "B/(A2,B1)/T=3",
        "A/(A3,B1)/T=4",
        "A/(A4,B1)/T=5",
        "A/(A5,B1)/T=6",
        "C/(A5,B1,C1)/T=7",
        "C/(A5,B1,C2)/T=8",
        "B/(A5,B2,C2)/T=9",
    }));
   
    expectedStitchedBranches.put("C", TestDatabaseUtil.createBranch(new String[] {
        "A/(A1)/T=1",
        "A/(A2)/T=2",
        "B/(A2,B1)/T=3",
        "A/(A3,B1)/T=4",
        "A/(A4,B1)/T=5",
        "A/(A5,B1)/T=6",
        "C/(A5,B1,C1)/T=7",
        "C/(A5,B1,C2)/T=8",
        "B/(A5,B2,C2)/T=9",
        "C/(A5,B2,C3)/T=10",
    }));
   
    assertEquals("Stitched branches not equal.", expectedStitchedBranches.toString(), actualStitchedRemoteBranches.toString());
  }   

  private void testFromMachinePerspective(String localMachineName, DatabaseVersionHeader currentLocalVersion, DatabaseBranches allBranches, TestResult expectedTestResult) throws Exception {
    // Print them all
    System.out.println("testFromMachinePerspective('"+localMachineName+"') with database version headers:");
   
    printBranches(allBranches);
     
 
    System.out.println("----------");
   
    DatabaseReconciliator databaseReconciliator = new DatabaseReconciliator();
    TestResult actualTestResult = new TestResult();
   
    // Get 'local' branch
    DatabaseBranch localBranch = allBranches.getBranch(localMachineName);
   
    // Get all the other ones (clone 'all', and remove local)
    DatabaseBranches unstitchedRemoteBranches = allBranches.clone();
    unstitchedRemoteBranches.remove(localMachineName);

    DatabaseBranches stitchedRemoteBranches = databaseReconciliator.stitchBranches(unstitchedRemoteBranches, localMachineName, localBranch);
   
    System.out.println("Before Orchestration : Remote");
    printBranches(unstitchedRemoteBranches);
    System.out.println("Before Orchestration : Local");
    printBranch(localBranch);
    System.out.println("BEGIN Branch Orchestration!! ----------");
    printBranches(stitchedRemoteBranches);       
    System.out.println("END Branch Orchestration ----------");
       
    actualTestResult.lastCommonHeader = databaseReconciliator.findLastCommonDatabaseVersionHeader(localBranch, stitchedRemoteBranches);
    actualTestResult.firstConflictingDatabaseVersionHeaders = databaseReconciliator.findFirstConflictingDatabaseVersionHeader(actualTestResult.lastCommonHeader, stitchedRemoteBranches);
    actualTestResult.winningFirstConflictingDatabaseVersionHeaders = databaseReconciliator.findWinningFirstConflictingDatabaseVersionHeaders(actualTestResult.firstConflictingDatabaseVersionHeaders);
    actualTestResult.winnersWinnersLastDatabaseVersionHeader = databaseReconciliator.findWinnersLastDatabaseVersionHeader(actualTestResult.winningFirstConflictingDatabaseVersionHeaders, stitchedRemoteBranches);
   
    System.out.println("Actual lastCommonDatabaseVersionHeader = " +actualTestResult.lastCommonHeader);
    System.out.println("Expect lastCommonDatabaseVersionHeader = " +expectedTestResult.lastCommonHeader);

    System.out.println("Actual firstConflictingDatabaseVersionHeaders = "); printMap(actualTestResult.firstConflictingDatabaseVersionHeaders);
    System.out.println("Expect firstConflictingDatabaseVersionHeaders = "); printMap(expectedTestResult.firstConflictingDatabaseVersionHeaders);

    System.out.println("Actual winningFirstConflictingDatabaseVersionHeaders = "); printMap(actualTestResult.winningFirstConflictingDatabaseVersionHeaders);
    System.out.println("Expect winningFirstConflictingDatabaseVersionHeaders = "); printMap(expectedTestResult.winningFirstConflictingDatabaseVersionHeaders);
   
    System.out.println("Actual winnersWinnersLastDatabaseVersionHeader = " + actualTestResult.winnersWinnersLastDatabaseVersionHeader);
    System.out.println("Expect winnersWinnersLastDatabaseVersionHeader = " + expectedTestResult.winnersWinnersLastDatabaseVersionHeader);

    assertEquals("Different last common database version header expected", expectedTestResult.lastCommonHeader, actualTestResult.lastCommonHeader);
    assertEquals("Different first conflicting versions expected", expectedTestResult.firstConflictingDatabaseVersionHeaders, actualTestResult.firstConflictingDatabaseVersionHeaders);
    assertEquals("Different winning first conflicting versions expected", expectedTestResult.winningFirstConflictingDatabaseVersionHeaders, actualTestResult.winningFirstConflictingDatabaseVersionHeaders);
    assertEquals("Different winners winners last version expected", expectedTestResult.winnersWinnersLastDatabaseVersionHeader, actualTestResult.winnersWinnersLastDatabaseVersionHeader);
  }

  private void printBranches(DatabaseBranches branches) {
    for (String machineName : branches.getClients()) {
      System.out.println(machineName+":");
      printBranch(branches.getBranch(machineName));
    }
  }
 
  private void printBranch(DatabaseBranch branch) {
    for (DatabaseVersionHeader databaseVersionHeader : branch.getAll()) {
      System.out.println("- "+databaseVersionHeader);
    }
  }

  private void printMap(Map<?, ?> someMap) {
    for (Map.Entry<?, ?> entry : someMap.entrySet()) {
      System.out.println("- "+entry.getKey()+": "+entry.getValue());
    }
  }   
 
  private class TestResult {
    DatabaseVersionHeader lastCommonHeader;   
    TreeMap<String, DatabaseVersionHeader> firstConflictingDatabaseVersionHeaders;
    TreeMap<String, DatabaseVersionHeader> winningFirstConflictingDatabaseVersionHeaders;
    Map.Entry<String, DatabaseVersionHeader> winnersWinnersLastDatabaseVersionHeader; 
  }
}
TOP

Related Classes of org.syncany.tests.database.DatabaseReconciliatorTest$TestResult

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.