@RunWith(AndroidJUnit4.class)
public class MainActivityTest {

  public final TestComponentRule component =
      new TestComponentRule(InstrumentationRegistry.getTargetContext(), true);
  public final ClearDataRule clearDataRule = new ClearDataRule(component);
  public final ActivityTestRule<MainActivity> main =
      new ActivityTestRule<>(MainActivity.class, false, false);

  // TestComponentRule needs to go first to make sure the Dagger ApplicationTestComponent is set
  // in the Application before any Activity is launched.
  @Rule public TestRule chain = RuleChain.outerRule(component).around(clearDataRule).around(main);

  @Test
  public void listOfRibotsShows() {
    List<Ribot> mockRibots = TestDataFactory.makeListRibots(20);
    when(component.getMockRibotsService().getRibots()).thenReturn(Observable.just(mockRibots));

    main.launchActivity(null);

    int position = 0;
    for (Ribot mockRibot : mockRibots) {
      onView(withId(R.id.recycler_view)).perform(RecyclerViewActions.scrollToPosition(position));
      String name =
          String.format("%s %s", mockRibot.profile.name.first, mockRibot.profile.name.last);
      onView(withText(name)).check(matches(isDisplayed()));
      onView(withText(mockRibot.profile.email)).check(matches(isDisplayed()));
      position++;
    }
  }
}
public class ProxyOrphanedConnectionIT {

  private K3poRule robot = new K3poRule();

  public GatewayRule gateway =
      new GatewayRule() {
        {
          // @formatter:off
          GatewayConfiguration configuration =
              new GatewayConfigurationBuilder()
                  .service()
                  .name("proxy")
                  .description("proxy")
                  .accept("ws://localhost:8555/")
                  .connect("ws://localhost:8556/")
                  .type("proxy")
                  .done()
                  .done();
          // @formatter:on
          init(configuration);
        }
      };

  private TestRule timeout = new DisableOnDebug(Timeout.seconds(5));

  @Rule public TestRule chain = RuleChain.outerRule(gateway).around(robot).around(timeout);

  @Specification("connectToFrontEndProxyAndKillFrontBeforeBackendIsEstablished")
  @Test
  public void closeOnFrontBeforeConnectedFullyOnBackShouldKillBack() throws Exception {
    robot.finish();
  }
}
/**
 * リスト9.20 RuleChainによるルールの連鎖
 *
 * @author shuji.w6e
 */
public class RuleChainExampleTest {

  @Rule public RuleChain ruleChain = RuleChain.outerRule(new DBServer()).around(new AppServer());

  @Test
  public void テスト() throws Exception {}
}
public class H2ConfigurationCheckingTest {

  private ClientDriverRule driver = new ClientDriverRule();

  @Rule
  public TestRule chain =
      RuleChain.outerRule(driver)
          .around(new TemporaryFolder())
          .around(
              new GuiceRule(
                  this,
                  new TestImapArchiveModules.Simple(
                      driver,
                      new Provider<TemporaryFolder>() {

                        @Override
                        public TemporaryFolder get() {
                          return temporaryFolder;
                        }
                      })))
          .around(
              new H2InMemoryDatabaseTestRule(
                  new Provider<H2InMemoryDatabase>() {
                    @Override
                    public H2InMemoryDatabase get() {
                      return db;
                    }
                  },
                  "sql/initial.sql"));

  private @Inject TemporaryFolder temporaryFolder;
  private @Inject H2InMemoryDatabase db;
  private @Inject WebServer server;

  @After
  public void tearDown() throws Exception {
    server.stop();
  }

  @Test
  public void startingShouldWorkWhenH2() throws Exception {
    server.start();
    assertThat(server.isStarted()).isTrue();
  }
}
/** @author Thorben Lindhauer */
@RequiredHistoryLevel(ProcessEngineConfiguration.HISTORY_FULL)
public class HistoricBatchQueryAuthorizationTest {

  public ProcessEngineRule engineRule = new ProvidedProcessEngineRule();
  public AuthorizationTestBaseRule authRule = new AuthorizationTestBaseRule(engineRule);
  public ProcessEngineTestRule testHelper = new ProcessEngineTestRule(engineRule);

  @Rule
  public RuleChain ruleChain = RuleChain.outerRule(engineRule).around(authRule).around(testHelper);

  protected MigrationPlan migrationPlan;
  protected Batch batch1;
  protected Batch batch2;

  @Before
  public void setUp() {
    authRule.createUserAndGroup("user", "group");
  }

  @Before
  public void deployProcessesAndCreateMigrationPlan() {
    ProcessDefinition sourceDefinition =
        testHelper.deployAndGetDefinition(ProcessModels.ONE_TASK_PROCESS);
    ProcessDefinition targetDefinition =
        testHelper.deployAndGetDefinition(ProcessModels.ONE_TASK_PROCESS);

    migrationPlan =
        engineRule
            .getRuntimeService()
            .createMigrationPlan(sourceDefinition.getId(), targetDefinition.getId())
            .mapEqualActivities()
            .build();

    ProcessInstance pi =
        engineRule.getRuntimeService().startProcessInstanceById(sourceDefinition.getId());

    batch1 =
        engineRule
            .getRuntimeService()
            .newMigration(migrationPlan)
            .processInstanceIds(Arrays.asList(pi.getId()))
            .executeAsync();

    batch2 =
        engineRule
            .getRuntimeService()
            .newMigration(migrationPlan)
            .processInstanceIds(Arrays.asList(pi.getId()))
            .executeAsync();
  }

  @After
  public void tearDown() {
    authRule.deleteUsersAndGroups();
  }

  @After
  public void deleteBatches() {
    engineRule.getManagementService().deleteBatch(batch1.getId(), true);
    engineRule.getManagementService().deleteBatch(batch2.getId(), true);
  }

  @Test
  public void testQueryList() {
    // given
    authRule.createGrantAuthorization(
        Resources.BATCH, batch1.getId(), "user", Permissions.READ_HISTORY);

    // when
    authRule.enableAuthorization("user");
    List<HistoricBatch> batches = engineRule.getHistoryService().createHistoricBatchQuery().list();
    authRule.disableAuthorization();

    // then
    Assert.assertEquals(1, batches.size());
    Assert.assertEquals(batch1.getId(), batches.get(0).getId());
  }

  @Test
  public void testQueryCount() {
    // given
    authRule.createGrantAuthorization(
        Resources.BATCH, batch1.getId(), "user", Permissions.READ_HISTORY);

    // when
    authRule.enableAuthorization("user");
    long count = engineRule.getHistoryService().createHistoricBatchQuery().count();
    authRule.disableAuthorization();

    // then
    Assert.assertEquals(1, count);
  }

  @Test
  public void testQueryNoAuthorizations() {
    // when
    authRule.enableAuthorization("user");
    long count = engineRule.getHistoryService().createHistoricBatchQuery().count();
    authRule.disableAuthorization();

    // then
    Assert.assertEquals(0, count);
  }

  @Test
  public void testQueryListAccessAll() {
    // given
    authRule.createGrantAuthorization(Resources.BATCH, "*", "user", Permissions.READ_HISTORY);

    // when
    authRule.enableAuthorization("user");
    List<HistoricBatch> batches = engineRule.getHistoryService().createHistoricBatchQuery().list();
    authRule.disableAuthorization();

    // then
    Assert.assertEquals(2, batches.size());
  }

  @Test
  public void testQueryListMultiple() {
    // given
    authRule.createGrantAuthorization(Resources.BATCH, "*", "user", Permissions.READ_HISTORY);
    authRule.createGrantAuthorization(
        Resources.BATCH, batch1.getId(), "user", Permissions.READ_HISTORY);

    // when
    authRule.enableAuthorization("user");
    List<HistoricBatch> batches = engineRule.getHistoryService().createHistoricBatchQuery().list();
    authRule.disableAuthorization();

    // then
    Assert.assertEquals(2, batches.size());
  }
}
public class JoinSelectionIT extends SpliceUnitTest {

  public static final String CLASS_NAME = JoinSelectionIT.class.getSimpleName().toUpperCase();
  public static final SpliceWatcher spliceClassWatcher = new SpliceWatcher(CLASS_NAME);
  public static final SpliceSchemaWatcher spliceSchemaWatcher = new SpliceSchemaWatcher(CLASS_NAME);
  public static final SpliceTableWatcher spliceTableWatcher =
      new SpliceTableWatcher(
          "PERSON",
          CLASS_NAME,
          "(pid int NOT NULL GENERATED ALWAYS AS IDENTITY (START WITH 1, INCREMENT BY 1), i int)");
  public static final SpliceTableWatcher spliceTableWatcher2 =
      new SpliceTableWatcher(
          "RP_BC_14_1",
          CLASS_NAME,
          "(pid int NOT NULL GENERATED ALWAYS AS IDENTITY (START WITH 1, INCREMENT BY 1), i int)");
  public static final SpliceTableWatcher spliceTableWatcher3 =
      new SpliceTableWatcher("T", CLASS_NAME, "(i int)");
  public static final SpliceTableWatcher spliceTableWatcher4 =
      new SpliceTableWatcher("A", CLASS_NAME, "(i int,j int)");
  public static final SpliceTableWatcher spliceTableWatcher5 =
      new SpliceTableWatcher("B", CLASS_NAME, "(i int,j int)");
  public static final SpliceTableWatcher spliceTableRegion =
      new SpliceTableWatcher(
          "REGION2", CLASS_NAME, "(R_REGIONKEY INTEGER NOT NULL PRIMARY KEY, R_NAME VARCHAR(25))");
  public static final SpliceTableWatcher spliceTableNation =
      new SpliceTableWatcher(
          "NATION2",
          CLASS_NAME,
          "(N_NATIONKEY INTEGER NOT NULL PRIMARY KEY, N_NAME VARCHAR(25), N_REGIONKEY INTEGER NOT NULL)");

  private static final String PLAN_LINE_LEADER = "->  ";
  private static final String JOIN_STRATEGY_TERMINATOR = "(";
  private static final String NESTED_LOOP_JOIN = "NestedLoopJoin";
  private static final String MERGE_SORT_JOIN = "MergeSortJoin";
  private static final String LO_MERGE_SORT_JOIN = "MergeSortLeftOuterJoin";
  private static final String BROADCAST_JOIN = "BroadcastJoin";
  private static final String LO_BROADCAST_JOIN = "BroadcastLeftOuterJoin";

  @ClassRule
  public static TestRule rule =
      RuleChain.outerRule(spliceSchemaWatcher)
          .around(spliceTableWatcher)
          .around(spliceTableWatcher2)
          .around(spliceTableWatcher3)
          .around(spliceTableWatcher4)
          .around(spliceTableWatcher5)
          .around(spliceTableRegion)
          .around(spliceTableNation)
          .around(
              new SpliceDataWatcher() {
                @Override
                protected void starting(Description description) {
                  try {
                    spliceClassWatcher.setAutoCommit(true);
                    spliceClassWatcher.executeUpdate(
                        format(
                            "insert into %s (i) values 1,2,3,4,5,6,7,8,9,10", spliceTableWatcher));
                    spliceClassWatcher.executeUpdate(
                        format(
                            "insert into %s (i) select i from %s",
                            spliceTableWatcher, spliceTableWatcher));
                    spliceClassWatcher.executeUpdate(
                        format(
                            "insert into %s (i) select i from %s",
                            spliceTableWatcher, spliceTableWatcher));
                    spliceClassWatcher.executeUpdate(
                        format(
                            "insert into %s (i) select i from %s",
                            spliceTableWatcher, spliceTableWatcher));
                    spliceClassWatcher.executeUpdate(
                        format(
                            "insert into %s (i) select i from %s",
                            spliceTableWatcher, spliceTableWatcher));
                    spliceClassWatcher.executeUpdate(
                        format(
                            "insert into %s (i) select i from %s",
                            spliceTableWatcher, spliceTableWatcher));
                    spliceClassWatcher.executeUpdate(
                        format(
                            "insert into %s (i) select i from %s",
                            spliceTableWatcher, spliceTableWatcher));
                    spliceClassWatcher.executeUpdate(
                        format(
                            "insert into %s (i) select i from %s",
                            spliceTableWatcher, spliceTableWatcher));
                    spliceClassWatcher.executeUpdate(
                        format(
                            "insert into %s (i) select i from %s",
                            spliceTableWatcher, spliceTableWatcher));
                    spliceClassWatcher.executeUpdate(
                        format(
                            "insert into %s (i) select i from %s",
                            spliceTableWatcher, spliceTableWatcher));
                    spliceClassWatcher.executeUpdate(
                        format(
                            "insert into %s (i) select i from %s",
                            spliceTableWatcher, spliceTableWatcher));
                    spliceClassWatcher.executeUpdate(
                        format(
                            "insert into %s (i) select i from %s",
                            spliceTableWatcher, spliceTableWatcher));
                    spliceClassWatcher.executeUpdate(
                        format(
                            "insert into %s (i) select i from %s",
                            spliceTableWatcher, spliceTableWatcher));
                    spliceClassWatcher.executeUpdate(
                        format(
                            "insert into %s (i) select i from %s",
                            spliceTableWatcher, spliceTableWatcher));

                    spliceClassWatcher.executeUpdate(
                        format(
                            "insert into %s (i) values 1,2,3,4,5,6,7,8,9,10", spliceTableWatcher2));
                    spliceClassWatcher.executeUpdate(
                        format(
                            "insert into %s (i) select i from %s",
                            spliceTableWatcher2, spliceTableWatcher2));
                    spliceClassWatcher.executeUpdate(
                        format(
                            "insert into %s (i) select i from %s",
                            spliceTableWatcher2, spliceTableWatcher2));
                    spliceClassWatcher.executeUpdate(
                        format(
                            "insert into %s (i) select i from %s",
                            spliceTableWatcher2, spliceTableWatcher2));
                    spliceClassWatcher.executeUpdate(
                        format(
                            "insert into %s (i) select i from %s",
                            spliceTableWatcher2, spliceTableWatcher2));
                    spliceClassWatcher.executeUpdate(
                        format(
                            "insert into %s (i) select i from %s",
                            spliceTableWatcher2, spliceTableWatcher2));
                    spliceClassWatcher.executeUpdate(
                        format(
                            "insert into %s (i) select i from %s",
                            spliceTableWatcher2, spliceTableWatcher2));
                    spliceClassWatcher.executeUpdate(
                        format(
                            "insert into %s (i) select i from %s",
                            spliceTableWatcher2, spliceTableWatcher2));

                    spliceClassWatcher.executeUpdate(
                        format(
                            "insert into %s (i) values 1,2,3,4,5,6,7,8,9,10", spliceTableWatcher3));

                    spliceClassWatcher.executeUpdate(
                        format(
                            "insert into %s (r_regionkey, r_name) values "
                                + "(0, 'AFRICA'), (1, 'AMERICA'), (2, 'ASIA'), (3, 'EUROPE'), (4, 'MIDDLE EAST'), "
                                + "(5, 'AMERICA'), (6, 'AMERICA'), (7, 'AMERICA'), (8, 'AMERICA'), (9, 'AMERICA')",
                            spliceTableRegion));

                    spliceClassWatcher.executeUpdate(
                        format(
                            "insert into %s (n_nationkey, n_name, n_regionkey) values "
                                + "(0, 'ALGERIA', 0), "
                                + "(1, 'ARGENTINA', 1), "
                                + "(2, 'BRAZIL', 1), "
                                + "(4, 'EGYPT', 4), "
                                + "(5, 'ETHIOPIA', 0), "
                                + "(6, 'FRANCE', 3)",
                            spliceTableNation));

                    spliceClassWatcher.execute(
                        format(
                            "call syscs_util.COLLECT_SCHEMA_STATISTICS('%s',false)", CLASS_NAME));

                  } catch (Exception e) {
                    throw new RuntimeException(e);
                  } finally {
                    spliceClassWatcher.closeAll();
                  }
                }
              });

  @Rule public SpliceWatcher methodWatcher = new SpliceWatcher(CLASS_NAME);

  // should be NestedLoopJoin
  @Test
  public void testInnerJoinWithSubqueryFilterExactCriteria() throws Exception {
    fourthRowContainsQuery(
        format(
            "explain select a2.pid from %s a2 join "
                + "(select person.pid from %s) as a3 "
                + " on a2.pid = a3.pid "
                + " where a2.pid = 100",
            spliceTableWatcher2, spliceTableWatcher),
        BROADCAST_JOIN,
        methodWatcher);
  }

  @Test
  public void testInnerJoinWithSubquery() throws Exception {
    ResultSet rs =
        methodWatcher.executeQuery(
            format(
                "explain select a2.pid from %s a2 join "
                    + "(select person.pid from %s) as a3 "
                    + " on a2.pid = a3.pid ",
                spliceTableWatcher2, spliceTableWatcher));
    int count = 0;
    while (rs.next()) {
      count++;
      if (count == 4) {
        String row = rs.getString(1);
        String joinStrategy =
            row.substring(
                row.indexOf(PLAN_LINE_LEADER) + PLAN_LINE_LEADER.length(),
                row.indexOf(JOIN_STRATEGY_TERMINATOR));
        Assert.assertThat(
            "Join strategy must be either MERGE_SORT_JOIN or BROADCAST_JOIN",
            joinStrategy,
            anyOf(equalTo(MERGE_SORT_JOIN), equalTo(BROADCAST_JOIN)));
        break;
      }
    }
  }

  // should be NLJ?  Comes back with MergeSortJoin
  @Test
  public void testLeftOuterJoinWithSubqueryFilterExactCriteria() throws Exception {
    fourthRowContainsQuery(
        format(
            "explain select a2.pid from %s a2 left outer join "
                + "(select person.pid from %s) as a3 "
                + " on a2.pid = a3.pid "
                + " where a2.pid = 100",
            spliceTableWatcher2, spliceTableWatcher),
        LO_MERGE_SORT_JOIN,
        methodWatcher);
  }

  // should be Broadcast but comes back with MergeSort?
  @Test
  public void testLeftOuterJoinWithSubquery() throws Exception {
    fourthRowContainsQuery(
        format(
            "explain select a2.pid from %s a2 left outer join "
                + "(select person.pid from %s) as a3 "
                + " on a2.pid = a3.pid ",
            spliceTableWatcher2, spliceTableWatcher),
        LO_MERGE_SORT_JOIN,
        methodWatcher);
  }

  @Test
  public void testRPLeftOuterJoinWithNestedSubqueries() throws Exception {
    explainQueryNoNestedLoops(
        format(
            "explain SELECT a2.pid FROM %s a2 "
                + "LEFT OUTER JOIN "
                + "(SELECT a4.PID FROM %s a4 WHERE EXISTS "
                + "(SELECT a5.PID FROM %s a5 WHERE a4.PID = a5.PID)) AS a3 "
                + "ON a2.PID = a3.PID",
            spliceTableWatcher2, spliceTableWatcher2, spliceTableWatcher));
  }

  @Test
  public void testRPLeftOuterJoinWithNestedSubqueriesFilterExactCriteria() throws Exception {
    fourthRowContainsQuery(
        format(
            "explain SELECT a2.pid FROM %s a2 "
                + "LEFT OUTER JOIN "
                + "(SELECT a4.PID FROM %s a4 WHERE EXISTS "
                + "(SELECT a5.PID FROM %s a5 WHERE a4.PID = a5.PID)) AS a3 "
                + "ON a2.PID = a3.PID "
                + "WHERE a2.PID = 100",
            spliceTableWatcher2, spliceTableWatcher2, spliceTableWatcher),
        LO_MERGE_SORT_JOIN,
        methodWatcher);
  }

  @Test
  public void testInnerJoinWithNestedSubqueries() throws Exception {
    explainQueryNoNestedLoops(
        format(
            "explain SELECT a2.pid FROM %s a2 "
                + "INNER JOIN "
                + "(SELECT a4.PID FROM %s a4 WHERE EXISTS "
                + "(SELECT a5.PID FROM %s a5 WHERE a4.PID = a5.PID)) AS a3 "
                + "ON a2.PID = a3.PID",
            spliceTableWatcher2, spliceTableWatcher2, spliceTableWatcher));
    //            BROADCAST_JOIN, methodWatcher);
  }

  @Test
  public void testInnerJoinWithNestedSubqueriesFilterExactCriteria() throws Exception {
    fourthRowContainsQuery(
        format(
            "explain SELECT a2.pid FROM %s a2 "
                + "INNER JOIN "
                + "(SELECT a4.PID FROM %s a4 WHERE EXISTS "
                + "(SELECT a5.PID FROM %s a5 WHERE a4.PID = a5.PID)) AS a3 "
                + "ON a2.PID = a3.PID"
                + " where a2.pid = 100",
            spliceTableWatcher2, spliceTableWatcher2, spliceTableWatcher),
        BROADCAST_JOIN,
        methodWatcher);
  }

  @Test
  public void testInnerJoinWithSubqueryLHSFilterExactCriteria() throws Exception {
    fourthRowContainsQuery(
        format(
            "explain select a2.pid from (select person.pid from %s) as a3 "
                + " join %s a2 "
                + " on a2.pid = a3.pid "
                + " where a2.pid = 100",
            spliceTableWatcher, spliceTableWatcher2),
        BROADCAST_JOIN,
        methodWatcher);
  }

  @Test
  public void testInnerJoinWithSubqueryLHS() throws Exception {

    ResultSet rs =
        methodWatcher.executeQuery(
            format(
                "explain select a2.pid from (select person.pid from %s) as a3 "
                    + " join %s a2 "
                    + " on a2.pid = a3.pid ",
                spliceTableWatcher, spliceTableWatcher2));
    int count = 0;
    while (rs.next()) {
      count++;
      if (count == 4) {
        String row = rs.getString(1);
        String joinStrategy =
            row.substring(
                row.indexOf(PLAN_LINE_LEADER) + PLAN_LINE_LEADER.length(),
                row.indexOf(JOIN_STRATEGY_TERMINATOR));
        Assert.assertTrue(
            MERGE_SORT_JOIN.equals(joinStrategy) || BROADCAST_JOIN.equals(joinStrategy));
        break;
      }
    }
  }

  // should be NLJ
  @Test
  public void testLeftOuterJoinWithSubqueryLHSFilterExactCriteria() throws Exception {
    fourthRowContainsQuery(
        format(
            "explain select a2.pid from (select person.pid from %s) as a3 "
                + " left outer join %s a2 "
                + " on a2.pid = a3.pid "
                + " where a2.pid = 100",
            spliceTableWatcher, spliceTableWatcher2),
        BROADCAST_JOIN,
        methodWatcher);
  }

  @Test
  public void testLeftOuterJoinWithSubqueryLHS() throws Exception {
    fourthRowContainsQuery(
        format(
            "explain select a2.pid from (select person.pid from %s) as a3 "
                + " left outer join %s a2 "
                + " on a2.pid = a3.pid ",
            spliceTableWatcher, spliceTableWatcher2),
        LO_BROADCAST_JOIN,
        methodWatcher);
  }

  @Test
  public void testLeftOuterJoinWithNestedSubqueryLHSFilterExactCriteria() throws Exception {
    fourthRowContainsQuery(
        format(
            "explain select a2.pid from "
                + "(SELECT a4.PID FROM %s a4 WHERE EXISTS "
                + "   (SELECT a5.PID FROM %s a5 WHERE a4.PID = a5.PID)) AS a3 "
                + " left outer join %s a2 "
                + " on a2.pid = a3.pid "
                + " where a2.pid = 100",
            spliceTableWatcher2, spliceTableWatcher, spliceTableWatcher2),
        BROADCAST_JOIN,
        methodWatcher);
  }

  @Test
  public void testInnerJoinWithNestedSubqueryLHSFilterExactCriteria() throws Exception {
    fourthRowContainsQuery(
        format(
            "explain select a2.pid from "
                + "(SELECT a4.PID FROM %s a4 WHERE EXISTS "
                + "   (SELECT a5.PID FROM %s a5 WHERE a4.PID = a5.PID)) AS a3 "
                + " join %s a2 "
                + " on a2.pid = a3.pid "
                + " where a2.pid = 100",
            spliceTableWatcher2, spliceTableWatcher, spliceTableWatcher2),
        BROADCAST_JOIN,
        methodWatcher);
  }

  @Test
  public void testInnerJoinWithNestedSubqueryLHS() throws Exception {
    fourthRowContainsQuery(
        format(
            "explain select a2.pid from "
                + "(SELECT a4.PID FROM %s a4 WHERE EXISTS "
                + "   (SELECT a5.PID FROM %s a5 WHERE a4.PID = a5.PID)) AS a3 "
                + " join %s a2 "
                + " on a2.pid = a3.pid ",
            spliceTableWatcher2, spliceTableWatcher, spliceTableWatcher2),
        BROADCAST_JOIN,
        methodWatcher);
  }

  @Test
  public void testLeftOuterJoinWithNestedSubqueryLHS() throws Exception {
    fourthRowContainsQuery(
        format(
            "explain select a2.pid from "
                + "(SELECT a4.PID FROM %s a4 WHERE EXISTS "
                + "   (SELECT a5.PID FROM %s a5 WHERE a4.PID = a5.PID)) AS a3 "
                + " left outer join %s a2 "
                + " on a2.pid = a3.pid ",
            spliceTableWatcher2, spliceTableWatcher, spliceTableWatcher2),
        LO_BROADCAST_JOIN,
        methodWatcher);
  }

  @Test
  public void testNoNestedLoops1() throws Exception {
    // This tests DB-3608 (wrong row estimate for frequent element match of type varchar).
    // If it fails, do not ignore it or comment it out. Let it fail until it is fixed.
    explainQueryNoNestedLoops(
        "explain select * from region2, nation2 where n_regionkey = r_regionkey and r_name = 'AMERICA'");
  }

  private void explainQueryNoNestedLoops(String query) throws Exception {
    queryDoesNotContainString(query, NESTED_LOOP_JOIN, methodWatcher);
  }

  /* Regression test for DB-3614 */
  @Test
  @Category(SlowTest.class)
  @Ignore("-sf- takes way too long to fail and interferes rest of build")
  public void testTenTableJoinExplainDuration() throws Exception {
    int size = 10;
    List<String> tables = new ArrayList<String>(size);
    List<String> joins = new ArrayList<String>(size - 1);
    for (int i = 0; i < size; i++) {
      methodWatcher.executeUpdate(format("create table tentab%s (c1 int primary key)", i));
      methodWatcher.executeUpdate(format("insert into tentab%s values (1)", i));
      tables.add(format("tentab%s", i));
      if (i > 0) {
        joins.add(format("tentab%s.c1 = tentab%s.c1", i, i - 1));
      }
    }
    System.out.println("Tables created");
    final String fromClause = Joiner.on(", ").join(tables);
    final String joinCriteria = Joiner.on(" AND ").join(joins);

    ExecutorService es =
        Executors.newSingleThreadExecutor(
            new ThreadFactory() {
              @Override
              public Thread newThread(Runnable r) {
                Thread t = new Thread(r);
                t.setDaemon(true);
                return t;
              }
            });
    try {
      final CyclicBarrier startLatch = new CyclicBarrier(2);
      final CountDownLatch finishLatch = new CountDownLatch(1);
      Future<Void> f =
          es.submit(
              new Callable<Void>() {
                @Override
                public Void call() throws Exception {
                  String query =
                      format("EXPLAIN SELECT * FROM %s WHERE %s ", fromClause, joinCriteria);
                  startLatch.await();
                  try {
                    ResultSet rs = methodWatcher.executeQuery(query);
                    // Loose check that explain statement took a few seconds or less,
                    // because we're just making sure the short circuit logic in
                    // OptimizerImpl.checkTimeout() blocks this from taking several minutes.
                    Assert.assertTrue("Explain did not return result!", rs.next());
                  } finally {
                    finishLatch.countDown();
                  }
                  return null;
                }
              });
      System.out.println("Starting wait");
      startLatch.await();
      f.get(1, TimeUnit.SECONDS);
      System.out.println("Finished waiting");
    } finally {
      System.out.println("shutting down");
    }
  }

  // DB-3865
  @Test
  public void testLeftJoin() throws Exception {
    thirdRowContainsQuery(
        format(
            "explain select * from %s t1 left join %s t2 on t1.i=t2.i",
            spliceTableWatcher3, spliceTableWatcher3),
        LO_BROADCAST_JOIN,
        methodWatcher);
  }

  @Test
  public void testRepetivePredicate() throws Exception {

    // predicates that repeat in all sub-clauses are all extracted as hashable join predicates
    thirdRowContainsQuery(
        "explain select * from a, b where (a.i = b.i and a.j=1) or (a.i = b.i and a.j=2)",
        BROADCAST_JOIN,
        methodWatcher);

    thirdRowContainsQuery(
        "explain select * from a, b where (a.i = b.i and a.j=1) or (a.i = b.i and a.j=2)",
        "preds=[(A.I[4:1] = B.I[4:3])]",
        methodWatcher);

    rowContainsQuery(
        5,
        "explain select * from a, b where (a.i = b.i and a.j=1) or (a.i = b.i and a.j=2)",
        "preds=[(A.J[0:2] IN (1,2))]",
        methodWatcher);

    thirdRowContainsQuery(
        "explain select * from a, b where (a.i = b.i and a.j=1 and a.j=b.j) or (a.i = b.i and a.j=2 and a.j=b.j)",
        BROADCAST_JOIN,
        methodWatcher);

    thirdRowContainsQuery(
        "explain select * from a, b where (a.i = b.i and a.j=1 and a.j=b.j) or (a.i = b.i and a.j=2 and a.j=b.j)",
        "preds=[(A.J[4:2] = B.J[4:4]),(A.I[4:1] = B.I[4:3])]",
        methodWatcher);

    rowContainsQuery(
        5,
        "explain select * from a, b where (a.i = b.i and a.j=1 and a.j=b.j) or (a.i = b.i and a.j=2 and a.j=b.j)",
        "preds=[(A.J[0:2] IN (1,2))]",
        methodWatcher);

    // Negative test: predicate does not repeat in all clauses
    thirdRowContainsQuery(
        "explain select * from a, b where (a.i = b.i and a.j=1) or (a.i = b.i and a.j=2) or (b.j=1)",
        NESTED_LOOP_JOIN,
        methodWatcher);

    fourthRowContainsQuery(
        "explain select * from a, b where (a.i = b.i and a.j=1) or (a.i = b.i and a.j=2) or (b.j=1)",
        "preds=[(((A.I[1:1] = B.I[2:1]) and ((A.J[1:2] = 1) and true)) or (((A.I[1:1] = B.I[2:1]) and ((A.J[1:2] = 2) and true)) or ((B.J[2:2] = 1) or false)))]",
        methodWatcher);

    thirdRowContainsQuery(
        "explain select * from a, b where (a.i = b.i and a.j=1) or (a.i = b.i+1 and a.j=2)",
        NESTED_LOOP_JOIN,
        methodWatcher);

    fourthRowContainsQuery(
        "explain select * from a, b where (a.i = b.i and a.j=1) or (a.i = b.i+1 and a.j=2)",
        "preds=[(((A.I[1:1] = B.I[2:1]) and ((A.J[1:2] = 1) and true)) or (((A.I[1:1] = (B.I[2:1] + 1)) and ((A.J[1:2] = 2) and true)) or false))]",
        methodWatcher);

    // Negative test: predicate is under a NOT node
    thirdRowContainsQuery(
        "explain select * from a, b where (a.i = b.i and a.j=1) or (not(a.i = b.i) and a.j=2)",
        NESTED_LOOP_JOIN,
        methodWatcher);

    fourthRowContainsQuery(
        "explain select * from a, b where (a.i = b.i and a.j=1) or (not(a.i = b.i) and a.j=2)",
        "preds=[(((A.I[1:1] = B.I[2:1]) and ((A.J[1:2] = 1) and true)) or (((A.I[1:1] <> B.I[2:1]) and ((A.J[1:2] = 2) and true)) or false))]",
        methodWatcher);

    // Negative test: Clause is not in a DNF form and not subject to optimization
    thirdRowContainsQuery(
        "explain select * from a, b where (a.i = b.i and a.j=1) or ((a.i = b.i or a.j=2) and a.i=1)",
        NESTED_LOOP_JOIN,
        methodWatcher);

    fourthRowContainsQuery(
        "explain select * from a, b where (a.i = b.i and a.j=1) or ((a.i = b.i or a.j=2) and a.i=1)",
        "preds=[(((A.I[1:1] = B.I[2:1]) and ((A.J[1:2] = 1) and true)) or ((((A.I[1:1] = B.I[2:1]) or ((A.J[1:2] = 2) or false)) and ((A.I[1:1] = 1) and true)) or false))]",
        methodWatcher);
  }
}
示例#7
0
// TODO - remove the bundle after the test
public class BundleDeploymentTest {

  private final LaunchpadConfig config = LaunchpadConfig.getInstance();

  private final SlingWstServer wstServer = new SlingWstServer(config);

  @Rule
  public TestRule chain =
      RuleChain.outerRule(new ExternalSlingLaunchpad(config))
          .around(new ToolingSupportBundle(config))
          .around(wstServer);

  @Rule public TemporaryProject projectRule = new TemporaryProject();

  @Rule public DefaultJavaVMInstall jvm = new DefaultJavaVMInstall();

  @Rule public DisableDebugStatusHandlers disableDebugHandlers = new DisableDebugStatusHandlers();

  @Test
  public void deployBundleOnServer_localInstall() throws Exception {

    deployBundleOnServer(true);
  }

  private void deployBundleOnServer(boolean installBundleLocally) throws Exception {
    wstServer.waitForServerToStart();

    // create faceted project
    IProject bundleProject = projectRule.getProject();

    ProjectAdapter project = new ProjectAdapter(bundleProject);
    project.addNatures(JavaCore.NATURE_ID, "org.eclipse.wst.common.project.facet.core.nature");

    // configure java project with dependencies
    MavenDependency slingApiDep =
        new MavenDependency()
            .groupId("org.apache.sling")
            .artifactId("org.apache.sling.api")
            .version("2.2.0");
    MavenDependency servletApiDep =
        new MavenDependency().groupId("javax.servlet").artifactId("servlet-api").version("2.4");
    project.configureAsJavaProject(slingApiDep, servletApiDep);

    // create DS component class
    InputStream simpleServlet = getClass().getResourceAsStream("SimpleServlet.java.v1.txt");
    project.createOrUpdateFile(
        Path.fromPortableString("src/example/SimpleServlet.java"), simpleServlet);

    // create DS component descriptor
    InputStream servletDescriptor = getClass().getResourceAsStream("SimpleServlet.xml");
    project.createOrUpdateFile(
        Path.fromPortableString("src/OSGI-INF/SimpleServlet.xml"), servletDescriptor);

    // create manifest
    OsgiBundleManifest manifest =
        OsgiBundleManifest.symbolicName("test.bundle001")
            .version("1.0.0.SNAPSHOT")
            .name("Test bundle")
            .serviceComponent("OSGI-INF/SimpleServlet.xml")
            .importPackage("javax.servlet,org.apache.sling.api,org.apache.sling.api.servlets");
    project.createOsgiBundleManifest(manifest);

    // install bundle facet
    project.installFacet("sling.bundle", "1.0");

    ServerAdapter server = new ServerAdapter(wstServer.getServer());
    server.setAttribute(ISlingLaunchpadServer.PROP_INSTALL_LOCALLY, installBundleLocally);
    server.installModule(bundleProject);

    final RepositoryAccessor repo = new RepositoryAccessor(config);
    Poller poller = new Poller();
    poller.pollUntil(
        new Callable<Void>() {
          @Override
          public Void call() throws HttpException, IOException {
            repo.assertGetIsSuccessful("simple-servlet", "Version 1");
            return null;
          }
        },
        nullValue(Void.class));

    // update DS component class
    InputStream simpleServlet2 = getClass().getResourceAsStream("SimpleServlet.java.v2.txt");
    project.createOrUpdateFile(
        Path.fromPortableString("src/example/SimpleServlet.java"), simpleServlet2);

    poller.pollUntil(
        new Callable<Void>() {
          @Override
          public Void call() throws HttpException, IOException {
            repo.assertGetIsSuccessful("simple-servlet", "Version 2");
            return null;
          }
        },
        nullValue(Void.class));
  }

  @Test
  public void deployBundleOnServer_jarredInstall() throws Exception {

    deployBundleOnServer(false);
  }
}
/** Tests a "complete" XML file a.k.a. a well-formed XML file. */
public class JsonCompleteFileAppenderTest {

  private final File logFile = new File("target", "JsonCompleteFileAppenderTest.log");

  private final LoggerContextRule init = new LoggerContextRule("JsonCompleteFileAppenderTest.xml");
  private final CleanFiles files = new CleanFiles(logFile);

  @Rule public RuleChain chain = RuleChain.outerRule(files).around(init);

  @Test
  public void testFlushAtEndOfBatch() throws Exception {
    final Logger log = this.init.getLogger("com.foo.Bar");
    final String logMsg = "Message flushed with immediate flush=true";
    log.info(logMsg);
    log.error(logMsg, new IllegalArgumentException("badarg"));
    this.init.getContext().stop(); // stops async thread
    String line1;
    String line2;
    String line3;
    String line4;
    String line5;
    String line6;
    final BufferedReader reader = new BufferedReader(new FileReader(this.logFile));
    try {
      line1 = reader.readLine();
      line2 = reader.readLine();
      line3 = reader.readLine();
      line4 = reader.readLine();
      line5 = reader.readLine();
      line6 = reader.readLine();
    } finally {
      reader.close();
    }
    assertNotNull("line1", line1);
    final String msg1 = "[";
    assertTrue(
        "line1 incorrect: [" + line1 + "], does not contain: [" + msg1 + ']', line1.equals(msg1));

    assertNotNull("line2", line2);
    final String msg2 = "{";
    assertTrue(
        "line2 incorrect: [" + line2 + "], does not contain: [" + msg2 + ']', line2.equals(msg2));

    assertNotNull("line3", line3);
    final String msg3 = "  \"timeMillis\" : ";
    assertTrue(
        "line3 incorrect: [" + line3 + "], does not contain: [" + msg3 + ']', line3.contains(msg3));

    assertNotNull("line4", line4);
    final String msg4 = "  \"thread\" : \"main\",";
    assertTrue(
        "line4 incorrect: [" + line4 + "], does not contain: [" + msg4 + ']', line4.contains(msg4));

    assertNotNull("line5", line5);
    final String msg5 = "  \"level\" : \"INFO\",";
    assertTrue(
        "line5 incorrect: [" + line5 + "], does not contain: [" + msg5 + ']', line5.contains(msg5));

    assertNotNull("line6", line6);
    final String msg6 = "  \"loggerName\" : \"com.foo.Bar\",";
    assertTrue(
        "line5 incorrect: [" + line6 + "], does not contain: [" + msg6 + ']', line6.contains(msg6));

    final String location = "testFlushAtEndOfBatch";
    assertTrue("no location", !line1.contains(location));
  }
}
/**
 * Quick share service tests.
 *
 * @author Alex Miller
 * @since Cloud/4.2
 */
public class QuickShareServiceIntegrationTest {
  private static final ApplicationContextInit testContext = new ApplicationContextInit();

  private static final String MODEL =
      "<?xml version='1.0' encoding='UTF-8'?>"
          + "<model name='lx:lxmodel' xmlns='http://www.alfresco.org/model/dictionary/1.0'>"
          + "<description>LX model</description>"
          + "<author>Peter Löfgren</author>"
          + "<version>1.0</version>"
          + "<imports>"
          + "<import uri='http://www.alfresco.org/model/dictionary/1.0' prefix='d' />"
          + "<import uri='http://www.alfresco.org/model/content/1.0' prefix='cm' />"
          + "</imports>"
          + "<namespaces>"
          + "<namespace uri='http://bugtestmodel' prefix='lx' />"
          + "</namespaces>"
          + "<constraints>"
          + "</constraints>"
          + "<types>"
          + "<type name='lx:doc'>"
          + "<title>LX dokument</title>"
          + "<parent>cm:content</parent>"
          + "<mandatory-aspects>"
          + "<aspect>cm:generalclassifiable</aspect>"
          + "</mandatory-aspects>"
          + "</type>"
          + "<type name='lx:doc2'>"
          + "<title>LX dokument 2</title>"
          + "<parent>cm:cmobject</parent>"
          + "</type>"
          + "</types>"
          + "</model>";

  private static CopyService copyService;
  private static NodeService nodeService;
  private static QuickShareService quickShareService;
  private static DictionaryService dictionaryService;
  private static Repository repository;
  private static AttributeService attributeService;
  private static PermissionService permissionService;

  private static AlfrescoPerson user1 = new AlfrescoPerson(testContext, "UserOne");
  private static AlfrescoPerson user2 = new AlfrescoPerson(testContext, "UserTwo");

  // A rule to manage test nodes reused across all the test methods
  @Rule public TemporaryNodes testNodes = new TemporaryNodes(testContext);

  @Rule public TemporaryModels temporaryModels = new TemporaryModels(testContext);

  @ClassRule
  public static RuleChain classChain = RuleChain.outerRule(testContext).around(user1).around(user2);

  private NodeRef testNode;

  private NodeRef userHome;

  @BeforeClass
  public static void beforeClass() throws Exception {
    findServices();
  }

  private static void findServices() {
    ApplicationContext ctx = testContext.getApplicationContext();

    copyService = ctx.getBean("CopyService", CopyService.class);
    dictionaryService = ctx.getBean("dictionaryService", DictionaryService.class);
    nodeService = ctx.getBean("NodeService", NodeService.class);
    quickShareService = ctx.getBean("QuickShareService", QuickShareService.class);
    repository = ctx.getBean("repositoryHelper", Repository.class);
    attributeService = ctx.getBean("AttributeService", AttributeService.class);
    permissionService = ctx.getBean("PermissionService", PermissionService.class);
  }

  @Before
  public void createTestData() {
    userHome = repository.getUserHome(user1.getPersonNode());

    testNode =
        testNodes.createNodeWithTextContent(
            userHome,
            "Quick Share Test Node",
            ContentModel.TYPE_CONTENT,
            user1.getUsername(),
            "Quick Share Test Node Content");
  }

  @Test
  public void getMetaDataFromNodeRefByOwner() {
    Map<String, Object> metadata =
        AuthenticationUtil.runAs(
            new RunAsWork<Map<String, Object>>() {

              @Override
              public Map<String, Object> doWork() throws Exception {
                return quickShareService.getMetaData(testNode);
              }
            },
            user1.getUsername());

    assertNotNull(metadata);
    assertTrue(metadata.size() > 0);
  }

  @Test(expected = AccessDeniedException.class)
  public void getMetaDataFromNodeRefByNonOwner() {
    Map<String, Object> metadata =
        AuthenticationUtil.runAs(
            new RunAsWork<Map<String, Object>>() {

              @Override
              public Map<String, Object> doWork() throws Exception {
                return quickShareService.getMetaData(testNode);
              }
            },
            user2.getUsername());
  }

  @Test
  public void share() {
    share(testNode, user1.getUsername());

    AuthenticationUtil.runAsSystem(
        new RunAsWork<Void>() {

          @Override
          public Void doWork() throws Exception {
            assertTrue(nodeService.getAspects(testNode).contains(QuickShareModel.ASPECT_QSHARE));
            assertNotNull(nodeService.getProperty(testNode, QuickShareModel.PROP_QSHARE_SHAREDID));
            assertEquals(
                user1.getUsername(),
                nodeService.getProperty(testNode, QuickShareModel.PROP_QSHARE_SHAREDBY));
            return null;
          }
        });
  }

  @Test
  public void unshare() {
    final QuickShareDTO dto = share(testNode, user1.getUsername());
    unshare(dto.getId(), user1.getUsername());
    AuthenticationUtil.runAsSystem(
        new RunAsWork<Void>() {

          @Override
          public Void doWork() throws Exception {
            assertFalse(nodeService.getAspects(testNode).contains(QuickShareModel.ASPECT_QSHARE));
            assertNull(nodeService.getProperty(testNode, QuickShareModel.PROP_QSHARE_SHAREDID));
            assertNull(nodeService.getProperty(testNode, QuickShareModel.PROP_QSHARE_SHAREDBY));
            return null;
          }
        });
  }

  private void unshare(final String sharedId, final String userName) {

    AuthenticationUtil.runAs(
        new RunAsWork<Void>() {

          @Override
          public Void doWork() throws Exception {
            quickShareService.unshareContent(sharedId);
            return null;
          }
        },
        userName);
  }

  private QuickShareDTO share(final NodeRef nodeRef, String username) {
    return AuthenticationUtil.runAs(
        new RunAsWork<QuickShareDTO>() {
          @Override
          public QuickShareDTO doWork() throws Exception {
            return quickShareService.shareContent(nodeRef);
          }
        },
        username);
  }

  @Test
  public void getMetadataFromShareId() {
    QuickShareDTO dto = share(testNode, user1.getUsername());

    Map<String, Object> metadata = quickShareService.getMetaData(dto.getId());

    assertNotNull(metadata);
    assertTrue(metadata.size() > 0);
  }

  @Test(expected = InvalidSharedIdException.class)
  public void getMetadataFromShareIdWithInvalidId() {
    UUID uuid = UUIDGenerator.getInstance().generateRandomBasedUUID();
    String sharedId =
        Base64.encodeBase64URLSafeString(
            uuid.toByteArray()); // => 22 chars (eg. q3bEKPeDQvmJYgt4hJxOjw)

    Map<String, Object> metadata = quickShareService.getMetaData(sharedId);
  }

  @Test
  public void copyNode() {
    share(testNode, user1.getUsername());

    AuthenticationUtil.runAs(
        new RunAsWork<Object>() {

          @Override
          public Object doWork() throws Exception {

            Assert.assertTrue(nodeService.hasAspect(testNode, QuickShareModel.ASPECT_QSHARE));
            Assert.assertNotNull(
                nodeService.getProperty(testNode, QuickShareModel.PROP_QSHARE_SHAREDBY));
            Assert.assertNotNull(
                nodeService.getProperty(testNode, QuickShareModel.PROP_QSHARE_SHAREDID));

            Map<QName, Serializable> originalProps = nodeService.getProperties(testNode);

            NodeRef copyNodeRef =
                copyService.copyAndRename(
                    testNode,
                    userHome,
                    ContentModel.ASSOC_CONTAINS,
                    QName.createQName(NamespaceService.APP_MODEL_1_0_URI, "copy"),
                    true);

            Map<QName, Serializable> copyProps = nodeService.getProperties(copyNodeRef);

            Assert.assertFalse(nodeService.hasAspect(copyNodeRef, QuickShareModel.ASPECT_QSHARE));
            Assert.assertNull(
                nodeService.getProperty(copyNodeRef, QuickShareModel.PROP_QSHARE_SHAREDBY));
            Assert.assertNull(
                nodeService.getProperty(copyNodeRef, QuickShareModel.PROP_QSHARE_SHAREDID));

            for (QName property : originalProps.keySet()) {
              if (property.equals(QuickShareModel.PROP_QSHARE_SHAREDBY)
                  || property.equals(QuickShareModel.PROP_QSHARE_SHAREDID)) {
                continue;
              }
              Assert.assertTrue("Mising property " + property, copyProps.containsKey(property));
            }
            return null;
          }
        },
        user1.getUsername());
  }

  /**
   * Content types that extend cm:content should be shareable.
   *
   * <p>See https://issues.alfresco.com/jira/browse/ALF-16274.
   */
  @Test
  public void testWithCustomContentType() {
    ByteArrayInputStream modelStream = new ByteArrayInputStream(MODEL.getBytes());
    temporaryModels.loadModel(modelStream);

    QName sharableType = QName.createQName("{http://bugtestmodel}doc");
    QName unsharableType = QName.createQName("{http://bugtestmodel}doc2");

    final NodeRef sharableNode =
        testNodes.createNodeWithTextContent(
            userHome,
            "Quick Share Custom Type Sharable Test Node",
            sharableType,
            user1.getUsername(),
            "Quick Share Test Node Content");

    Map<String, Object> metadata = getMetadata(sharableNode, user1);

    assertTrue((Boolean) metadata.get("sharable"));

    QuickShareDTO dto = share(sharableNode, user1.getUsername());
    unshare(dto.getId(), user1.getUsername());

    final NodeRef unsharableNode =
        testNodes.createNodeWithTextContent(
            userHome,
            "Quick Share Custom Type Unsharable Test Node",
            unsharableType,
            user1.getUsername(),
            "Quick Share Test Node Content");

    metadata = getMetadata(unsharableNode, user1);
    assertFalse((Boolean) metadata.get("sharable"));

    boolean exceptionThrown = false;
    try {
      // Prior to fixing ALF-16274, this would throw an InvalidNodeRefException.
      share(unsharableNode, user1.getUsername());
    } catch (InvalidNodeRefException ex) {
      exceptionThrown = true;
    }
    assertTrue(
        "InvalidNodeRefException not thrown on trying to share an unsharable content type",
        exceptionThrown);
  }

  @SuppressWarnings("unchecked")
  private Map<String, Object> getMetadata(final NodeRef nodeRef, AlfrescoPerson user) {
    Map<String, Object> container =
        AuthenticationUtil.runAs(
            new RunAsWork<Map<String, Object>>() {
              @Override
              public Map<String, Object> doWork() throws Exception {
                return quickShareService.getMetaData(nodeRef);
              }
            },
            user.getUsername());
    return (Map<String, Object>) container.get("item");
  }

  @Test
  public void cloud928() {
    final NodeRef node =
        testNodes.createNodeWithTextContent(
            userHome,
            "CLOUD-928 Test Node",
            ContentModel.TYPE_CONTENT,
            user1.getUsername(),
            "Quick Share Test Node Content");

    QuickShareDTO dto = share(node, user1.getUsername());

    attributeService.removeAttribute(QuickShareServiceImpl.ATTR_KEY_SHAREDIDS_ROOT, dto.getId());

    AuthenticationUtil.runAs(
        new RunAsWork<Object>() {

          @Override
          public Object doWork() throws Exception {
            nodeService.deleteNode(node);
            return null;
          }
        },
        user1.getUsername());

    AuthenticationUtil.setAdminUserAsFullyAuthenticatedUser();
    Assert.assertFalse(nodeService.exists(node));
  }

  /**
   * Test for MNT-11960
   *
   * <p>The node is created by user1 and shared by user2.
   *
   * <p>The modifier should not change to user2 after sharing.
   */
  @Test
  public void testModifierAfterSharing() {
    AuthenticationUtil.runAs(
        new RunAsWork<Void>() {
          @Override
          public Void doWork() throws Exception {
            permissionService.setPermission(
                testNode, user2.getUsername(), PermissionService.CONSUMER, true);
            return null;
          }
        },
        user1.getUsername());

    final Serializable modifiedDate =
        AuthenticationUtil.runAsSystem(
            new RunAsWork<Serializable>() {
              @Override
              public Serializable doWork() throws Exception {
                return nodeService.getProperty(testNode, ContentModel.PROP_MODIFIED);
              }
            });

    share(testNode, user2.getUsername());

    AuthenticationUtil.runAsSystem(
        new RunAsWork<Void>() {
          @Override
          public Void doWork() throws Exception {
            assertTrue(nodeService.getAspects(testNode).contains(ContentModel.ASPECT_AUDITABLE));
            assertNotNull(nodeService.getProperty(testNode, ContentModel.PROP_MODIFIER));
            assertEquals(
                "The modifier has changed after sharing.",
                user1.getUsername(),
                nodeService.getProperty(testNode, ContentModel.PROP_MODIFIER));
            assertNotNull(nodeService.getProperty(testNode, ContentModel.PROP_MODIFIED));
            assertEquals(
                "The modified date has changed after sharing.",
                modifiedDate,
                nodeService.getProperty(testNode, ContentModel.PROP_MODIFIED));
            return null;
          }
        });
  }
}
示例#10
0
public class VacationIntegrationTest {

  @Rule public DebuggableTemporaryFolder temporaryFolder = new DebuggableTemporaryFolder();

  public VacationIntegrationTest() throws IOException {
    super();
    temporaryFolder.create();
  }

  @Rule public VacationFixture vacationFixture = new VacationFixture(temporaryFolder);

  @Rule public RuleChain rule = RuleChain.outerRule(temporaryFolder).around(vacationFixture);

  @Test
  public void seeMultipleFailuresWhenNotUsingDrop() throws IOException {
    vacationFixture.setTestToFail(WEEPHOTO_TEST);
    vacationFixture.setTestToFail(PASSPORT_TEST);
    vacationFixture.setTestToFail(VACATION_TEST);

    Map<TestName, ResultType> results = vacationFixture.runAllTests();

    assertResult(results, ResultType.FAIL, WEEPHOTO_TEST, PASSPORT_TEST, VACATION_TEST);
    assertResult(
        results,
        ResultType.PASS,
        LOCATION_TEST,
        READBOOK_TEST,
        HAVEMIND_TEST,
        MEDICINE_TEST,
        CURRENCY_TEST);
  }

  @Test
  public void isolatedLeafTestFailureIsIsolated() throws IOException {
    vacationFixture.setTestToFail(WEEPHOTO_TEST);

    Map<TestName, ResultType> results = vacationFixture.runAllTestsWithDrop();

    assertResult(results, ResultType.FAIL, WEEPHOTO_TEST);
    assertResult(
        results,
        ResultType.PASS,
        PASSPORT_TEST,
        VACATION_TEST,
        LOCATION_TEST,
        READBOOK_TEST,
        HAVEMIND_TEST,
        MEDICINE_TEST,
        CURRENCY_TEST);
  }

  @Test
  public void childFailureMeansParentFailuresAreDropsNotFails() throws IOException {
    vacationFixture.setTestToFail(WEEPHOTO_TEST);
    vacationFixture.setTestToFail(PASSPORT_TEST);
    vacationFixture.setTestToFail(VACATION_TEST);

    Map<TestName, ResultType> results = vacationFixture.runAllTestsWithDrop();

    assertResult(results, ResultType.FAIL, WEEPHOTO_TEST);
    assertResult(results, ResultType.DROP, PASSPORT_TEST, VACATION_TEST);
    assertResult(
        results,
        ResultType.PASS,
        LOCATION_TEST,
        READBOOK_TEST,
        HAVEMIND_TEST,
        MEDICINE_TEST,
        CURRENCY_TEST);
  }

  private void assertResult(
      Map<VacationFixture.TestName, VacationFixture.ResultType> results,
      ResultType expectedResultType,
      TestName... testNames) {
    for (TestName testName : testNames) {
      assertTrue(
          String.format("We don't have a test result for test '%s'!", testName),
          results.containsKey(testName));
      ResultType actualResultType = results.get(testName);
      assertThat(
          String.format("Test result for '%s'", testName),
          actualResultType,
          equalTo(expectedResultType));
    }
  }
}
/**
 * Tests around creating tables with no data and with data calls.
 *
 * <p>e.g. sql that looks like "create table as ... with [no] data".
 *
 * @author Scott Fines Date: 12/18/13
 */
public class CreateTableWithDataIT {
  protected static SpliceWatcher spliceClassWatcher = new SpliceWatcher();

  protected static SpliceSchemaWatcher spliceSchemaWatcher =
      new SpliceSchemaWatcher(CreateTableWithDataIT.class.getSimpleName());
  protected static SpliceTableWatcher baseTable =
      new SpliceTableWatcher("T", spliceSchemaWatcher.schemaName, "(a int, b int)");
  protected static SpliceTableWatcher rightTable =
      new SpliceTableWatcher("R", spliceSchemaWatcher.schemaName, "(b int, c int)");
  protected static SpliceTableWatcher decimalTable =
      new SpliceTableWatcher("D", spliceSchemaWatcher.schemaName, "(d decimal(15, 2))");

  @ClassRule
  public static TestRule chain =
      RuleChain.outerRule(spliceClassWatcher)
          .around(spliceSchemaWatcher)
          .around(baseTable)
          .around(decimalTable)
          .around(rightTable)
          .around(
              new SpliceDataWatcher() {
                @Override
                protected void starting(Description description) {
                  try (PreparedStatement ps =
                      spliceClassWatcher.prepareStatement(
                          String.format("insert into %s (a,b) values (?,?)", baseTable))) {
                    for (int i = 0; i < 10; i++) {
                      ps.setInt(1, i);
                      ps.setInt(2, 2 * i);
                      ps.addBatch();
                    }
                    ps.executeBatch();
                  } catch (Exception e) {
                    throw new RuntimeException(e);
                  }

                  try (PreparedStatement ps =
                      spliceClassWatcher.prepareStatement(
                          String.format("insert into %s (b,c) values (?,?)", rightTable))) {
                    for (int i = 0; i < 10; i++) {
                      ps.setInt(1, 2 * i);
                      ps.setInt(2, i);
                      ps.addBatch();
                    }
                    ps.executeBatch();
                  } catch (Exception e) {
                    throw new RuntimeException(e);
                  }
                }
              });

  @Rule public SpliceWatcher methodWatcher = new SpliceWatcher();

  private Connection conn;

  @Before
  public void setUp() throws Exception {
    conn = methodWatcher.getOrCreateConnection();
    conn.setAutoCommit(false);
  }

  @After
  public void tearDown() throws Exception {
    conn.rollback();
  }

  @Test
  public void testCreateTableWithNoDataHasNoData() throws Exception {
    // confirmation test that we don't break anything that derby does correctly
    try (PreparedStatement ps =
        conn.prepareStatement(
            String.format(
                "create table %s.t2 as select * from %s with no data",
                spliceSchemaWatcher.schemaName, baseTable))) {
      int numRows = ps.executeUpdate();
      Assert.assertEquals("It claims to have updated rows!", 0, numRows);
    }
    try (Statement s = conn.createStatement()) {
      try (ResultSet rs =
          s.executeQuery("select * from " + spliceSchemaWatcher.schemaName + ".t2")) {
        Assert.assertFalse("Rows returned by no data!", rs.next());
      }
    }
  }

  @Test
  public void testCreateTableWithData() throws Exception {
    try (PreparedStatement ps =
        methodWatcher.prepareStatement(
            String.format(
                "create table %s.t3 as select * from %s with data",
                spliceSchemaWatcher.schemaName, baseTable))) {
      int numRows = ps.executeUpdate();
      Assert.assertEquals("It does not claim to have updated rows!", 10, numRows);
    }

    try (Statement s = conn.createStatement()) {
      try (ResultSet rs =
          s.executeQuery("select * from " + spliceSchemaWatcher.schemaName + ".t3")) {
        int count = 0;
        while (rs.next()) {
          int first = rs.getInt(1);
          int second = rs.getInt(2);
          Assert.assertEquals("Incorrect row: (" + first + "," + second + ")", first * 2, second);
          count++;
        }
        Assert.assertEquals("Incorrect row count", 10, count);
      }
    }
  }

  @Test
  public void testCreateTableWithData2() throws Exception {
    try (PreparedStatement ps =
        conn.prepareStatement(
            String.format(
                "create table %s.t4 as select t1.a, t2.c from %s t1, %s t2 where t1.b = t2.b with data",
                spliceSchemaWatcher.schemaName, baseTable, rightTable))) {
      int numRows = ps.executeUpdate();
      Assert.assertEquals("It claims to have updated rows!", 10, numRows);
    }
    try (Statement s = conn.createStatement()) {
      try (ResultSet rs =
          s.executeQuery("select * from " + spliceSchemaWatcher.schemaName + ".t4")) {
        int count = 0;
        while (rs.next()) {
          int first = rs.getInt(1);
          int second = rs.getInt(2);
          Assert.assertEquals("Incorrect row: (" + first + "," + second + ")", first, second);
          count++;
        }
        Assert.assertEquals("Incorrect row count", 10, count);
      }
    }
  }

  @Test
  public void testCreateTableWithoutWithDataClause() throws Exception {
    try (PreparedStatement ps =
        conn.prepareStatement(
            String.format(
                "create table %s.t10 as select t1.a, t2.c from %s t1, %s t2 where t1.b = t2.b",
                spliceSchemaWatcher.schemaName, baseTable, rightTable))) {
      int numRows = ps.executeUpdate();
      Assert.assertEquals("It claims to have updated rows!", 10, numRows);
    }
    try (Statement s = conn.createStatement()) {
      try (ResultSet rs =
          s.executeQuery("select * from " + spliceSchemaWatcher.schemaName + ".t10")) {
        int count = 0;
        while (rs.next()) {
          int first = rs.getInt(1);
          int second = rs.getInt(2);
          Assert.assertEquals("Incorrect row: (" + first + "," + second + ")", first, second);
          count++;
        }
        Assert.assertEquals("Incorrect row count", 10, count);
      }
    }
  }

  // DB-1170
  @Test
  public void testCreateTableWithNoDataDerivedDecimal() throws Exception {
    try (Statement s = conn.createStatement()) {
      s.executeUpdate(
          String.format(
              "create table %s.t5 as select (d * (1 - d)) as volume from %s with no data",
              spliceSchemaWatcher.schemaName, decimalTable));
      s.executeUpdate("drop table " + spliceSchemaWatcher.schemaName + ".t5");
    }
  }

  @SuppressWarnings("unchecked")
  @Test
  public void createTableWithViewJoins() throws Exception {
    // DB-4170: create table with data didn't work with more than one join (the view defn is
    // executed)
    String nameTable = "names";
    String nameTableRef = spliceSchemaWatcher.schemaName + "." + nameTable;
    String nameTableDef = "(id int, fname varchar(10), lname varchar(10))";
    new TableDAO(methodWatcher.getOrCreateConnection())
        .drop(spliceSchemaWatcher.schemaName, nameTable);

    new TableCreator(methodWatcher.getOrCreateConnection())
        .withCreate(format("create table %s %s", nameTableRef, nameTableDef))
        .withInsert(format("insert into %s values (?,?,?)", nameTableRef))
        .withRows(
            rows(
                row(20, "Joe", "Blow"),
                row(70, "Fred", "Ziffle"),
                row(60, "Floyd", "Jones"),
                row(40, "Janice", "Jones")))
        .create();

    String empTable = "emptab";
    String empTableRef = spliceSchemaWatcher.schemaName + "." + empTable;
    String empTableDef = "(empnum int, dept int, salary int)";
    new TableDAO(methodWatcher.getOrCreateConnection())
        .drop(spliceSchemaWatcher.schemaName, empTable);

    new TableCreator(methodWatcher.getOrCreateConnection())
        .withCreate(format("create table %s %s", empTableRef, empTableDef))
        .withInsert(format("insert into %s values (?,?,?)", empTableRef))
        .withRows(rows(row(20, 1, 75000), row(70, 3, 76000), row(60, 2, 78000), row(40, 2, 52000)))
        .create();

    String ssnTable = "ssn";
    String ssnTableRef = spliceSchemaWatcher.schemaName + "." + ssnTable;
    String ssnTableDef = "(id int, ssn int)";
    new TableDAO(methodWatcher.getOrCreateConnection())
        .drop(spliceSchemaWatcher.schemaName, ssnTable);

    new TableCreator(methodWatcher.getOrCreateConnection())
        .withCreate(format("create table %s %s", ssnTableRef, ssnTableDef))
        .withInsert(format("insert into %s values (?,?)", ssnTableRef))
        .withRows(rows(row(20, 11199222), row(70, 33366777), row(60, 88844777), row(40, 22200555)))
        .create();

    String viewName = "empsal";
    String viewRef = spliceSchemaWatcher.schemaName + "." + viewName;
    String viewDef =
        format(
            "create view %s as select distinct "
                + "A.ID, A.LNAME, A.FNAME, "
                + "B.DEPT, B.SALARY, "
                + "C.SSN "
                + "FROM %s A "
                + "LEFT OUTER JOIN %s B ON A.ID = B.EMPNUM "
                + "LEFT OUTER JOIN %s C ON A.ID = C.ID ",
            viewRef, nameTableRef, empTableRef, ssnTableRef);

    methodWatcher.execute(viewDef);

    String depsalTable = "depsal";
    String depsalTableRef = spliceSchemaWatcher.schemaName + "." + depsalTable;
    String depsalTableDef =
        format(
            "create table %s as " + "select dept, salary, ssn from %s with data",
            depsalTableRef, viewRef);
    new TableDAO(methodWatcher.getOrCreateConnection())
        .drop(spliceSchemaWatcher.schemaName, depsalTable);

    methodWatcher.executeUpdate(depsalTableDef);
    String sqlText = format("select * from %s order by dept, salary", depsalTableRef);
    ResultSet rs = methodWatcher.executeQuery(sqlText);

    String expected =
        "DEPT |SALARY |   SSN   |\n"
            + "------------------------\n"
            + "  1  | 75000 |11199222 |\n"
            + "  2  | 52000 |22200555 |\n"
            + "  2  | 78000 |88844777 |\n"
            + "  3  | 76000 |33366777 |";
    assertEquals(
        "\n" + sqlText + "\n",
        expected,
        TestUtils.FormattedResult.ResultFactory.toStringUnsorted(rs));
  }
}
/** Index tests. Using more manual SQL, rather than SpliceIndexWatcher. */
@Category({Transactions.class})
public class WriteWriteRollbackIT extends SpliceUnitTest {
  public static final String CLASS_NAME = WriteWriteRollbackIT.class.getSimpleName().toUpperCase();

  protected static SpliceWatcher spliceClassWatcher = new SpliceWatcher();
  public static final String TABLE_NAME_1 = "A";
  protected static SpliceSchemaWatcher spliceSchemaWatcher = new SpliceSchemaWatcher(CLASS_NAME);

  private static String tableDef = "(col1 int, col2 int)";
  protected static SpliceTableWatcher spliceTableWatcher1 =
      new SpliceTableWatcher(TABLE_NAME_1, CLASS_NAME, tableDef);

  @ClassRule
  public static TestRule chain =
      RuleChain.outerRule(spliceClassWatcher)
          .around(spliceSchemaWatcher)
          .around(spliceTableWatcher1)
          .around(
              new SpliceDataWatcher() {
                @Override
                protected void starting(Description description) {
                  try {
                    PreparedStatement s =
                        spliceClassWatcher.prepareStatement(
                            String.format(
                                "insert into %s.%s values (?, ?)", CLASS_NAME, TABLE_NAME_1));
                    s.setInt(1, 1);
                    s.setInt(2, 10);
                    s.execute();

                  } catch (Exception e) {
                    throw new RuntimeException(e);
                  } finally {
                    spliceClassWatcher.closeAll();
                  }
                }
              });

  @Rule public SpliceWatcher methodWatcher = new SpliceWatcher();

  @Test
  public void testUpdateWriteWriteRollbackConcurrent() throws Exception {

    Connection c1 = methodWatcher.createConnection();
    c1.setAutoCommit(false);
    PreparedStatement ps1 =
        c1.prepareStatement(
            String.format("update %s.%s set col2 = ? where col1 = ?", CLASS_NAME, TABLE_NAME_1));
    ps1.setInt(1, 100);
    ps1.setInt(2, 1);
    ps1.execute();

    Connection c2 = methodWatcher.createConnection();
    c2.setAutoCommit(false);
    try { // catch problem with rollback
      try { // catch write-write conflict
        PreparedStatement ps2 =
            c2.prepareStatement(
                String.format(
                    "update %s.%s set col2 = ? where col1 = ?", CLASS_NAME, TABLE_NAME_1));
        ps2.setInt(1, 1000);
        ps2.setInt(2, 1);
        ps2.execute();
        Assert.fail("Didn't raise write-conflict exception");
      } catch (Exception e) {
        c2.rollback();
      }
    } catch (Exception e) {
      Assert.fail("Unexpected exception " + e);
    }
  }
}
/** @since solr 1.3 */
public class TestSolrProperties extends AbstractEmbeddedSolrServerTestCase {
  private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());

  @Rule public TestRule solrTestRules = RuleChain.outerRule(new SystemPropertiesRestoreRule());

  protected SolrClient getSolrAdmin() {
    return new EmbeddedSolrServer(cores, "core0");
  }

  protected SolrClient getRenamedSolrAdmin() {
    return new EmbeddedSolrServer(cores, "renamed_core");
  }

  @Test
  public void testProperties() throws Exception {

    UpdateRequest up = new UpdateRequest();
    up.setAction(ACTION.COMMIT, true, true);
    up.deleteByQuery("*:*");
    up.process(getSolrCore0());
    up.process(getSolrCore1());
    up.clear();

    // Add something to each core
    SolrInputDocument doc = new SolrInputDocument();
    doc.setField("id", "AAA");
    doc.setField("core0", "yup stopfra stopfrb stopena stopenb");

    // Add to core0
    up.add(doc);
    up.process(getSolrCore0());

    SolrTestCaseJ4.ignoreException("unknown field");

    // You can't add it to core1
    try {
      up.process(getSolrCore1());
      fail("Can't add core0 field to core1!");
    } catch (Exception ex) {
    }

    // Add to core1
    doc.setField("id", "BBB");
    doc.setField("core1", "yup stopfra stopfrb stopena stopenb");
    doc.removeField("core0");
    up.add(doc);
    up.process(getSolrCore1());

    // You can't add it to core1
    try {
      SolrTestCaseJ4.ignoreException("core0");
      up.process(getSolrCore0());
      fail("Can't add core1 field to core0!");
    } catch (Exception ex) {
    }

    SolrTestCaseJ4.resetExceptionIgnores();

    // now Make sure AAA is in 0 and BBB in 1
    SolrQuery q = new SolrQuery();
    QueryRequest r = new QueryRequest(q);
    q.setQuery("id:AAA");
    assertEquals(1, r.process(getSolrCore0()).getResults().size());
    assertEquals(0, r.process(getSolrCore1()).getResults().size());

    // Now test Changing the default core
    assertEquals(1, getSolrCore0().query(new SolrQuery("id:AAA")).getResults().size());
    assertEquals(0, getSolrCore0().query(new SolrQuery("id:BBB")).getResults().size());

    assertEquals(0, getSolrCore1().query(new SolrQuery("id:AAA")).getResults().size());
    assertEquals(1, getSolrCore1().query(new SolrQuery("id:BBB")).getResults().size());

    // Now test reloading it should have a newer open time
    String name = "core0";
    SolrClient coreadmin = getSolrAdmin();
    CoreAdminResponse mcr = CoreAdminRequest.getStatus(name, coreadmin);
    long before = mcr.getStartTime(name).getTime();
    CoreAdminRequest.reloadCore(name, coreadmin);

    mcr = CoreAdminRequest.getStatus(name, coreadmin);
    long after = mcr.getStartTime(name).getTime();
    assertTrue("should have more recent time: " + after + "," + before, after > before);
  }
}
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(
    locations = {
      "classpath:WEB-INF/applicationContext-global.xml",
      "classpath:WEB-INF/applicationContext-dataLocalAccess.xml",
      "classpath:WEB-INF/applicationContext-acegi-security.xml"
    })
public class ConfigSaveDeadlockDetectionIntegrationTest {
  @Autowired private GoConfigDao goConfigDao;
  @Autowired private GoConfigService goConfigService;
  @Autowired private CachedFileGoConfig cachedFileGoConfig;
  @Autowired private PipelineConfigService pipelineConfigService;
  @Autowired private ServerStatusService serverStatusService;
  @Autowired private Localizer localizer;
  private GoConfigFileHelper configHelper;
  private final int TWO_MINUTES = 2 * 60 * 1000;

  @Before
  public void setup() throws Exception {
    configHelper = new GoConfigFileHelper();
    configHelper.usingCruiseConfigDao(goConfigDao).initializeConfigFile();
    configHelper.onSetUp();
    goConfigService.forceNotifyListeners();
  }

  @After
  public void tearDown() throws Exception {
    configHelper.onTearDown();
  }

  @Rule
  public final TestRule timeout =
      RuleChain.outerRule(
              new TestWatcher() {
                @Override
                protected void failed(Throwable e, Description description) {
                  if (e.getMessage().contains("test timed out") || e instanceof TimeoutException) {
                    try {
                      fail(
                          "Test timed out, possible deadlock. Thread Dump:"
                              + serverStatusService.captureServerInfo(
                                  Username.ANONYMOUS, new HttpLocalizedOperationResult()));
                    } catch (IOException e1) {
                      throw new RuntimeException(e1);
                    }
                  }
                }
              })
          .around(new Timeout(TWO_MINUTES));

  @Test
  public void shouldNotDeadlockWhenAllPossibleWaysOfUpdatingTheConfigAreBeingUsedAtTheSameTime()
      throws Exception {
    final ArrayList<Thread> configSaveThreads = new ArrayList<>();
    final int pipelineCreatedThroughApiCount = 100;
    final int pipelineCreatedThroughUICount = 100;

    for (int i = 0; i < pipelineCreatedThroughUICount; i++) {
      Thread thread = configSaveThread(i);
      configSaveThreads.add(thread);
    }

    for (int i = 0; i < pipelineCreatedThroughApiCount; i++) {
      Thread thread = pipelineSaveThread(i);
      configSaveThreads.add(thread);
    }

    for (Thread configSaveThread : configSaveThreads) {
      Thread timerThread = null;
      try {
        timerThread =
            createThread(
                new Runnable() {
                  @Override
                  public void run() {
                    try {
                      File configFile = new File(goConfigDao.fileLocation());
                      String currentConfig = FileUtil.readContentFromFile(configFile);
                      String updatedConfig =
                          currentConfig.replaceFirst(
                              "artifactsdir=\".*\"",
                              "artifactsdir=\"" + UUID.randomUUID().toString() + "\"");
                      FileUtil.writeContentToFile(updatedConfig, configFile);
                    } catch (IOException e) {
                      fail("Failed with error: " + e.getMessage());
                    }
                    cachedFileGoConfig.forceReload();
                  }
                },
                "timer-thread");
      } catch (InterruptedException e) {
        fail(e.getMessage());
      }

      try {
        configSaveThread.start();
        timerThread.start();
        configSaveThread.join();
        timerThread.join();
      } catch (InterruptedException e) {
        fail(e.getMessage());
      }
    }
    assertThat(
        goConfigService.getAllPipelineConfigs().size(),
        is(pipelineCreatedThroughApiCount + pipelineCreatedThroughUICount));
  }

  private Thread pipelineSaveThread(int counter) throws InterruptedException {
    return createThread(
        new Runnable() {
          @Override
          public void run() {
            PipelineConfig pipelineConfig =
                GoConfigMother.createPipelineConfigWithMaterialConfig(
                    UUID.randomUUID().toString(), new GitMaterialConfig("FOO"));
            HttpLocalizedOperationResult result = new HttpLocalizedOperationResult();
            pipelineConfigService.createPipelineConfig(
                new Username(new CaseInsensitiveString("root")), pipelineConfig, result, "default");
            assertThat(result.message(localizer), result.isSuccessful(), is(true));
          }
        },
        "pipeline-config-save-thread" + counter);
  }

  private Thread configSaveThread(final int counter)
      throws InvalidCipherTextException, InterruptedException {
    return createThread(
        new Runnable() {
          @Override
          public void run() {
            goConfigService.updateConfig(
                new UpdateConfigCommand() {
                  @Override
                  public CruiseConfig update(CruiseConfig cruiseConfig) throws Exception {
                    PipelineConfig pipelineConfig =
                        GoConfigMother.createPipelineConfigWithMaterialConfig(
                            UUID.randomUUID().toString(), new GitMaterialConfig("FOO"));
                    cruiseConfig.addPipeline("default", pipelineConfig);
                    return cruiseConfig;
                  }
                });
          }
        },
        "config-save-thread" + counter);
  }

  private Thread createThread(Runnable runnable, String name) throws InterruptedException {
    Thread thread = new Thread(runnable, name);
    thread.setUncaughtExceptionHandler(
        new Thread.UncaughtExceptionHandler() {
          public void uncaughtException(Thread t, Throwable e) {
            e.printStackTrace();
            throw new RuntimeException(e.getMessage(), e);
          }
        });
    return thread;
  }
}
示例#15
0
/** Test cases for the {@link DcsApp}. */
@ThreadLeakLingering(linger = 3000)
@ThreadLeakScope(Scope.SUITE)
public class AuthConnectionTest extends CarrotTestCase {
  private static class ListenerAdapter implements LifeCycle.Listener {
    public void lifeCycleFailure(LifeCycle lc, Throwable t) {}

    public void lifeCycleStarted(LifeCycle lc) {}

    public void lifeCycleStarting(LifeCycle lc) {}

    public void lifeCycleStopped(LifeCycle lc) {}

    public void lifeCycleStopping(LifeCycle lc) {}
  }

  @Rule public RuleChain rules = RuleChain.outerRule(new SystemPropertiesRestoreRule());

  @Test
  public void checkBasicAuthAccess() throws Throwable {
    final Server server = new Server();
    final SelectChannelConnector connector = new SelectChannelConnector();
    connector.setPort(/* any */ 0);
    connector.setReuseAddress(false);
    connector.setSoLingerTime(0);
    server.addConnector(connector);

    HashLoginService loginService = new HashLoginService();
    loginService.putUser("username", new Password("userpass"), new String[] {"role1", "role2"});

    final CountDownLatch latch = new CountDownLatch(1);

    WebAppContext wac = new WebAppContext();
    wac.getSecurityHandler().setLoginService(loginService);
    wac.setContextPath("/");

    connector.addLifeCycleListener(
        new ListenerAdapter() {
          public void lifeCycleStarted(LifeCycle lc) {
            System.out.println("Started on port: " + connector.getLocalPort());
            latch.countDown();
          }

          public void lifeCycleFailure(LifeCycle lc, Throwable t) {
            System.out.println("Failure: " + t);
            latch.countDown();
          }
        });
    wac.setParentLoaderPriority(true);

    URL resource = getClass().getResource("/auth/basic/kaczynski.xml");
    assertThat(resource.toURI().getScheme()).isEqualTo("file");
    File webapp = new File(resource.toURI());
    webapp = webapp.getParentFile(); // /auth/basic
    webapp = webapp.getParentFile(); // /auth
    wac.setWar(webapp.getAbsolutePath());
    wac.setClassLoader(Thread.currentThread().getContextClassLoader());

    server.setHandler(wac);
    server.setStopAtShutdown(true);
    try {
      server.start();
      latch.await();

      System.setProperty(HttpAuthHub.USERNAME_PROPERTY, "username");
      System.setProperty(HttpAuthHub.PASSWORD_PROPERTY, "userpass");
      Controller c = ControllerFactory.createSimple();
      try {
        Map<String, Object> attrs = new HashMap<String, Object>();
        XmlDocumentSourceDescriptor.attributeBuilder(attrs)
            .xml(
                new URLResourceWithParams(
                    new URL(
                        "http://localhost:" + connector.getLocalPort() + "/basic/kaczynski.xml")));
        ProcessingResult r = c.process(attrs, XmlDocumentSource.class);

        assertThat(r.getDocuments()).hasSize(50);
      } finally {
        c.dispose();
      }
    } finally {
      server.stop();
    }
  }
}
public class AddressBookIntegrationTest {

  @Rule
  public TestRule chain =
      RuleChain.outerRule(new GuiceRule(this, new TestingProvisioningModule()))
          .around(
              new H2InMemoryDatabaseTestRule(
                  new Provider<H2InMemoryDatabase>() {
                    @Override
                    public H2InMemoryDatabase get() {
                      return db;
                    }
                  },
                  "dbInitialScriptEvent.sql"));

  @Inject private H2InMemoryDatabase db;
  @Inject private WebServer server;
  @Inject private JMSServer jmsServer;

  @Inject private UserDao userDao;
  @Inject private AddressBookDao addressBookDao;

  private URL baseURL;
  private AccessToken token;
  private ObmUser obmUser;

  @Before
  public void init() throws Exception {
    server.start();
    baseURL = new URL("http", "localhost", server.getHttpPort(), "/");

    ObmDomain domain = ObmDomain.builder().name("test.tlse.lng").id(2).build();
    UserLogin login = UserLogin.valueOf("user-with-books");
    ObmHost mailHost = ObmHost.builder().id(1).build();
    UserEmails emails =
        UserEmails.builder()
            .domain(domain)
            .addAddress(login.getStringValue())
            .server(mailHost)
            .build();
    obmUser =
        userDao.create(
            ObmUser.builder()
                .login(login)
                .emails(emails)
                .domain(domain)
                .extId(UserExtId.valueOf("extId123"))
                .build());
    token = new AccessToken(obmUser.getUid(), "papi");
    token.setDomain(domain);
  }

  @After
  public void tearDown() throws Exception {
    jmsServer.stop();
    server.stop();
  }

  @Test
  public void testPostWhenTheUserIsUnknown() {
    ObmDomainUuid obmDomainUuid = ObmDomainUuid.of("ac21bc0c-f816-4c52-8bb9-e50cfbfec5b6");
    String batchId = startBatch(baseURL, obmDomainUuid);

    String json = "{}";
    createAddressBook(json, "*****@*****.**");
    commitBatch();
    waitForBatchSuccess(batchId, 1, 0);

    given()
        .auth()
        .basic("*****@*****.**", "admin0")
        .expect()
        .statusCode(Status.OK.getStatusCode())
        .body(
            containsString(
                "{"
                    + "\"id\":"
                    + batchId
                    + ","
                    + "\"status\":\"SUCCESS\","
                    + "\"operationCount\":1,"
                    + "\"operationDone\":0,"
                    + "\"operations\":["
                    + "{\"status\":\"ERROR\","
                    + "\"entityType\":\"ADDRESS_BOOK\","
                    + "\"entity\":"
                    + json
                    + ","
                    + "\"operation\":\"POST\","
                    + "\"error\":\"org.obm.provisioning.exception.ProcessingException: "
                    + "org.obm.provisioning.dao.exceptions.UserNotFoundException: "
                    + "The user with login [email protected] with domain id ac21bc0c-f816-4c52-8bb9-e50cfbfec5b6 was not found\"}"
                    + "]"
                    + "}"))
        .when()
        .get("");
  }

  @Test
  public void testPostShouldCreateReferenceWhenPrimaryWithReference() throws Exception {
    ObmDomainUuid obmDomainUuid = ObmDomainUuid.of("ac21bc0c-f816-4c52-8bb9-e50cfbfec5b6");

    String json =
        "{"
            + "\"name\":\"the primary address book name can't be choosen\","
            + "\"role\":\"primary\","
            + "\"reference\": {"
            + "\"value\":\"1234\","
            + "\"origin\":\"exchange\""
            + "}"
            + "}";

    String batchId = startBatch(baseURL, obmDomainUuid);
    createAddressBook(json, obmUser.getLoginAtDomain());
    commitBatch();
    waitForBatchSuccess(batchId);

    Optional<Id> idByReference =
        addressBookDao.findByReference(new AddressBookReference("1234", "exchange"));
    assertThat(idByReference).isPresent();
    assertThatAddressBookIsSynced(idByReference.get());
    assertThat(addressBookDao.get(idByReference.get()))
        .isEqualTo(
            AddressBook.builder()
                .uid(idByReference.get())
                .name("contacts")
                .origin("provisioning")
                .defaultBook(true)
                .readOnly(false)
                .syncable(true)
                .build());
  }

  @Test
  public void testPostShouldCreateReferenceWhenCollectedWithReference() throws Exception {
    ObmDomainUuid obmDomainUuid = ObmDomainUuid.of("ac21bc0c-f816-4c52-8bb9-e50cfbfec5b6");

    String json =
        "{"
            + "\"name\":\"the collected address book name can't be choosen\","
            + "\"role\":\"collected\","
            + "\"reference\": {"
            + "\"value\":\"1234\","
            + "\"origin\":\"exchange\""
            + "}"
            + "}";

    String batchId = startBatch(baseURL, obmDomainUuid);
    createAddressBook(json, obmUser.getLoginAtDomain());
    commitBatch();
    waitForBatchSuccess(batchId);

    Optional<Id> idByReference =
        addressBookDao.findByReference(new AddressBookReference("1234", "exchange"));
    assertThat(idByReference).isPresent();
    assertThat(addressBookDao.get(idByReference.get()))
        .isEqualTo(
            AddressBook.builder()
                .uid(idByReference.get())
                .name("collected_contacts")
                .origin("provisioning")
                .defaultBook(true)
                .readOnly(false)
                .syncable(true)
                .build());
  }

  @Test
  public void testPostShouldCreateWhenCustomWithReference() throws Exception {
    ObmDomainUuid obmDomainUuid = ObmDomainUuid.of("ac21bc0c-f816-4c52-8bb9-e50cfbfec5b6");
    String batchId = startBatch(baseURL, obmDomainUuid);

    String json =
        "{"
            + "\"name\":\"custom book\","
            + "\"role\":\"custom\","
            + "\"reference\": {"
            + "\"value\":\"1234\","
            + "\"origin\":\"exchange\""
            + "}"
            + "}";

    createAddressBook(json, obmUser.getLoginAtDomain());

    given()
        .auth()
        .basic("*****@*****.**", "admin0")
        .expect()
        .statusCode(Status.OK.getStatusCode())
        .body(
            containsString(
                "{"
                    + "\"id\":"
                    + batchId
                    + ","
                    + "\"status\":\"IDLE\","
                    + "\"operationCount\":1,"
                    + "\"operationDone\":0,"
                    + "\"operations\":["
                    + "{\"status\":\"IDLE\","
                    + "\"entityType\":\"ADDRESS_BOOK\","
                    + "\"entity\":"
                    + json
                    + ","
                    + "\"operation\":\"POST\","
                    + "\"error\":null}"
                    + "]"
                    + "}"))
        .when()
        .get("");

    commitBatch();
    waitForBatchSuccess(batchId);

    given()
        .auth()
        .basic("*****@*****.**", "admin0")
        .expect()
        .statusCode(Status.OK.getStatusCode())
        .body(
            containsString(
                "{"
                    + "\"id\":"
                    + batchId
                    + ","
                    + "\"status\":\"SUCCESS\","
                    + "\"operationCount\":1,"
                    + "\"operationDone\":1,"
                    + "\"operations\":["
                    + "{\"status\":\"SUCCESS\","
                    + "\"entityType\":\"ADDRESS_BOOK\","
                    + "\"entity\":"
                    + json
                    + ","
                    + "\"operation\":\"POST\","
                    + "\"error\":null}"
                    + "]"
                    + "}"))
        .when()
        .get("");

    Optional<Id> idByReference =
        addressBookDao.findByReference(new AddressBookReference("1234", "exchange"));
    assertThat(idByReference).isPresent();
    assertThatAddressBookIsSynced(idByReference.get());
    assertThat(addressBookDao.get(idByReference.get()))
        .isEqualTo(
            AddressBook.builder()
                .uid(idByReference.get())
                .name("custom book")
                .origin("provisioning")
                .defaultBook(false)
                .readOnly(false)
                .syncable(true)
                .build());
  }

  @Test
  public void testPostShouldRenameWhenCustomWithKnownReference() throws Exception {
    ObmDomainUuid obmDomainUuid = ObmDomainUuid.of("ac21bc0c-f816-4c52-8bb9-e50cfbfec5b6");

    String creationJson =
        "{"
            + "\"name\":\"creation name\","
            + "\"role\":\"custom\","
            + "\"reference\": {"
            + "\"value\":\"1234\","
            + "\"origin\":\"exchange\""
            + "}"
            + "}";

    String updatingJson =
        "{"
            + "\"name\":\"updating name\","
            + "\"role\":\"custom\","
            + "\"reference\": {"
            + "\"value\":\"1234\","
            + "\"origin\":\"exchange\""
            + "}"
            + "}";

    String batchId1 = startBatch(baseURL, obmDomainUuid);
    createAddressBook(creationJson, obmUser.getLoginAtDomain());
    commitBatch();
    waitForBatchSuccess(batchId1);

    String batchId2 = startBatch(baseURL, obmDomainUuid);
    createAddressBook(updatingJson, obmUser.getLoginAtDomain());
    commitBatch();
    waitForBatchSuccess(batchId2);

    Optional<Id> idByReference =
        addressBookDao.findByReference(new AddressBookReference("1234", "exchange"));
    assertThat(idByReference).isPresent();
    assertThatAddressBookIsSynced(idByReference.get());
    assertThat(addressBookDao.get(idByReference.get()))
        .isEqualTo(
            AddressBook.builder()
                .uid(idByReference.get())
                .name("updating name")
                .origin("provisioning")
                .defaultBook(false)
                .readOnly(false)
                .syncable(true)
                .build());
  }

  @Test
  public void testPostShouldBeIdempotentWhenSameReferenceIsUsed() throws Exception {
    ObmDomainUuid obmDomainUuid = ObmDomainUuid.of("ac21bc0c-f816-4c52-8bb9-e50cfbfec5b6");

    String json =
        "{"
            + "\"name\":\"the collected address book name can't be choosen\","
            + "\"role\":\"collected\","
            + "\"reference\": {"
            + "\"value\":\"1234\","
            + "\"origin\":\"exchange\""
            + "}"
            + "}";

    String batchId1 = startBatch(baseURL, obmDomainUuid);
    createAddressBook(json, obmUser.getLoginAtDomain());
    commitBatch();
    waitForBatchSuccess(batchId1);

    String batchId2 = startBatch(baseURL, obmDomainUuid);
    createAddressBook(json, obmUser.getLoginAtDomain());
    commitBatch();
    waitForBatchSuccess(batchId2);

    Optional<Id> idByReference =
        addressBookDao.findByReference(new AddressBookReference("1234", "exchange"));
    assertThat(idByReference).isPresent();
    assertThat(addressBookDao.get(idByReference.get()))
        .isEqualTo(
            AddressBook.builder()
                .uid(idByReference.get())
                .name("collected_contacts")
                .origin("provisioning")
                .defaultBook(true)
                .readOnly(false)
                .syncable(true)
                .build());
  }

  private void assertThatAddressBookIsSynced(Id addressBookId) throws Exception {
    ResultSet results =
        db.execute(
            "select count(1) from syncedaddressbook "
                + "where addressbook_id="
                + addressBookId.getId()
                + " and user_id="
                + obmUser.getUid());
    results.next();
    assertThat(results.getInt(1)).isEqualTo(1);
  }
}
/** @author kristin.polenz */
@RequiredHistoryLevel(ProcessEngineConfiguration.HISTORY_FULL)
public class MultiTenancyCaseInstanceCmdsTenantCheckTest {

  protected static final String VARIABLE_NAME = "myVar";
  protected static final String VARIABLE_VALUE = "myValue";

  protected static final String TENANT_ONE = "tenant1";

  protected static final String CMMN_MODEL =
      "org/camunda/bpm/engine/test/api/cmmn/twoTaskCase.cmmn";

  protected static final String ACTIVITY_ID = "PI_HumanTask_1";

  protected ProcessEngineRule engineRule = new ProvidedProcessEngineRule();

  protected ProcessEngineTestRule testRule = new ProcessEngineTestRule(engineRule);

  @Rule public RuleChain ruleChain = RuleChain.outerRule(engineRule).around(testRule);

  @Rule public ExpectedException thrown = ExpectedException.none();

  protected IdentityService identityService;
  protected CaseService caseService;
  protected HistoryService historyService;
  protected ProcessEngineConfiguration processEngineConfiguration;

  protected String caseInstanceId;
  protected String caseExecutionId;

  @Before
  public void setUp() {
    processEngineConfiguration = engineRule.getProcessEngineConfiguration();
    identityService = engineRule.getIdentityService();
    caseService = engineRule.getCaseService();
    historyService = engineRule.getHistoryService();

    testRule.deployForTenant(TENANT_ONE, CMMN_MODEL);

    caseInstanceId = createCaseInstance(null);

    caseExecutionId = getCaseExecution().getId();
  }

  @Test
  public void manuallyStartCaseExecutionNoAuthenticatedTenants() {
    identityService.setAuthentication("user", null, null);

    thrown.expect(ProcessEngineException.class);
    thrown.expectMessage("Cannot update the case execution");

    caseService.manuallyStartCaseExecution(caseExecutionId);
  }

  @Test
  public void manuallyStartCaseExecutionWithAuthenticatedTenant() {
    identityService.setAuthentication("user", null, Arrays.asList(TENANT_ONE));

    caseService.manuallyStartCaseExecution(caseExecutionId);

    identityService.clearAuthentication();

    CaseExecution caseExecution = getCaseExecution();

    assertThat(caseExecution.isActive(), is(true));
  }

  @Test
  public void manuallyStartCaseExecutionDisabledTenantCheck() {
    identityService.setAuthentication("user", null, null);
    processEngineConfiguration.setTenantCheckEnabled(false);

    caseService.manuallyStartCaseExecution(caseExecutionId);

    identityService.clearAuthentication();

    CaseExecution caseExecution = getCaseExecution();

    assertThat(caseExecution.isActive(), is(true));
  }

  @Test
  public void disableCaseExecutionNoAuthenticatedTenants() {
    identityService.setAuthentication("user", null, null);

    thrown.expect(ProcessEngineException.class);
    thrown.expectMessage("Cannot update the case execution");

    caseService.disableCaseExecution(caseExecutionId);
  }

  @Test
  public void disableCaseExecutionWithAuthenticatedTenant() {
    identityService.setAuthentication("user", null, Arrays.asList(TENANT_ONE));

    caseService.disableCaseExecution(caseExecutionId);

    identityService.clearAuthentication();

    HistoricCaseActivityInstance historicCaseActivityInstance = getHistoricCaseActivityInstance();

    assertThat(historicCaseActivityInstance, notNullValue());
    assertThat(historicCaseActivityInstance.isDisabled(), is(true));
  }

  @Test
  public void disableCaseExecutionDisabledTenantCheck() {
    identityService.setAuthentication("user", null, null);
    processEngineConfiguration.setTenantCheckEnabled(false);

    caseService.disableCaseExecution(caseExecutionId);

    identityService.clearAuthentication();

    HistoricCaseActivityInstance historicCaseActivityInstance = getHistoricCaseActivityInstance();

    assertThat(historicCaseActivityInstance, notNullValue());
    assertThat(historicCaseActivityInstance.isDisabled(), is(true));
  }

  @Test
  public void reenableCaseExecutionNoAuthenticatedTenants() {
    caseService.disableCaseExecution(caseExecutionId);

    identityService.setAuthentication("user", null, null);

    thrown.expect(ProcessEngineException.class);
    thrown.expectMessage("Cannot update the case execution");

    caseService.reenableCaseExecution(caseExecutionId);
  }

  @Test
  public void reenableCaseExecutionWithAuthenticatedTenant() {
    caseService.disableCaseExecution(caseExecutionId);

    identityService.setAuthentication("user", null, Arrays.asList(TENANT_ONE));

    caseService.reenableCaseExecution(caseExecutionId);

    identityService.clearAuthentication();

    CaseExecution caseExecution = getCaseExecution();

    assertThat(caseExecution.isEnabled(), is(true));
  }

  @Test
  public void reenableCaseExecutionDisabledTenantCheck() {
    caseService.disableCaseExecution(caseExecutionId);

    identityService.setAuthentication("user", null, null);
    processEngineConfiguration.setTenantCheckEnabled(false);

    caseService.reenableCaseExecution(caseExecutionId);

    identityService.clearAuthentication();

    CaseExecution caseExecution = getCaseExecution();

    assertThat(caseExecution.isEnabled(), is(true));
  }

  @Test
  public void completeCaseExecutionNoAuthenticatedTenants() {
    caseService.manuallyStartCaseExecution(caseExecutionId);

    identityService.setAuthentication("user", null, null);

    thrown.expect(ProcessEngineException.class);
    thrown.expectMessage("Cannot update the case execution");

    caseService.completeCaseExecution(caseExecutionId);
  }

  @Test
  public void completeCaseExecutionWithAuthenticatedTenant() {
    caseService.manuallyStartCaseExecution(caseExecutionId);

    identityService.setAuthentication("user", null, Arrays.asList(TENANT_ONE));

    caseService.completeCaseExecution(caseExecutionId);

    identityService.clearAuthentication();

    HistoricCaseActivityInstance historicCaseActivityInstance = getHistoricCaseActivityInstance();

    assertThat(historicCaseActivityInstance, notNullValue());
    assertThat(historicCaseActivityInstance.isCompleted(), is(true));
  }

  @Test
  public void completeCaseExecutionDisabledTenantCheck() {
    caseService.manuallyStartCaseExecution(caseExecutionId);

    identityService.setAuthentication("user", null, null);
    processEngineConfiguration.setTenantCheckEnabled(false);

    caseService.completeCaseExecution(caseExecutionId);

    identityService.clearAuthentication();

    HistoricCaseActivityInstance historicCaseActivityInstance = getHistoricCaseActivityInstance();

    assertThat(historicCaseActivityInstance, notNullValue());
    assertThat(historicCaseActivityInstance.isCompleted(), is(true));
  }

  @Test
  public void closeCaseInstanceNoAuthenticatedTenants() {
    caseService.completeCaseExecution(caseInstanceId);

    identityService.setAuthentication("user", null, null);

    thrown.expect(ProcessEngineException.class);
    thrown.expectMessage("Cannot update the case execution");

    caseService.closeCaseInstance(caseInstanceId);
  }

  @Test
  public void closeCaseInstanceWithAuthenticatedTenant() {
    caseService.completeCaseExecution(caseInstanceId);

    identityService.setAuthentication("user", null, Arrays.asList(TENANT_ONE));

    caseService.closeCaseInstance(caseInstanceId);

    identityService.clearAuthentication();

    HistoricCaseInstance historicCaseInstance = getHistoricCaseInstance();

    assertThat(historicCaseInstance, notNullValue());
    assertThat(historicCaseInstance.isClosed(), is(true));
  }

  @Test
  public void closeCaseInstanceDisabledTenantCheck() {
    caseService.completeCaseExecution(caseInstanceId);

    identityService.setAuthentication("user", null, null);
    processEngineConfiguration.setTenantCheckEnabled(false);

    caseService.closeCaseInstance(caseInstanceId);

    identityService.clearAuthentication();

    HistoricCaseInstance historicCaseInstance = getHistoricCaseInstance();

    assertThat(historicCaseInstance, notNullValue());
    assertThat(historicCaseInstance.isClosed(), is(true));
  }

  @Test
  public void getVariablesNoAuthenticatedTenants() {
    identityService.setAuthentication("user", null, null);

    thrown.expect(ProcessEngineException.class);
    thrown.expectMessage("Cannot get the case execution");

    caseService.getVariables(caseExecutionId);
  }

  @Test
  public void getVariablesWithAuthenticatedTenant() {
    identityService.setAuthentication("user", null, Arrays.asList(TENANT_ONE));

    Map<String, Object> variables = caseService.getVariables(caseExecutionId);

    assertThat(variables, notNullValue());
    assertThat(variables.keySet(), hasItem(VARIABLE_NAME));
  }

  @Test
  public void getVariablesDisabledTenantCheck() {
    identityService.setAuthentication("user", null, null);
    processEngineConfiguration.setTenantCheckEnabled(false);

    Map<String, Object> variables = caseService.getVariables(caseExecutionId);

    assertThat(variables, notNullValue());
    assertThat(variables.keySet(), hasItem(VARIABLE_NAME));
  }

  @Test
  public void getVariableNoAuthenticatedTenants() {
    identityService.setAuthentication("user", null, null);

    thrown.expect(ProcessEngineException.class);
    thrown.expectMessage("Cannot get the case execution");

    caseService.getVariable(caseExecutionId, VARIABLE_NAME);
  }

  @Test
  public void getVariableWithAuthenticatedTenant() {
    identityService.setAuthentication("user", null, Arrays.asList(TENANT_ONE));

    String variableValue = (String) caseService.getVariable(caseExecutionId, VARIABLE_NAME);

    assertThat(variableValue, is(VARIABLE_VALUE));
  }

  @Test
  public void getVariableDisabledTenantCheck() {
    identityService.setAuthentication("user", null, null);
    processEngineConfiguration.setTenantCheckEnabled(false);

    String variableValue = (String) caseService.getVariable(caseExecutionId, VARIABLE_NAME);

    assertThat(variableValue, is(VARIABLE_VALUE));
  }

  @Test
  public void getVariableTypedNoAuthenticatedTenants() {
    identityService.setAuthentication("user", null, null);

    thrown.expect(ProcessEngineException.class);
    thrown.expectMessage("Cannot get the case execution");

    caseService.getVariableTyped(caseExecutionId, VARIABLE_NAME);
  }

  @Test
  public void getVariableTypedWithAuthenticatedTenant() {
    identityService.setAuthentication("user", null, Arrays.asList(TENANT_ONE));

    StringValue variable = caseService.getVariableTyped(caseExecutionId, VARIABLE_NAME);

    assertThat(variable.getValue(), is(VARIABLE_VALUE));
  }

  @Test
  public void getVariableTypedDisabledTenantCheck() {
    identityService.setAuthentication("user", null, null);
    processEngineConfiguration.setTenantCheckEnabled(false);

    StringValue variable = caseService.getVariableTyped(caseExecutionId, VARIABLE_NAME);

    assertThat(variable.getValue(), is(VARIABLE_VALUE));
  }

  @Test
  public void removeVariablesNoAuthenticatedTenants() {
    identityService.setAuthentication("user", null, null);

    thrown.expect(ProcessEngineException.class);
    thrown.expectMessage("Cannot update the case execution");

    caseService.removeVariable(caseExecutionId, VARIABLE_NAME);
  }

  @Test
  public void removeVariablesWithAuthenticatedTenant() {
    identityService.setAuthentication("user", null, Arrays.asList(TENANT_ONE));

    caseService.removeVariable(caseExecutionId, VARIABLE_NAME);

    identityService.clearAuthentication();

    Map<String, Object> variables = caseService.getVariables(caseExecutionId);
    assertThat(variables.isEmpty(), is(true));
  }

  @Test
  public void removeVariablesDisabledTenantCheck() {
    identityService.setAuthentication("user", null, null);
    processEngineConfiguration.setTenantCheckEnabled(false);

    caseService.removeVariable(caseExecutionId, VARIABLE_NAME);

    identityService.clearAuthentication();

    Map<String, Object> variables = caseService.getVariables(caseExecutionId);
    assertThat(variables.isEmpty(), is(true));
  }

  @Test
  public void setVariableNoAuthenticatedTenants() {
    identityService.setAuthentication("user", null, null);

    thrown.expect(ProcessEngineException.class);
    thrown.expectMessage("Cannot update the case execution");

    caseService.setVariable(caseExecutionId, "newVar", "newValue");
  }

  @Test
  public void setVariableWithAuthenticatedTenant() {
    identityService.setAuthentication("user", null, Arrays.asList(TENANT_ONE));

    caseService.setVariable(caseExecutionId, "newVar", "newValue");

    identityService.clearAuthentication();

    Map<String, Object> variables = caseService.getVariables(caseExecutionId);
    assertThat(variables, notNullValue());
    assertThat(variables.keySet(), hasItems(VARIABLE_NAME, "newVar"));
  }

  @Test
  public void setVariableDisabledTenantCheck() {
    identityService.setAuthentication("user", null, null);
    processEngineConfiguration.setTenantCheckEnabled(false);

    caseService.setVariable(caseExecutionId, "newVar", "newValue");

    identityService.clearAuthentication();

    Map<String, Object> variables = caseService.getVariables(caseExecutionId);
    assertThat(variables, notNullValue());
    assertThat(variables.keySet(), hasItems(VARIABLE_NAME, "newVar"));
  }

  protected String createCaseInstance(String tenantId) {
    VariableMap variables = Variables.putValue(VARIABLE_NAME, VARIABLE_VALUE);
    CaseInstanceBuilder builder =
        caseService.withCaseDefinitionByKey("twoTaskCase").setVariables(variables);
    if (tenantId == null) {
      return builder.create().getId();
    } else {
      return builder.caseDefinitionTenantId(tenantId).create().getId();
    }
  }

  protected CaseExecution getCaseExecution() {
    return caseService.createCaseExecutionQuery().activityId(ACTIVITY_ID).singleResult();
  }

  protected HistoricCaseActivityInstance getHistoricCaseActivityInstance() {
    return historyService
        .createHistoricCaseActivityInstanceQuery()
        .caseActivityId(ACTIVITY_ID)
        .singleResult();
  }

  protected HistoricCaseInstance getHistoricCaseInstance() {
    return historyService
        .createHistoricCaseInstanceQuery()
        .caseInstanceId(caseInstanceId)
        .singleResult();
  }
}
示例#18
0
/**
 * @author <a href="mailto:[email protected]">Bill Burke</a>
 * @version $Revision: 1 $
 */
public class SamlPicketlinkSPTest {

  // This test is ignored in IBM JDK due to the IBM JDK bug, which is handled in Keycloak SP (
  // org.keycloak.saml.common.parsers.AbstractParser ) but not in Picketlink SP
  public static TestRule ignoreIBMJDK =
      new TestRule() {

        @Override
        public Statement apply(final Statement base, final Description description) {
          return new Statement() {

            @Override
            public void evaluate() throws Throwable {
              if (Environment.IS_IBM_JAVA) {
                System.err.println(
                    "Ignore " + description.getDisplayName() + " because executing on IBM JDK");
              } else {
                base.evaluate();
              }
            }
          };
        }
      };

  public static SamlKeycloakRule keycloakRule =
      new SamlKeycloakRule() {
        @Override
        public void initWars() {
          ClassLoader classLoader = SamlPicketlinkSPTest.class.getClassLoader();

          initializeSamlSecuredWar("/saml/simple-post", "/sales-post", "post.war", classLoader);
          initializeSamlSecuredWar(
              "/saml/signed-post", "/sales-post-sig", "post-sig.war", classLoader);
          initializeSamlSecuredWar(
              "/saml/signed-post-email",
              "/sales-post-sig-email",
              "post-sig-email.war",
              classLoader);
          initializeSamlSecuredWar(
              "/saml/signed-post-transient",
              "/sales-post-sig-transient",
              "post-sig-transient.war",
              classLoader);
          initializeSamlSecuredWar(
              "/saml/signed-post-persistent",
              "/sales-post-sig-persistent",
              "post-sig-persistent.war",
              classLoader);
          initializeSamlSecuredWar(
              "/saml/signed-metadata", "/sales-metadata", "post-metadata.war", classLoader);
          initializeSamlSecuredWar(
              "/saml/signed-get", "/employee-sig", "employee-sig.war", classLoader);
          // initializeSamlSecuredWar("/saml/simple-get", "/employee",  "employee.war",
          // classLoader);
          initializeSamlSecuredWar(
              "/saml/signed-front-get",
              "/employee-sig-front",
              "employee-sig-front.war",
              classLoader);
          initializeSamlSecuredWar(
              "/saml/bad-client-signed-post",
              "/bad-client-sales-post-sig",
              "bad-client-post-sig.war",
              classLoader);
          initializeSamlSecuredWar(
              "/saml/bad-realm-signed-post",
              "/bad-realm-sales-post-sig",
              "bad-realm-post-sig.war",
              classLoader);
          initializeSamlSecuredWar(
              "/saml/encrypted-post", "/sales-post-enc", "post-enc.war", classLoader);
          uploadSP();
          server
              .getServer()
              .deploy(createDeploymentInfo("employee.war", "/employee", SamlSPFacade.class));
        }

        @Override
        public String getRealmJson() {
          return "/saml/testsaml.json";
        }
      };

  @ClassRule public static TestRule chain = RuleChain.outerRule(ignoreIBMJDK).around(keycloakRule);

  public static class SamlSPFacade extends HttpServlet {
    public static String samlResponse;
    public static String RELAY_STATE = "http://test.com/foo/bar";
    public static String sentRelayState;

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp)
        throws ServletException, IOException {
      handler(req, resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp)
        throws ServletException, IOException {
      handler(req, resp);
    }

    private void handler(HttpServletRequest req, HttpServletResponse resp) {
      System.out.println("********* HERE ******");
      if (req.getParameterMap().isEmpty()) {
        System.out.println("redirecting");
        resp.setStatus(302);
        // Redirect
        // UriBuilder builder =
        // UriBuilder.fromUri("http://localhost:8081/auth/realms/demo/protocol/saml?SAMLRequest=jVLRTsIwFP2Vpe%2BjG4wxG0YyWYxL0BBAH3wx3XYnTbp29nYof%2B8YEvEBNOlD03vOveec2ynyWjYsae1WreC9BbTOZy0Vsr4Qk9YopjkKZIrXgMwWbJ08LNhw4LHGaKsLLcmRch3MEcFYoRVxktN1rhW2NZg1mJ0o4Gm1iMnW2oZRKnXB5VajZZEX%2BRTqRuo9ACVO2mkUih%2F4l9C8s0MNcFkjLaHW9KSUHlwR506bAnrPMam4RCBOlsYkS1%2BD3MvLcDJxAx9KN4jCkXszrG5cP%2BCVH4y8IM8PYFx2dsQOfuiILWQKLVc2JkPPH7te6HrRxh%2BzUdidwSSIXoiz%2FBZyK1Qp1Nv1yPIjCNn9ZrN0V1AKA4UlzjMY7N13IDKbHjyxXoA5291%2FtzH7I%2FApPet%2FHNawx65hli61FMXeSaTUH%2FMubtvlYU0LfcA1t5cl%2BAO%2FfxGlW%2FVQ1ipsoBCVgJLQ2XHo7385%2BwI%3D");
        UriBuilder builder =
            UriBuilder.fromUri(
                "http://localhost:8081/auth/realms/demo/protocol/saml?SAMLRequest=jVJbT8IwFP4rS99HuwluNIwEIUYSLwugD76Y2h2kSdfOng7l31uGRn0ATfrQ9HznfJfTEYpaN3zS%2Bo1ZwGsL6KP3WhvkXaEgrTPcClTIjagBuZd8Obm55mmP8cZZb6XV5NByGiwQwXllDYkmX9epNdjW4JbgtkrC%2FeK6IBvvG06ptlLojUXPc5YnFOpG2x0AJdEsaFRG7PuPoUWwQx0IXSOtoLb0SynduyLRpXUSOs8FWQuNQKL5rCDz2VO%2FymEgIY2zlJ3H%2FSx9jkU%2BzOK0ys8yNmSSsUEAYxnsqC18tyO2MDfohfEFSVkyiNlZzM5XacrDSbJePug%2Fkqj8FHKhTKXMy%2BnIng8g5FerVRmXd8sViR7AYec8AMh4tPfDO3L3Y2%2F%2F3cT4j7BH9Mf8A1nDb8PA%2Bay0WsldNNHavk1D1D5k4V0LXbi18MclJL2ke1FVvO6gvDXYgFRrBRWh4wPp7z85%2FgA%3D");
        builder.queryParam("RelayState", RELAY_STATE);
        resp.setHeader("Location", builder.build().toString());
        return;
      }
      System.out.println("received response");
      samlResponse = req.getParameter("SAMLResponse");
      sentRelayState = req.getParameter("RelayState");
    }
  }

  @Rule public WebRule webRule = new WebRule(this);
  @WebResource protected WebDriver driver;
  @WebResource protected LoginPage loginPage;

  protected void checkLoggedOut(String mainUrl, boolean postBinding) {
    String pageSource = driver.getPageSource();
    System.out.println("*** logout pagesouce ***");
    System.out.println(pageSource);
    System.out.println("driver url: " + driver.getCurrentUrl());
    Assert.assertTrue(pageSource.contains("request-path: /logout.jsp"));
    driver.navigate().to(mainUrl);
    checkAtLoginPage(postBinding);
  }

  protected void checkAtLoginPage(boolean postBinding) {
    if (postBinding) assertAtLoginPagePostBinding();
    else assertAtLoginPageRedirectBinding();
  }

  protected void assertAtLoginPageRedirectBinding() {
    Assert.assertTrue(
        driver.getCurrentUrl().startsWith("http://localhost:8081/auth/realms/demo/protocol/saml"));
  }

  protected void assertAtLoginPagePostBinding() {
    Assert.assertTrue(
        driver
            .getCurrentUrl()
            .startsWith("http://localhost:8081/auth/realms/demo/login-actions/authenticate"));
  }

  // @Test
  public void ideTesting() throws Exception {
    Thread.sleep(100000000);
  }

  @Test
  public void testPostSimpleLoginLogout() {
    driver.navigate().to("http://localhost:8081/sales-post/");
    assertAtLoginPagePostBinding();
    loginPage.login("bburke", "password");
    Assert.assertEquals(driver.getCurrentUrl(), "http://localhost:8081/sales-post/");
    System.out.println(driver.getPageSource());
    Assert.assertTrue(driver.getPageSource().contains("bburke"));
    driver.navigate().to("http://localhost:8081/sales-post?GLO=true");
    checkLoggedOut("http://localhost:8081/sales-post/", true);
  }

  @Test
  public void testPostSimpleLoginLogoutIdpInitiated() {
    driver.navigate().to("http://localhost:8081/auth/realms/demo/protocol/saml/clients/sales-post");
    loginPage.login("bburke", "password");
    Assert.assertEquals(driver.getCurrentUrl(), "http://localhost:8081/sales-post/");
    System.out.println(driver.getPageSource());
    Assert.assertTrue(driver.getPageSource().contains("bburke"));
    driver.navigate().to("http://localhost:8081/sales-post?GLO=true");
    checkLoggedOut("http://localhost:8081/sales-post/", true);
  }

  @Test
  public void testPostSignedLoginLogout() {
    driver.navigate().to("http://localhost:8081/sales-post-sig/");
    assertAtLoginPagePostBinding();
    loginPage.login("bburke", "password");
    Assert.assertEquals(driver.getCurrentUrl(), "http://localhost:8081/sales-post-sig/");
    Assert.assertTrue(driver.getPageSource().contains("bburke"));
    driver.navigate().to("http://localhost:8081/sales-post-sig?GLO=true");
    checkLoggedOut("http://localhost:8081/sales-post-sig/", true);
  }

  @Test
  public void testPostSignedLoginLogoutTransientNameID() {
    driver.navigate().to("http://localhost:8081/sales-post-sig-transient/");
    assertAtLoginPagePostBinding();
    loginPage.login("bburke", "password");
    Assert.assertEquals(driver.getCurrentUrl(), "http://localhost:8081/sales-post-sig-transient/");
    System.out.println(driver.getPageSource());
    Assert.assertFalse(driver.getPageSource().contains("bburke"));
    Assert.assertTrue(driver.getPageSource().contains("principal=G-"));
    driver.navigate().to("http://localhost:8081/sales-post-sig-transient?GLO=true");
    checkLoggedOut("http://localhost:8081/sales-post-sig-transient/", true);
  }

  @Test
  public void testPostSignedLoginLogoutPersistentNameID() {
    driver.navigate().to("http://localhost:8081/sales-post-sig-persistent/");
    assertAtLoginPagePostBinding();
    loginPage.login("bburke", "password");
    Assert.assertEquals(driver.getCurrentUrl(), "http://localhost:8081/sales-post-sig-persistent/");
    System.out.println(driver.getPageSource());
    Assert.assertFalse(driver.getPageSource().contains("bburke"));
    Assert.assertTrue(driver.getPageSource().contains("principal=G-"));
    driver.navigate().to("http://localhost:8081/sales-post-sig-persistent?GLO=true");
    checkLoggedOut("http://localhost:8081/sales-post-sig-persistent/", true);
  }

  @Test
  public void testPostSignedLoginLogoutEmailNameID() {
    driver.navigate().to("http://*****:*****@redhat.com"));
    driver.navigate().to("http://localhost:8081/sales-post-sig-email?GLO=true");
    checkLoggedOut("http://localhost:8081/sales-post-sig-email/", true);
  }

  @Test
  public void testRelayStateEncoding() throws Exception {
    // this test has a hardcoded SAMLRequest and we hack a SP face servlet to get the SAMLResponse
    // so we can look
    // at the relay state
    SamlSPFacade.samlResponse = null;
    driver.navigate().to("http://localhost:8081/employee/");
    assertAtLoginPageRedirectBinding();
    System.out.println(driver.getCurrentUrl());
    loginPage.login("bburke", "password");
    Assert.assertEquals(driver.getCurrentUrl(), "http://localhost:8081/employee/");
    Assert.assertEquals(SamlSPFacade.sentRelayState, SamlSPFacade.RELAY_STATE);
    Assert.assertNotNull(SamlSPFacade.samlResponse);
  }

  @Test
  public void testAttributes() throws Exception {
    // this test has a hardcoded SAMLRequest and we hack a SP face servlet to get the SAMLResponse
    // so we can look
    // at the assertions sent.  This is because Picketlink, AFAICT, does not give you any way to get
    // access to
    // the assertion.

    {
      SamlSPFacade.samlResponse = null;
      driver.navigate().to("http://*****:*****@redhat.com");
            email = true;
          } else if (attr.getName().equals("phone")) {
            Assert.assertEquals(
                JBossSAMLURIConstants.ATTRIBUTE_FORMAT_BASIC.get(), attr.getNameFormat());
            Assert.assertEquals(attr.getAttributeValue().get(0), "617");
            phone = true;
          } else if (attr.getName().equals("Role")) {
            if (attr.getAttributeValue().get(0).equals("manager")) managerRole = true;
            if (attr.getAttributeValue().get(0).equals("user")) userRole = true;
          }
        }
      }

      Assert.assertTrue(email);
      Assert.assertTrue(phone);
      Assert.assertTrue(userRole);
      Assert.assertTrue(managerRole);
    }

    keycloakRule.update(
        new KeycloakRule.KeycloakSetup() {
          @Override
          public void config(
              RealmManager manager, RealmModel adminstrationRealm, RealmModel appRealm) {
            ClientModel app = appRealm.getClientByClientId("http://localhost:8081/employee/");
            for (ProtocolMapperModel mapper : app.getProtocolMappers()) {
              if (mapper.getName().equals("role-list")) {
                app.removeProtocolMapper(mapper);
                mapper.setId(null);
                mapper.getConfig().put(RoleListMapper.SINGLE_ROLE_ATTRIBUTE, "true");
                mapper.getConfig().put(AttributeStatementHelper.SAML_ATTRIBUTE_NAME, "memberOf");
                app.addProtocolMapper(mapper);
              }
            }
            app.addProtocolMapper(
                HardcodedAttributeMapper.create(
                    "hardcoded-attribute",
                    "hardcoded-attribute",
                    "Basic",
                    null,
                    "hard",
                    false,
                    null));
            app.addProtocolMapper(HardcodedRole.create("hardcoded-role", "hardcoded-role"));
            app.addProtocolMapper(RoleNameMapper.create("renamed-role", "manager", "el-jefe"));
            app.addProtocolMapper(
                RoleNameMapper.create(
                    "renamed-employee-role", "http://localhost:8081/employee/.employee", "pee-on"));
          }
        },
        "demo");

    System.out.println(">>>>>>>>>> single role attribute <<<<<<<<");

    {
      SamlSPFacade.samlResponse = null;
      driver.navigate().to("http://localhost:8081/employee/");
      System.out.println(driver.getCurrentUrl());
      Assert.assertEquals(driver.getCurrentUrl(), "http://localhost:8081/employee/");
      Assert.assertNotNull(SamlSPFacade.samlResponse);
      SAML2Response saml2Response = new SAML2Response();
      byte[] samlResponse = PostBindingUtil.base64Decode(SamlSPFacade.samlResponse);
      ResponseType rt = saml2Response.getResponseType(new ByteArrayInputStream(samlResponse));
      Assert.assertTrue(rt.getAssertions().size() == 1);
      AssertionType assertion = rt.getAssertions().get(0).getAssertion();

      // test attributes and roles

      boolean userRole = false;
      boolean managerRole = false;
      boolean single = false;
      boolean hardcodedRole = false;
      boolean hardcodedAttribute = false;
      boolean peeOn = false;
      for (AttributeStatementType statement : assertion.getAttributeStatements()) {
        for (AttributeStatementType.ASTChoiceType choice : statement.getAttributes()) {
          AttributeType attr = choice.getAttribute();
          if (attr.getName().equals("memberOf")) {
            if (single) Assert.fail("too many role attributes");
            single = true;
            for (Object value : attr.getAttributeValue()) {
              if (value.equals("el-jefe")) managerRole = true;
              if (value.equals("user")) userRole = true;
              if (value.equals("hardcoded-role")) hardcodedRole = true;
              if (value.equals("pee-on")) peeOn = true;
            }
          } else if (attr.getName().equals("hardcoded-attribute")) {
            hardcodedAttribute = true;
            Assert.assertEquals(attr.getAttributeValue().get(0), "hard");
          }
        }
      }

      Assert.assertTrue(single);
      Assert.assertTrue(hardcodedAttribute);
      Assert.assertTrue(hardcodedRole);
      Assert.assertTrue(peeOn);
      Assert.assertTrue(userRole);
      Assert.assertTrue(managerRole);
    }
  }

  @Test
  public void testRedirectSignedLoginLogout() {
    driver.navigate().to("http://localhost:8081/employee-sig/");
    assertAtLoginPageRedirectBinding();
    loginPage.login("bburke", "password");
    Assert.assertEquals(driver.getCurrentUrl(), "http://localhost:8081/employee-sig/");
    Assert.assertTrue(driver.getPageSource().contains("bburke"));
    driver.navigate().to("http://localhost:8081/employee-sig?GLO=true");
    checkLoggedOut("http://localhost:8081/employee-sig/", false);
  }

  @Test
  public void testRedirectSignedLoginLogoutFrontNoSSO() {
    driver.navigate().to("http://localhost:8081/employee-sig-front/");
    assertAtLoginPageRedirectBinding();
    loginPage.login("bburke", "password");
    Assert.assertEquals(driver.getCurrentUrl(), "http://localhost:8081/employee-sig-front/");
    Assert.assertTrue(driver.getPageSource().contains("bburke"));
    driver.navigate().to("http://localhost:8081/employee-sig-front?GLO=true");
    checkLoggedOut("http://localhost:8081/employee-sig-front/", false);
  }

  @Test
  public void testRedirectSignedLoginLogoutFront() {
    // visit 1st app an logg in
    System.out.println("visit 1st app ");
    driver.navigate().to("http://localhost:8081/employee-sig/");
    assertAtLoginPageRedirectBinding();
    System.out.println("login to form");
    loginPage.login("bburke", "password");
    Assert.assertEquals(driver.getCurrentUrl(), "http://localhost:8081/employee-sig/");
    Assert.assertTrue(driver.getPageSource().contains("bburke"));

    // visit 2nd app
    System.out.println("visit 2nd app ");
    driver.navigate().to("http://localhost:8081/employee-sig-front/");
    Assert.assertEquals(driver.getCurrentUrl(), "http://localhost:8081/employee-sig-front/");
    Assert.assertTrue(driver.getPageSource().contains("bburke"));

    // visit 3rd app
    System.out.println("visit 3rd app ");
    driver.navigate().to("http://localhost:8081/sales-post-sig/");
    Assert.assertEquals(driver.getCurrentUrl(), "http://localhost:8081/sales-post-sig/");
    Assert.assertTrue(driver.getPageSource().contains("bburke"));

    // logout of first app
    System.out.println("GLO");
    driver.navigate().to("http://localhost:8081/employee-sig?GLO=true");
    checkLoggedOut("http://localhost:8081/employee-sig/", false);
    driver.navigate().to("http://localhost:8081/employee-sig-front/");
    assertAtLoginPageRedirectBinding();
    driver.navigate().to("http://localhost:8081/sales-post-sig/");
    assertAtLoginPagePostBinding();
  }

  @Test
  public void testPostEncryptedLoginLogout() {
    driver.navigate().to("http://localhost:8081/sales-post-enc/");
    assertAtLoginPagePostBinding();
    loginPage.login("bburke", "password");
    Assert.assertEquals(driver.getCurrentUrl(), "http://localhost:8081/sales-post-enc/");
    Assert.assertTrue(driver.getPageSource().contains("bburke"));
    driver.navigate().to("http://localhost:8081/sales-post-enc?GLO=true");
    checkLoggedOut("http://localhost:8081/sales-post-enc/", true);
  }

  @Test
  public void testPostBadClientSignature() {
    driver.navigate().to("http://localhost:8081/bad-client-sales-post-sig/");
    Assert.assertEquals(
        driver.getCurrentUrl(), "http://localhost:8081/auth/realms/demo/protocol/saml");
    Assert.assertEquals(driver.getTitle(), "We're sorry...");
  }

  @Test
  public void testPostBadRealmSignature() {
    driver.navigate().to("http://localhost:8081/bad-realm-sales-post-sig/");
    assertAtLoginPagePostBinding();
    loginPage.login("bburke", "password");
    Assert.assertEquals(driver.getCurrentUrl(), "http://localhost:8081/bad-realm-sales-post-sig/");
    Assert.assertTrue(driver.getPageSource().contains("null"));
  }

  @Test
  public void testPassiveMode() {
    // KEYCLOAK-2075 test SAML IsPassive handling - PicketLink SP client library doesn't support
    // this option unfortunately.
    // But the test of server side is included in test of SAML Keycloak adapter
  }

  @Test
  public void testMetadataPostSignedLoginLogout() throws Exception {

    driver.navigate().to("http://localhost:8081/sales-metadata/");
    assertAtLoginPagePostBinding();
    loginPage.login("bburke", "password");
    Assert.assertEquals(driver.getCurrentUrl(), "http://localhost:8081/sales-metadata/");
    String pageSource = driver.getPageSource();
    Assert.assertTrue(pageSource.contains("bburke"));
    driver.navigate().to("http://localhost:8081/sales-metadata?GLO=true");
    checkLoggedOut("http://localhost:8081/sales-metadata/", true);
  }

  public static void uploadSP() {
    try {
      Keycloak keycloak =
          Keycloak.getInstance(
              "http://localhost:8081/auth",
              "master",
              "admin",
              "admin",
              Constants.ADMIN_CLI_CLIENT_ID,
              null);
      RealmResource admin = keycloak.realm("demo");

      admin.toRepresentation();

      ClientRepresentation clientRep =
          admin.convertClientDescription(
              IOUtils.toString(
                  SamlPicketlinkSPTest.class.getResourceAsStream("/saml/sp-metadata.xml")));
      Response response = admin.clients().create(clientRep);

      assertEquals(201, response.getStatus());

      keycloak.close();
    } catch (IOException e) {
      throw new RuntimeException(e);
    }
  }
}
/**
 * This class tests BO functionality.
 *
 * <p>
 *
 * @author Barry.Grotjahn
 * @version $Revision$
 */
public class BusinessObjectsTest {
  private static final UsernamePasswordPair ADMIN_USER_PWD_PAIR =
      new UsernamePasswordPair(MOTU, MOTU);

  private final TestMethodSetup testMethodSetup =
      new TestMethodSetup(ADMIN_USER_PWD_PAIR, testClassSetup);
  private final TestServiceFactory sf = new TestServiceFactory(ADMIN_USER_PWD_PAIR);

  @ClassRule
  public static final TestClassSetup testClassSetup =
      new TestClassSetup(
          ADMIN_USER_PWD_PAIR, ForkingServiceMode.NATIVE_THREADING, MODEL_NAME2, MODEL_NAME3);

  @Rule public final TestRule chain = RuleChain.outerRule(testMethodSetup).around(sf);

  @Before
  public void setup() {
    for (int customerId = 1; customerId <= 5; customerId++) {
      ProcessInstance pi =
          sf.getWorkflowService()
              .startProcess(new QName(MODEL_NAME2, "OrderCreation").toString(), null, true);
      List<ActivityInstance> w = getWorklist();
      Assert.assertEquals("worklist", 1, w.size());
      ActivityInstance ai = w.get(0);
      Assert.assertEquals("process instance", pi.getOID(), ai.getProcessInstanceOID());
      Assert.assertEquals("activity instance", "EnterOrderData", ai.getActivity().getId());
      Map<String, Object> order = CollectionUtils.newMap();
      order.put("date", new Date());
      order.put("customerId", customerId);
      ai =
          complete(
              ai, PredefinedConstants.DEFAULT_CONTEXT, Collections.singletonMap("Order", order));

      try {
        ProcessInstanceStateBarrier.instance().await(pi.getOID(), ProcessInstanceState.Completed);
      } catch (Exception e) {
      }
      w = getWorklist();
    }
  }

  /**
   * Validate if BusinessObjectQuery returns business objects which are defined in the models
   * MODEL_NAME2 and MODEL_NAME3. Note: If BusinessObjectsList is executed standalone than
   * bos.size() == expected.size(). But if it is executed after CheckFiltering2 then bos.size() >
   * expected.size() because CheckFiltering2 deployes MODEL_NAME3 as a new version. This means that
   * bos.size() == expected.size()+2 in this case.
   */
  @Test
  public void BusinessObjectsList() {
    BusinessObjectQuery query = BusinessObjectQuery.findAll();
    query.setPolicy(new BusinessObjectQuery.Policy(BusinessObjectQuery.Option.WITH_DESCRIPTION));

    BusinessObjects bos = sf.getQueryService().getAllBusinessObjects(query);

    List<String> expected =
        CollectionUtils.newArrayListFromElements(
            Arrays.asList(
                new QName(MODEL_NAME2, "Account").toString(),
                new QName(MODEL_NAME2, "Customer").toString(),
                new QName(MODEL_NAME2, "Order").toString(),
                new QName(MODEL_NAME2, "Fund").toString(),
                new QName(MODEL_NAME2, "FundGroup").toString(),
                new QName(MODEL_NAME3, "Employee").toString(),
                new QName(MODEL_NAME3, "Fund").toString()));

    List<String> removedEntries = CollectionUtils.newArrayList(expected.size());

    for (BusinessObject bo : bos) {
      String qualifiedBOId = new QName(bo.getModelId(), bo.getId()).toString();
      if (expected.remove(qualifiedBOId)) {
        removedEntries.add(qualifiedBOId);
      } else {
        Assert.assertTrue(
            "Not expected entry: " + qualifiedBOId, removedEntries.contains(qualifiedBOId));
      }
    }
    Assert.assertTrue("Missing business objects: " + expected, expected.isEmpty());
  }

  /**
   * Test if the business object query returns all business object instances for a given business
   * object id. The BO instances was created by the OrderCreation process resp. EnterOrderData
   * activity in the setup() method.
   */
  @Test
  public void CheckOrders() {
    DeployedModelDescription model =
        sf.getQueryService().getModels(DeployedModelQuery.findActiveForId(MODEL_NAME2)).get(0);

    BusinessObjectQuery query =
        BusinessObjectQuery.findForBusinessObject(new QName(model.getId(), "Order").toString());
    query.setPolicy(new BusinessObjectQuery.Policy(BusinessObjectQuery.Option.WITH_VALUES));

    BusinessObjects bos = sf.getQueryService().getAllBusinessObjects(query);
    Assert.assertEquals("Objects", 1, bos.getSize());
    BusinessObject bo = bos.get(0);
    List<BusinessObject.Value> values = bo.getValues();
    Assert.assertTrue("Expected at least 5 values: " + values.size(), 5 <= values.size());
    checkValue(values, false, "customerId", 1, 2, 3, 4, 5);
  }

  /**
   * Create business object instances via API (not via process instances) and validate if they're
   * created and if a business object query for a given primary key returns the corresponding BO.
   */
  @Test
  public void CreateCustomersCheck() {
    DeployedModelDescription model =
        sf.getQueryService().getModels(DeployedModelQuery.findActiveForId(MODEL_NAME2)).get(0);
    for (int i = 1; i <= 3; i++) {
      createCustomer(model, i);
    }

    String businessObjectQualifiedId = new QName(model.getId(), "Customer").toString();
    BusinessObjectQuery query =
        BusinessObjectQuery.findForBusinessObject(businessObjectQualifiedId);
    query.setPolicy(new BusinessObjectQuery.Policy(BusinessObjectQuery.Option.WITH_VALUES));
    BusinessObjects bos = sf.getQueryService().getAllBusinessObjects(query);
    Assert.assertEquals("Objects", 1, bos.getSize());
    BusinessObject bo = bos.get(0);
    List<BusinessObject.Value> values = bo.getValues();
    Assert.assertEquals("Values", 3, values.size());

    query = BusinessObjectQuery.findWithPrimaryKey(businessObjectQualifiedId, 2);
    query.setPolicy(new BusinessObjectQuery.Policy(BusinessObjectQuery.Option.WITH_VALUES));
    bos = sf.getQueryService().getAllBusinessObjects(query);
    Assert.assertEquals("Objects", 1, bos.getSize());
    bo = bos.get(0);
    values = bo.getValues();
    Assert.assertEquals("Values", 1, values.size());
    checkValue(values, true, "firstName", "Danny2");
  }

  /**
   * Validate if BO instances can be created once only with the same primary key and that they can
   * be queried either via findWithPrimaryKey() or with help of data filters.
   */
  @Test
  public void CreateOrdersCheck() {
    DeployedModelDescription model =
        sf.getQueryService().getModels(DeployedModelQuery.findActiveForId(MODEL_NAME2)).get(0);
    createOrder(model, 666);
    try {
      createOrder(model, 666);
      Assert.fail("Extected BPMRT03825 error message");
    } catch (ObjectExistsException ex) {
      Assert.assertEquals("Error code", "BPMRT03825", ex.getError().getId());
    }

    String businessObjectQualifiedId = new QName(model.getId(), "Order").toString();
    BusinessObjectQuery query =
        BusinessObjectQuery.findWithPrimaryKey(businessObjectQualifiedId, 666);
    query.setPolicy(new BusinessObjectQuery.Policy(BusinessObjectQuery.Option.WITH_VALUES));
    BusinessObjects bos = sf.getQueryService().getAllBusinessObjects(query);
    Assert.assertEquals("Objects", 1, bos.getSize());
    BusinessObject bo = bos.get(0);
    List<Value> values = bo.getValues();
    Assert.assertEquals("Values", 1, values.size());
    checkValue(values, true, "customerId", 666);

    query = BusinessObjectQuery.findForBusinessObject(businessObjectQualifiedId);
    query
        .getFilter()
        .addOrTerm()
        .or(DataFilter.isEqual("Order", "customerId", 2))
        .or(DataFilter.isEqual("Order", "customerId", 4));
    query.setPolicy(new BusinessObjectQuery.Policy(BusinessObjectQuery.Option.WITH_VALUES));
    bos = sf.getQueryService().getAllBusinessObjects(query);
    Assert.assertEquals("Objects", 1, bos.getSize());
    bo = bos.get(0);
    values = bo.getValues();
    Assert.assertEquals("Values", 2, values.size());
    checkValue(values, true, "customerId", 2, 4);
  }

  /** Test if a field, other than the primary key, of a BO instance can be modified. */
  @Test
  public void ModifyOrdersCheck() {
    DeployedModelDescription model =
        sf.getQueryService().getModels(DeployedModelQuery.findActiveForId(MODEL_NAME2)).get(0);
    BusinessObject bo = createOrder(model, 777);
    @SuppressWarnings("unchecked")
    final Map<String, Object> order = (Map<String, Object>) bo.getValues().get(0).getValue();
    Date date = (Date) order.get("date");
    order.put("date", new Date(date.getTime() + TIME_LAPSE));
    sf.getWorkflowService()
        .updateBusinessObjectInstance(
            new QName(model.getId(), "Order").toString(), (Serializable) order);
    BusinessObjectQuery query =
        BusinessObjectQuery.findWithPrimaryKey(new QName(model.getId(), "Order").toString(), 777);
    query.setPolicy(new BusinessObjectQuery.Policy(BusinessObjectQuery.Option.WITH_VALUES));
    BusinessObjects bos = sf.getQueryService().getAllBusinessObjects(query);
    bo = bos.get(0);
    @SuppressWarnings("unchecked")
    Map<String, Object> updatedOrder = (Map<String, Object>) bo.getValues().get(0).getValue();
    Date updatedDate = (Date) updatedOrder.get("date");
    Assert.assertEquals("Time difference", TIME_LAPSE, updatedDate.getTime() - date.getTime());
  }

  /** Check if an already created BO instance can be deleted and created again later. */
  @Test
  public void DeleteOrdersCheck() {
    DeployedModelDescription model =
        sf.getQueryService().getModels(DeployedModelQuery.findActiveForId(MODEL_NAME2)).get(0);
    createOrder(model, 888);
    BusinessObjectQuery query =
        BusinessObjectQuery.findWithPrimaryKey(new QName(model.getId(), "Order").toString(), 888);
    query.setPolicy(new BusinessObjectQuery.Policy(BusinessObjectQuery.Option.WITH_VALUES));
    BusinessObjects bos = sf.getQueryService().getAllBusinessObjects(query);
    Assert.assertEquals("Values", 1, bos.getSize());

    sf.getWorkflowService()
        .deleteBusinessObjectInstance(new QName(model.getId(), "Order").toString(), 888);

    bos = sf.getQueryService().getAllBusinessObjects(query);
    Assert.assertEquals("Values", 0, bos.getSize());
    createOrder(model, 888);
    bos = sf.getQueryService().getAllBusinessObjects(query);
    Assert.assertEquals("Values", 1, bos.getSize());
  }

  /**
   * Create some instances for a given BO and validate if they can be queried:
   *
   * <ul>
   *   <li>where the qualified business object id is set
   *   <li>the primary key is passed to findForBusinessObject()
   *   <li>the qualified business object id is passed to findForBusinessObject and the primary key
   *       is set as a data filter
   *   <li>the qualified business object id is passed to findForBusinessObject and an attribute of
   *       the BO is set as a data filter
   * </ul>
   */
  @Test
  public void CheckFiltering() throws Exception {
    DeployedModelDescription model =
        sf.getQueryService().getModels(DeployedModelQuery.findActiveForId(MODEL_NAME3)).get(0);

    String businessObjectQualifiedId = new QName(model.getId(), "Fund").toString();
    for (int i = 1; i <= 9; i++) {
      final Map<String, Object> fund = CollectionUtils.newMap();
      fund.put("AccountNumber", "100100" + i);
      fund.put("AccountName", "Fund" + i);

      sf.getWorkflowService()
          .createBusinessObjectInstance(businessObjectQualifiedId, (Serializable) fund);
    }

    BusinessObjectQuery query =
        BusinessObjectQuery.findForBusinessObject(businessObjectQualifiedId);
    query.setPolicy(new BusinessObjectQuery.Policy(BusinessObjectQuery.Option.WITH_VALUES));
    BusinessObjects bos = sf.getQueryService().getAllBusinessObjects(query);
    Assert.assertEquals("Objects", 1, bos.getSize());
    BusinessObject bo = bos.get(0);
    List<BusinessObject.Value> values = bo.getValues();
    Assert.assertEquals("Values", 9, values.size());

    query = BusinessObjectQuery.findWithPrimaryKey(businessObjectQualifiedId, "1001003");
    query.setPolicy(new BusinessObjectQuery.Policy(BusinessObjectQuery.Option.WITH_VALUES));
    bos = sf.getQueryService().getAllBusinessObjects(query);
    Assert.assertEquals("Objects", 1, bos.getSize());
    bo = bos.get(0);
    values = bo.getValues();
    Assert.assertEquals("Values", 1, values.size());
    checkValue(values, true, "AccountNumber", "1001003");

    query = BusinessObjectQuery.findForBusinessObject(businessObjectQualifiedId);
    query.where(DataFilter.isEqual("Fund", "AccountNumber", "1001005"));
    query.setPolicy(new BusinessObjectQuery.Policy(BusinessObjectQuery.Option.WITH_VALUES));
    bos = sf.getQueryService().getAllBusinessObjects(query);
    Assert.assertEquals("Objects", 1, bos.getSize());
    bo = bos.get(0);
    values = bo.getValues();
    Assert.assertEquals("Values", 1, values.size());
    checkValue(values, true, "AccountNumber", "1001005");

    query = BusinessObjectQuery.findForBusinessObject(businessObjectQualifiedId);
    query.where(DataFilter.isEqual("Fund", "AccountName", "Fund7"));
    query.setPolicy(new BusinessObjectQuery.Policy(BusinessObjectQuery.Option.WITH_VALUES));
    bos = sf.getQueryService().getAllBusinessObjects(query);
    Assert.assertEquals("Objects", 1, bos.getSize());
    bo = bos.get(0);
    values = bo.getValues();
    Assert.assertEquals("Values", 1, values.size());
    checkValue(values, true, "AccountName", "Fund7");
  }

  /**
   * Create some instances for a given BO and validate if they can be queried where:
   *
   * <ul>
   *   <li>the qualified business object id is set
   *   <li>the primary key is passed to findForBusinessObject()
   *   <li>the qualified business object id is passed to findForBusinessObject and an attribute of
   *       the BO is set as a data filter
   *   <li>the qualified business object id is passed to findForBusinessObject and the query is
   *       restricted to the currently active model
   *   <li>the qualified business object id is passed to findForBusinessObject and across all
   *       deployed model versions
   *   <li>the qualified business object id is passed to findForBusinessObject and the query is
   *       restricted to a given modelOid
   * </ul>
   */
  @Test
  public void CheckFiltering2() throws Exception {
    DeployedModelDescription model =
        sf.getQueryService().getModels(DeployedModelQuery.findActiveForId(MODEL_NAME3)).get(0);

    String businessObjectQualifiedId = new QName(model.getId(), "Employee").toString();

    createEmployee(businessObjectQualifiedId, "1", "Florin");
    createEmployee(businessObjectQualifiedId, "Sid", "2");

    BusinessObjectQuery query =
        BusinessObjectQuery.findForBusinessObject(businessObjectQualifiedId);
    query.setPolicy(new BusinessObjectQuery.Policy(BusinessObjectQuery.Option.WITH_VALUES));
    BusinessObjects bos = sf.getQueryService().getAllBusinessObjects(query);
    Assert.assertEquals("Objects", 1, bos.getSize());
    BusinessObject bo = bos.get(0);
    List<BusinessObject.Value> values = bo.getValues();
    Assert.assertEquals("Values", 2, values.size());

    query = BusinessObjectQuery.findWithPrimaryKey(businessObjectQualifiedId, "1");
    query.setPolicy(new BusinessObjectQuery.Policy(BusinessObjectQuery.Option.WITH_VALUES));
    bos = sf.getQueryService().getAllBusinessObjects(query);
    Assert.assertEquals("Objects", 1, bos.getSize());
    bo = bos.get(0);
    values = bo.getValues();
    Assert.assertEquals("Values", 1, values.size());
    checkValue(values, true, "EmpID", "1");

    query = BusinessObjectQuery.findWithPrimaryKey(businessObjectQualifiedId, "Sid");
    query.setPolicy(new BusinessObjectQuery.Policy(BusinessObjectQuery.Option.WITH_VALUES));
    bos = sf.getQueryService().getAllBusinessObjects(query);
    Assert.assertEquals("Objects", 1, bos.getSize());
    bo = bos.get(0);
    values = bo.getValues();
    Assert.assertEquals("Values", 1, values.size());
    checkValue(values, true, "EmpID", "Sid");

    query = BusinessObjectQuery.findForBusinessObject(businessObjectQualifiedId);
    query.where(DataFilter.isEqual("Employee", "EmpName", "2"));
    query.setPolicy(new BusinessObjectQuery.Policy(BusinessObjectQuery.Option.WITH_VALUES));
    bos = sf.getQueryService().getAllBusinessObjects(query);
    Assert.assertEquals("Objects", 1, bos.getSize());
    bo = bos.get(0);
    values = bo.getValues();
    Assert.assertEquals("Values", 1, values.size());
    checkValue(values, true, "EmpName", "2");

    query = BusinessObjectQuery.findForBusinessObject(businessObjectQualifiedId);
    query.where(DataFilter.isEqual("Employee", "EmpName", "Florin"));
    query.setPolicy(new BusinessObjectQuery.Policy(BusinessObjectQuery.Option.WITH_VALUES));
    bos = sf.getQueryService().getAllBusinessObjects(query);
    Assert.assertEquals("Objects", 1, bos.getSize());
    bo = bos.get(0);
    values = bo.getValues();
    Assert.assertEquals("Values", 1, values.size());
    checkValue(values, true, "EmpName", "Florin");

    RtEnvHome.deployModel(sf.getAdministrationService(), null, MODEL_NAME3);
    createEmployee(businessObjectQualifiedId, "3", "Meyer");
    query =
        BusinessObjectQuery.findForBusinessObject(
            PredefinedConstants.ACTIVE_MODEL, businessObjectQualifiedId);
    query.setPolicy(new BusinessObjectQuery.Policy(BusinessObjectQuery.Option.WITH_VALUES));
    bos = sf.getQueryService().getAllBusinessObjects(query);
    Assert.assertEquals("Objects", 1, bos.getSize());
    bo = bos.get(0);
    values = bo.getValues();
    Assert.assertEquals("Values", 1, values.size());

    query = BusinessObjectQuery.findForBusinessObject(businessObjectQualifiedId);
    query.setPolicy(new BusinessObjectQuery.Policy(BusinessObjectQuery.Option.WITH_VALUES));
    bos = sf.getQueryService().getAllBusinessObjects(query);
    Assert.assertEquals("Objects", 2, bos.getSize());
    Assert.assertEquals("Values", 3, getTotalSize(bos));

    query =
        BusinessObjectQuery.findForBusinessObject(model.getModelOID(), businessObjectQualifiedId);
    query.setPolicy(new BusinessObjectQuery.Policy(BusinessObjectQuery.Option.WITH_VALUES));
    bos = sf.getQueryService().getAllBusinessObjects(query);
    Assert.assertEquals("Objects", 1, bos.getSize());
    bo = bos.get(0);
    values = bo.getValues();
    Assert.assertEquals("Values", 2, values.size());
  }

  /**
   * The following test case should ensure that
   *
   * <ul>
   *   <li>Any modifications to an attribute of a BOI via API isn't reflected to process data which
   *       are using the BO
   *   <li>Any modifications to an attribute of a BOI via the process data is only reflected to the
   *       BOI which is attached to the synthetic process instance and that it doesn't affect other
   *       BOIs which are used in other processes
   * </ul>
   */
  @Test
  public void checkFilteringOnBusinessObjectAttrChange() {
    // setup
    final int customerIdOffset = 100;
    final int customerCount = 3;
    for (int customerId = 1; customerId <= customerCount; customerId++) {
      ProcessInstance pi =
          sf.getWorkflowService()
              .startProcess(new QName(MODEL_NAME2, "DistributedOrder").toString(), null, true);
      List<ActivityInstance> w = getWorklist(pi);
      Assert.assertEquals("worklist", 1, w.size());
      ActivityInstance ai = w.get(0);
      Assert.assertEquals("activity instance", "CreateOrder", ai.getActivity().getId());
      Map<String, Object> order = CollectionUtils.newMap();
      order.put("date", new Date());
      order.put("customerId", customerIdOffset + customerId);
      order.put("items", "item " + customerId);
      ai =
          complete(
              ai, PredefinedConstants.DEFAULT_CONTEXT, Collections.singletonMap("Order", order));

      try {
        ActivityInstanceStateBarrier.instance().await(ai.getOID(), ActivityInstanceState.Completed);
      } catch (Exception e) {
      }
    }

    // after DistributeCreation activity is completed we have the following state:
    // * 2 asynchronous subprocesses are started: one which copies the data and the
    //   other one which doesn't
    // * 3 synchronous subprocesses are triggered: one with shared data, one with separate
    //   but copied data and the last one with separate data without copying
    // This results into the following state:
    // * Each process has created four business object instances
    //   * One which is attached to a synthetic process instance
    //   * 3 other BOIs which are attached to a real process instance
    String businessObjectQualifiedId = new QName(MODEL_NAME2, "Order").toString();
    BusinessObjectQuery businessObjectQuery =
        BusinessObjectQuery.findForBusinessObject(businessObjectQualifiedId);
    businessObjectQuery
        .getFilter()
        .addAndTerm()
        .add(DataFilter.greaterThan("Order", "customerId", customerIdOffset));
    businessObjectQuery.setPolicy(
        new BusinessObjectQuery.Policy(
            BusinessObjectQuery.Option.WITH_VALUES, BusinessObjectQuery.Option.WITH_DESCRIPTION));
    BusinessObjects bos = sf.getQueryService().getAllBusinessObjects(businessObjectQuery);
    Assert.assertEquals("Only one business object, namely Order, is expected", 1, bos.getSize());
    Assert.assertEquals(
        "Business object instances count isn't the same as started process ergo the count of the synthetic process instances",
        customerCount,
        getTotalSize(bos));

    // Wait that all ShowOrder processes are started (unfortunately we cannot use
    // ProcessInstanceStateBarrier here
    // because of the async processes.
    ProcessInstanceQuery piQuery = ProcessInstanceQuery.findAlive("ShowOrder");
    boolean waitForPIs = true;
    while (waitForPIs) {
      long instanceCount = sf.getQueryService().getProcessInstancesCount(piQuery);
      waitForPIs = instanceCount != (customerCount * 5);

      if (waitForPIs) {
        try {
          Thread.sleep(100);
        } catch (InterruptedException e) {
        }
      }
    }

    BusinessObject bo = bos.get(0);
    BusinessObject.Value customer101 = null;
    for (BusinessObject.Value boValue : bo.getValues()) {
      Map<?, ?> boAttr = (Map<?, ?>) boValue.getValue();
      Integer customerId = (Integer) boAttr.get("customerId");
      if (Integer.valueOf(customerIdOffset + 1).equals(customerId)) {
        customer101 = boValue;
      }
    }
    Assert.assertNotNull("Customer " + customerIdOffset + 1 + " not found", customer101);

    // Update BOI via API...
    ((Map) customer101.getValue()).put("items", "newitems");
    sf.getWorkflowService()
        .updateBusinessObjectInstance(businessObjectQualifiedId, customer101.getValue());

    // ...and validate if no process data is modified
    piQuery = ProcessInstanceQuery.findActive();
    FilterTerm filter = piQuery.getFilter().addAndTerm();
    filter.add(
        DataFilter.between(
            "Order", "customerId", customerIdOffset, customerIdOffset + customerCount));
    filter.add(DataFilter.like("Order", "items", "item%"));
    filter.addAndTerm().add(ProcessInstanceHierarchyFilter.ROOT_PROCESS);
    piQuery.setPolicy(SubsetPolicy.UNRESTRICTED);
    ProcessInstances rootPIs = sf.getQueryService().getAllProcessInstances(piQuery);
    // Root process instances are the DistributedOrder processes and the ShowOrder processes which
    // was started
    // as async processes and which had copied the data
    Assert.assertEquals(
        "Changes in BOIs must not be reflected in process instance data",
        customerCount * 2,
        rootPIs.getTotalCount());

    // Update BOI for a given process via data path...
    long piOid = rootPIs.get(0).getOID();
    ((Map) customer101.getValue()).put("items", "newitems1");
    sf.getWorkflowService().setOutDataPath(piOid, "OrderDataPath", (Map) customer101.getValue());

    // ...and validate if the BOI is updated...
    businessObjectQuery =
        BusinessObjectQuery.findWithPrimaryKey(
            businessObjectQualifiedId, ((Map) customer101.getValue()).get("customerId"));
    businessObjectQuery.setPolicy(
        new BusinessObjectQuery.Policy(BusinessObjectQuery.Option.WITH_VALUES));
    bos = sf.getQueryService().getAllBusinessObjects(businessObjectQuery);
    Assert.assertEquals("Only one business object, namely Order, is expected", 1, bos.getSize());
    List<BusinessObject.Value> boValues = bos.get(0).getValues();
    Assert.assertEquals(1, boValues.size());
    Assert.assertEquals("newitems1", ((Map) boValues.get(0).getValue()).get("items"));

    // ...but the other process instance data should be untouched
    piQuery = ProcessInstanceQuery.findActive();
    filter = piQuery.getFilter().addAndTerm();
    filter.add(
        DataFilter.between(
            "Order", "customerId", customerIdOffset, customerIdOffset + customerCount));
    filter.add(DataFilter.like("Order", "items", "item%"));
    filter.addAndTerm().add(ProcessInstanceHierarchyFilter.ROOT_PROCESS);
    piQuery.setPolicy(SubsetPolicy.UNRESTRICTED);
    rootPIs = sf.getQueryService().getAllProcessInstances(piQuery);
    Assert.assertEquals(
        "Changes in BOIs must not be reflected in process instance data",
        (customerCount * 2) - 1,
        rootPIs.getTotalCount());
  }

  /* helper methods */

  private BusinessObject createOrder(DeployedModelDescription model, int customerId) {
    final Map<String, Object> order = CollectionUtils.newMap();
    order.put("date", new Date());
    order.put("customerId", customerId);

    return sf.getWorkflowService()
        .createBusinessObjectInstance(
            new QName(model.getId(), "Order").toString(), (Serializable) order);
  }

  private void createEmployee(String bo, String id, String name) {
    final Map<String, Object> fund = CollectionUtils.newMap();
    fund.put("EmpID", id);
    fund.put("EmpName", name);
    sf.getWorkflowService().createBusinessObjectInstance(bo, (Serializable) fund);
  }

  private BusinessObject createCustomer(DeployedModelDescription model, int customerId) {
    final Map<String, Object> order = CollectionUtils.newMap();
    order.put("id", customerId);
    order.put("firstName", "Danny" + customerId);
    order.put("lastName", "North" + customerId);

    return sf.getWorkflowService()
        .createBusinessObjectInstance(
            new QName(model.getId(), "Customer").toString(), (Serializable) order);
  }

  private void checkValue(
      List<BusinessObject.Value> boValues, boolean strict, String name, Object... values) {
    Set<Object> expected = CollectionUtils.newSetFromIterator(Arrays.asList(values).iterator());
    Set<Object> actual = CollectionUtils.newSet();
    for (BusinessObject.Value boValue : boValues) {
      Map<?, ?> data = (Map<?, ?>) boValue.getValue();
      actual.add(data.get(name));
    }
    if (strict) {
      Assert.assertEquals("Values: ", expected, actual);
    } else {
      expected.removeAll(actual);
      Assert.assertTrue("Missing values: " + expected, expected.isEmpty());
    }
  }

  private ActivityInstance complete(ActivityInstance ai, String context, Map<String, ?> data) {
    WorkflowService ws = sf.getWorkflowService();
    if (ai.getState() != ActivityInstanceState.Application) {
      ai = ws.activate(ai.getOID());
    }
    ai = ws.complete(ai.getOID(), context, data);
    return ai;
  }

  @SuppressWarnings("unchecked")
  private List<ActivityInstance> getWorklist(EvaluationPolicy... policies) {
    WorkflowService ws = sf.getWorkflowService();
    WorklistQuery query = WorklistQuery.findCompleteWorklist();
    if (policies != null) {
      for (EvaluationPolicy policy : policies) {
        query.setPolicy(policy);
      }
    }
    Worklist worklist = ws.getWorklist(query);
    return worklist.getCumulatedItems();
  }

  @SuppressWarnings("unchecked")
  private List<ActivityInstance> getWorklist(ProcessInstance pi, EvaluationPolicy... policies) {
    WorkflowService ws = sf.getWorkflowService();
    WorklistQuery query = WorklistQuery.findCompleteWorklist();
    if (policies != null) {
      for (EvaluationPolicy policy : policies) {
        query.setPolicy(policy);
      }
    }
    query.getFilter().add(new ProcessInstanceFilter(pi.getOID(), false));
    Worklist worklist = ws.getWorklist(query);
    return worklist.getCumulatedItems();
  }

  private int getTotalSize(BusinessObjects bos) {
    int size = 0;
    for (BusinessObject bo : bos) {
      size += bo.getValues().size();
    }
    return size;
  }
}
示例#20
0
/**
 * An Abstract base class that makes writing Solr JUnit tests "easier"
 *
 * <p>Test classes that subclass this need only specify the path to the schema.xml file (:TODO: the
 * solrconfig.xml as well) and write some testMethods. This class takes care of creating/destroying
 * the index, and provides several assert methods to assist you.
 *
 * @see #setUp
 * @see #tearDown
 */
public abstract class AbstractSolrTestCase extends LuceneTestCase {
  protected SolrConfig solrConfig;

  /**
   * Harness initialized by initTestHarness.
   *
   * <p>For use in test methods as needed.
   */
  protected TestHarness h;

  /**
   * LocalRequestFactory initialized by initTestHarness using sensible defaults.
   *
   * <p>For use in test methods as needed.
   */
  protected TestHarness.LocalRequestFactory lrf;

  /** Subclasses must define this method to return the name of the schema.xml they wish to use. */
  public abstract String getSchemaFile();

  /**
   * Subclasses must define this method to return the name of the solrconfig.xml they wish to use.
   */
  public abstract String getSolrConfigFile();

  /** Subclasses can override this to change a test's solr home (default is in test-files) */
  public String getSolrHome() {
    return SolrTestCaseJ4.TEST_HOME();
  }

  @ClassRule
  public static TestRule solrClassRules = RuleChain.outerRule(new SystemPropertiesRestoreRule());

  @Rule public TestRule solrTestRules = RuleChain.outerRule(new SystemPropertiesRestoreRule());

  @BeforeClass
  public static void beforeClassAbstractSolrTestCase() throws Exception {
    SolrTestCaseJ4.startTrackingSearchers();
  }

  @AfterClass
  public static void afterClassAbstractSolrTestCase() throws Exception {
    SolrTestCaseJ4.endTrackingSearchers();
  }

  /** The directory used to story the index managed by the TestHarness h */
  protected File dataDir;

  public static Logger log = LoggerFactory.getLogger(AbstractSolrTestCase.class);

  private String factoryProp;

  /**
   * Initializes things your test might need
   *
   * <ul>
   *   <li>Creates a dataDir in the "java.io.tmpdir"
   *   <li>initializes the TestHarness h using this data directory, and getSchemaPath()
   *   <li>initializes the LocalRequestFactory lrf using sensible defaults.
   * </ul>
   */
  @Override
  public void setUp() throws Exception {
    super.setUp();
    log.info("####SETUP_START " + getTestName());
    ignoreException("ignore_exception");
    factoryProp = System.getProperty("solr.directoryFactory");
    if (factoryProp == null) {
      System.setProperty("solr.directoryFactory", "solr.RAMDirectoryFactory");
    }
    dataDir = new File(TEMP_DIR, getClass().getName() + "-" + System.currentTimeMillis());
    dataDir.mkdirs();
    String configFile = getSolrConfigFile();
    System.setProperty("solr.solr.home", getSolrHome());
    if (configFile != null) {

      solrConfig = TestHarness.createConfig(getSolrConfigFile());
      h = new TestHarness(dataDir.getAbsolutePath(), solrConfig, getSchemaFile());
      lrf = h.getRequestFactory("standard", 0, 20, CommonParams.VERSION, "2.2");
    }
    log.info("####SETUP_END " + getTestName());
  }

  /** Causes an exception matching the regex pattern to not be logged. */
  public static void ignoreException(String pattern) {
    if (SolrException.ignorePatterns == null) SolrException.ignorePatterns = new HashSet<String>();
    SolrException.ignorePatterns.add(pattern);
  }

  public static void resetExceptionIgnores() {
    SolrException.ignorePatterns = null;
    ignoreException("ignore_exception"); // always ignore "ignore_exception"
  }

  /**
   * Subclasses that override setUp can optionally call this method to log the fact that their setUp
   * process has ended.
   */
  public void postSetUp() {
    log.info("####POSTSETUP " + getTestName());
  }

  /**
   * Subclasses that override tearDown can optionally call this method to log the fact that the
   * tearDown process has started. This is necessary since subclasses will want to call
   * super.tearDown() at the *end* of their tearDown method.
   */
  public void preTearDown() {
    log.info("####PRETEARDOWN " + getTestName());
  }

  /**
   * Shuts down the test harness, and makes the best attempt possible to delete dataDir, unless the
   * system property "solr.test.leavedatadir" is set.
   */
  @Override
  public void tearDown() throws Exception {
    log.info("####TEARDOWN_START " + getTestName());
    if (factoryProp == null) {
      System.clearProperty("solr.directoryFactory");
    }

    if (h != null) {
      h.close();
    }
    String skip = System.getProperty("solr.test.leavedatadir");
    if (null != skip && 0 != skip.trim().length()) {
      System.err.println(
          "NOTE: per solr.test.leavedatadir, dataDir will not be removed: "
              + dataDir.getAbsolutePath());
    } else {
      if (!recurseDelete(dataDir)) {
        System.err.println(
            "!!!! WARNING: best effort to remove " + dataDir.getAbsolutePath() + " FAILED !!!!!");
      }
    }

    resetExceptionIgnores();
    super.tearDown();
  }

  /** Validates an update XML String is successful */
  public void assertU(String update) {
    assertU(null, update);
  }

  /** Validates an update XML String is successful */
  public void assertU(String message, String update) {
    checkUpdateU(message, update, true);
  }

  /** Validates an update XML String failed */
  public void assertFailedU(String update) {
    assertFailedU(null, update);
  }

  /** Validates an update XML String failed */
  public void assertFailedU(String message, String update) {
    checkUpdateU(message, update, false);
  }

  /** Checks the success or failure of an update message */
  private void checkUpdateU(String message, String update, boolean shouldSucceed) {
    try {
      String m = (null == message) ? "" : message + " ";
      if (shouldSucceed) {
        String res = h.validateUpdate(update);
        if (res != null) fail(m + "update was not successful: " + res);
      } else {
        String res = h.validateErrorUpdate(update);
        if (res != null) fail(m + "update succeeded, but should have failed: " + res);
      }
    } catch (SAXException e) {
      throw new RuntimeException("Invalid XML", e);
    }
  }

  /** Validates a query matches some XPath test expressions and closes the query */
  public void assertQ(SolrQueryRequest req, String... tests) {
    assertQ(null, req, tests);
  }

  /** Validates a query matches some XPath test expressions and closes the query */
  public void assertQ(String message, SolrQueryRequest req, String... tests) {
    try {
      String m = (null == message) ? "" : message + " ";
      String response = h.query(req);
      String results = h.validateXPath(response, tests);
      if (null != results) {
        fail(
            m
                + "query failed XPath: "
                + results
                + "\n xml response was: "
                + response
                + "\n request was: "
                + req.getParamString());
      }
    } catch (XPathExpressionException e1) {
      throw new RuntimeException("XPath is invalid", e1);
    } catch (Exception e2) {
      throw new RuntimeException("Exception during query", e2);
    }
  }

  /** Makes sure a query throws a SolrException with the listed response code */
  public void assertQEx(String message, SolrQueryRequest req, int code) {
    try {
      h.query(req);
      fail(message);
    } catch (SolrException sex) {
      assertEquals(code, sex.code());
    } catch (Exception e2) {
      throw new RuntimeException("Exception during query", e2);
    }
  }

  public void assertQEx(String message, SolrQueryRequest req, SolrException.ErrorCode code) {
    try {
      h.query(req);
      fail(message);
    } catch (SolrException e) {
      assertEquals(code.code, e.code());
    } catch (Exception e2) {
      throw new RuntimeException("Exception during query", e2);
    }
  }

  /** @see TestHarness#optimize */
  public String optimize(String... args) {
    return TestHarness.optimize(args);
  }
  /** @see TestHarness#commit */
  public String commit(String... args) {
    return TestHarness.commit(args);
  }

  /**
   * Generates a simple &lt;add&gt;&lt;doc&gt;... XML String with no options
   *
   * @param fieldsAndValues 0th and Even numbered args are fields names odds are field values.
   * @see #add
   * @see #doc
   */
  public String adoc(String... fieldsAndValues) {
    Doc d = doc(fieldsAndValues);
    return add(d);
  }

  /**
   * Generates a simple &lt;add&gt;&lt;doc&gt;... XML String with the commitWithin attribute.
   *
   * @param commitWithin the value of the commitWithin attribute
   * @param fieldsAndValues 0th and Even numbered args are fields names odds are field values.
   * @see #add
   * @see #doc
   */
  public String adoc(int commitWithin, String... fieldsAndValues) {
    Doc d = doc(fieldsAndValues);
    return add(d, "commitWithin", String.valueOf(commitWithin));
  }

  /** Generates a simple &lt;add&gt;&lt;doc&gt;... XML String with no options */
  public String adoc(SolrInputDocument sdoc) {
    List<String> fields = new ArrayList<String>();
    for (SolrInputField sf : sdoc) {
      for (Object o : sf.getValues()) {
        fields.add(sf.getName());
        fields.add(o.toString());
      }
    }
    return adoc(fields.toArray(new String[fields.size()]));
  }

  /**
   * Generates an &lt;add&gt;&lt;doc&gt;... XML String with options on the add.
   *
   * @param doc the Document to add
   * @param args 0th and Even numbered args are param names, Odds are param values.
   * @see #add
   * @see #doc
   */
  public String add(Doc doc, String... args) {
    try {
      StringWriter r = new StringWriter();

      // this is anoying
      if (null == args || 0 == args.length) {
        r.write("<add>");
        r.write(doc.xml);
        r.write("</add>");
      } else {
        XML.writeUnescapedXML(r, "add", doc.xml, (Object[]) args);
      }

      return r.getBuffer().toString();
    } catch (IOException e) {
      throw new RuntimeException("this should never happen with a StringWriter", e);
    }
  }

  /**
   * Generates a &lt;delete&gt;... XML string for an ID
   *
   * @see TestHarness#deleteById
   */
  public String delI(String id, String... args) {
    return TestHarness.deleteById(id, args);
  }

  /**
   * Generates a &lt;delete&gt;... XML string for an query
   *
   * @see TestHarness#deleteByQuery
   */
  public String delQ(String q, String... args) {
    return TestHarness.deleteByQuery(q, args);
  }

  /**
   * Generates a simple &lt;doc&gt;... XML String with no options
   *
   * @param fieldsAndValues 0th and Even numbered args are fields names, Odds are field values.
   * @see TestHarness#makeSimpleDoc
   */
  public Doc doc(String... fieldsAndValues) {
    Doc d = new Doc();
    d.xml = TestHarness.makeSimpleDoc(fieldsAndValues).toString();
    return d;
  }

  /**
   * Generates a SolrQueryRequest using the LocalRequestFactory
   *
   * @see #lrf
   */
  public SolrQueryRequest req(String... q) {
    return lrf.makeRequest(q);
  }

  /**
   * Generates a SolrQueryRequest using the LocalRequestFactory
   *
   * @see #lrf
   */
  public SolrQueryRequest req(String[] params, String... moreParams) {
    String[] allParams = moreParams;
    if (params.length != 0) {
      int len = params.length + moreParams.length;
      allParams = new String[len];
      System.arraycopy(params, 0, allParams, 0, params.length);
      System.arraycopy(moreParams, 0, allParams, params.length, moreParams.length);
    }

    return lrf.makeRequest(allParams);
  }

  /** Neccessary to make method signatures un-ambiguous */
  public static class Doc {
    public String xml;

    @Override
    public String toString() {
      return xml;
    }
  }

  public static boolean recurseDelete(File f) {
    if (f.isDirectory()) {
      for (File sub : f.listFiles()) {
        if (!recurseDelete(sub)) {
          System.err.println(
              "!!!! WARNING: best effort to remove " + sub.getAbsolutePath() + " FAILED !!!!!");
          return false;
        }
      }
    }
    return f.delete();
  }

  /** @see SolrTestCaseJ4#getFile */
  public static File getFile(String name) throws IOException {
    return SolrTestCaseJ4.getFile(name);
  }
}
示例#21
0
public class SolrXmlInZkTest extends SolrTestCaseJ4 {

  @Rule public TestRule solrTestRules = RuleChain.outerRule(new SystemPropertiesRestoreRule());

  protected ZkTestServer zkServer;

  protected String zkDir;

  private SolrZkClient zkClient;

  private ZkStateReader reader;

  private static int PORT = 7000;

  private ConfigSolr cfg;

  @Before
  public void beforeClass() {
    System.setProperty("solr.solrxml.location", "zookeeper");
  }

  private void setUpZkAndDiskXml(boolean toZk, boolean leaveOnLocal) throws Exception {

    createTempDir();
    File solrHome = new File(dataDir, "home");
    copyMinConf(new File(solrHome, "myCollect"));
    if (leaveOnLocal) {
      FileUtils.copyFile(
          new File(SolrTestCaseJ4.TEST_HOME(), "solr-stress-new.xml"),
          new File(solrHome, "solr.xml"));
    }

    System.setProperty("solr.solr.home", solrHome.getAbsolutePath());

    ignoreException("No UpdateLog found - cannot sync");
    ignoreException("No UpdateLog found - cannot recover");

    System.setProperty("zkClientTimeout", "8000");

    zkDir =
        dataDir.getAbsolutePath()
            + File.separator
            + "zookeeper"
            + System.currentTimeMillis()
            + "/server1/data";
    zkServer = new ZkTestServer(zkDir);
    zkServer.run();
    System.setProperty("zkHost", zkServer.getZkAddress());
    AbstractZkTestCase.buildZooKeeper(
        zkServer.getZkHost(), zkServer.getZkAddress(), "solrconfig.xml", "schema.xml");

    zkClient = new SolrZkClient(zkServer.getZkAddress(), AbstractZkTestCase.TIMEOUT);

    if (toZk) {
      zkClient.makePath("solr.xml", XML_FOR_ZK.getBytes(Charsets.UTF_8), true);
    }

    zkClient.close();

    log.info("####SETUP_START " + getTestName());

    // set some system properties for use by tests
    System.setProperty("solr.test.sys.prop1", "propone");
    System.setProperty("solr.test.sys.prop2", "proptwo");

    Method method =
        SolrDispatchFilter.class.getDeclaredMethod("loadConfigSolr", SolrResourceLoader.class);
    method.setAccessible(true);

    Object obj = method.invoke(new SolrDispatchFilter(), new SolrResourceLoader(null));
    cfg = (ConfigSolr) obj;

    log.info("####SETUP_END " + getTestName());
  }

  private void closeZK() throws Exception {
    if (zkClient != null) {
      zkClient.close();
    }

    if (reader != null) {
      reader.close();
    }
    zkServer.shutdown();
  }

  @Test
  public void testXmlOnBoth() throws Exception {
    try {
      setUpZkAndDiskXml(true, true);
      assertEquals(
          "Should have gotten a new port the xml file sent to ZK, overrides the copy on disk",
          cfg.getZkHostPort(),
          "9045");
    } finally {
      closeZK();
    }
  }

  @Test
  public void testXmlInZkOnly() throws Exception {
    try {
      setUpZkAndDiskXml(true, false);
      assertEquals(
          "Should have gotten a new port the xml file sent to ZK", cfg.getZkHostPort(), "9045");
    } finally {
      closeZK();
    }
  }

  @Test
  public void testNotInZkAndShouldBe() throws Exception {
    try {
      setUpZkAndDiskXml(false, true);
      fail("Should have gotten an exception here!");
    } catch (InvocationTargetException ite) {
      assertEquals(
          "Should have an exception here, file not in ZK.",
          "Could not load solr.xml from zookeeper",
          ite.getTargetException().getMessage());
    } finally {
      closeZK();
    }
  }

  @Test
  public void testNotInZkOrOnDisk() throws Exception {
    try {
      System.clearProperty("solr.solrxml.location");
      System.setProperty("hostPort", "8787");
      setUpZkAndDiskXml(false, false); // solr.xml not on disk either
      fail("Should have thrown an exception here");
    } catch (InvocationTargetException ite) {
      assertTrue(
          "Should be failing to create default solr.xml in code",
          ite.getTargetException().getCause().getMessage().indexOf("solr.xml does not exist")
              != -1);
    } finally {
      closeZK();
    }
  }
  // TODO: Remove for 5.x, this should fail when we don't have a real solr.xml file after we take
  // out the remove
  // the hard-coded default from ConifgSolrXmlOld
  @Test
  public void testHardCodedSolrXml() throws IOException {
    SolrResourceLoader loader = null;
    final File solrHome =
        new File(
            TEMP_DIR, SolrXmlInZkTest.getClassName() + File.separator + "testHardCodedSolrXml");
    try {
      loader = new SolrResourceLoader(solrHome.getAbsolutePath());
      ConfigSolr.fromSolrHome(loader, solrHome.getAbsolutePath());
    } catch (Exception e) {
      fail(
          "Should NOT have thrown any exception here, solr.xml should have been received from the hard-coded string");
    } finally {
      loader.close();
    }
  }

  @Test
  public void testOnDiskOnly() throws Exception {
    try {
      System.clearProperty("solr.solrxml.location");
      setUpZkAndDiskXml(false, true);
      assertEquals("Should have gotten the default port", cfg.getZkHostPort(), "8983");
    } finally {
      closeZK();
    }
  }

  @Test
  public void testBadSysProp() throws Exception {
    try {
      System.setProperty("solr.solrxml.location", "solrHomeDir");
      setUpZkAndDiskXml(false, true);
      fail("Should have thrown exception in SolrXmlInZkTest.testBadSysProp");
    } catch (InvocationTargetException ite) {
      assertEquals(
          "Should have an exception in SolrXmlInZkTest.testBadSysProp, sysprop set to bogus value.",
          ite.getTargetException().getMessage(),
          "Bad solr.solrxml.location set: solrHomeDir - should be 'solrhome' or 'zookeeper'");
    } finally {
      closeZK();
    }
  }

  // SolrDispatchFilter.protected static ConfigSolr loadConfigSolr(SolrResourceLoader loader) {
  @Test
  public void testZkHostDiscovery()
      throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException,
          InstantiationException, InvocationTargetException {

    // Should see an error when zkHost is not defined but solr.solrxml.location is set to zookeeper.
    System.clearProperty("zkHost");
    try {
      Method method =
          SolrDispatchFilter.class.getDeclaredMethod("loadConfigSolr", SolrResourceLoader.class);
      method.setAccessible(true);
      method.invoke(new SolrDispatchFilter(), new SolrResourceLoader(null));
      fail("Should have thrown an exception");
    } catch (InvocationTargetException ite) {
      assertTrue(
          "Should be catching a SolrException", ite.getTargetException() instanceof SolrException);
      assertEquals(
          "Caught Solr exception",
          ite.getTargetException().getMessage(),
          "Could not load solr.xml from zookeeper: zkHost system property not set");
    }
  }

  // Just a random port, I'm not going to use it but just check that the Solr instance constructed
  // from the XML
  // file in ZK overrides the default port.
  private final String XML_FOR_ZK =
      "<solr>"
          + "  <solrcloud>"
          + "    <str name=\"host\">127.0.0.1</str>"
          + "    <int name=\"hostPort\">9045</int>"
          + "    <str name=\"hostContext\">${hostContext:solr}</str>"
          + "  </solrcloud>"
          + "  <shardHandlerFactory name=\"shardHandlerFactory\" class=\"HttpShardHandlerFactory\">"
          + "    <int name=\"socketTimeout\">${socketTimeout:120000}</int>"
          + "    <int name=\"connTimeout\">${connTimeout:15000}</int>"
          + "  </shardHandlerFactory>"
          + "</solr>";
}
/**
 * Tests for {@link GitHubCommitNotifier}.
 *
 * @author Oleg Nenashev <*****@*****.**>
 */
@RunWith(MockitoJUnitRunner.class)
public class GitHubCommitNotifierTest {

  @Mock public BuildData data;

  @Mock public Revision rev;

  @Inject public GitHubPluginConfig config;

  public JenkinsRule jRule = new JenkinsRule();

  @Rule
  public RuleChain chain =
      RuleChain.outerRule(jRule).around(new InjectJenkinsMembersRule(jRule, this));

  @Rule
  public GHMockRule github =
      new GHMockRule(
              new WireMockRule(wireMockConfig().dynamicPort().notifier(new Slf4jNotifier(true))))
          .stubUser()
          .stubRepo()
          .stubStatuses();

  @Rule
  public ExternalResource prep =
      new ExternalResource() {
        @Override
        protected void before() throws Throwable {
          when(data.getLastBuiltRevision()).thenReturn(rev);
          data.lastBuild = new hudson.plugins.git.util.Build(rev, rev, 0, Result.SUCCESS);
          when(rev.getSha1()).thenReturn(ObjectId.fromString(SOME_SHA));
        }
      };

  @Test
  @Issue("JENKINS-23641")
  public void testNoBuildData() throws Exception {
    FreeStyleProject prj = jRule.createFreeStyleProject("23641_noBuildData");
    prj.getPublishersList().add(new GitHubCommitNotifier());
    Build b = prj.scheduleBuild2(0).get();
    jRule.assertBuildStatus(Result.FAILURE, b);
    jRule.assertLogContains(BuildDataHelper_NoBuildDataError(), b);
  }

  @Test
  @Issue("JENKINS-23641")
  public void testNoBuildRevision() throws Exception {
    FreeStyleProject prj = jRule.createFreeStyleProject();
    prj.setScm(new GitSCM("http://non.existent.git.repo.nowhere/repo.git"));
    prj.getPublishersList().add(new GitHubCommitNotifier());
    // Git plugin 2.4.1 + does not include BuildData if checkout fails, so we add it if needed
    Build b = safelyGenerateBuild(prj);
    jRule.assertBuildStatus(Result.FAILURE, b);
    jRule.assertLogContains(BuildDataHelper_NoLastRevisionError(), b);
  }

  @Test
  @Issue("JENKINS-25312")
  public void testMarkUnstableOnCommitNotifierFailure() throws Exception {
    FreeStyleProject prj = jRule.createFreeStyleProject();
    prj.getPublishersList().add(new GitHubCommitNotifier(Result.UNSTABLE.toString()));
    Build b = prj.scheduleBuild2(0).get();
    jRule.assertBuildStatus(Result.UNSTABLE, b);
  }

  @Test
  @Issue("JENKINS-25312")
  public void testMarkSuccessOnCommitNotifierFailure() throws Exception {
    FreeStyleProject prj = jRule.createFreeStyleProject();
    prj.getPublishersList().add(new GitHubCommitNotifier(Result.SUCCESS.toString()));
    Build b = prj.scheduleBuild2(0).get();
    jRule.assertBuildStatus(Result.SUCCESS, b);
  }

  @Test
  public void shouldWriteStatusOnGH() throws Exception {
    config.getConfigs().add(github.serverConfig());
    FreeStyleProject prj = jRule.createFreeStyleProject();

    prj.getBuildersList()
        .add(
            new TestBuilder() {
              @Override
              public boolean perform(
                  AbstractBuild<?, ?> build, Launcher launcher, BuildListener listener) {
                build.addAction(data);
                return true;
              }
            });

    prj.getPublishersList().add(new GitHubCommitNotifier(Result.SUCCESS.toString()));

    prj.scheduleBuild2(0).get();

    github.service().verify(1, postRequestedFor(urlPathMatching(".*/" + SOME_SHA)));
  }

  private Build safelyGenerateBuild(FreeStyleProject prj)
      throws InterruptedException, java.util.concurrent.ExecutionException {
    Build b;
    if (jRule
        .getPluginManager()
        .getPlugin("git")
        .getVersionNumber()
        .isNewerThan(new VersionNumber("2.4.0"))) {
      b = prj.scheduleBuild2(0, new Cause.UserIdCause(), new BuildData()).get();
    } else {
      b = prj.scheduleBuild2(0).get();
    }
    return b;
  }

  @TestExtension
  public static final FixedGHRepoNameTestContributor CONTRIBUTOR =
      new FixedGHRepoNameTestContributor();
}
public class CoreAdminHandlerTest extends SolrTestCaseJ4 {

  @BeforeClass
  public static void beforeClass() throws Exception {
    initCore("solrconfig.xml", "schema.xml");
  }

  @Rule public TestRule solrTestRules = RuleChain.outerRule(new SystemPropertiesRestoreRule());

  public String getCoreName() {
    return this.getClass().getName() + "_sys_vars";
  }

  @Test
  public void testCreateWithSysVars() throws Exception {
    useFactory(null); // I require FS-based indexes for this test.

    final File workDir = createTempDir(getCoreName()).toFile();

    String coreName = "with_sys_vars";
    File instDir = new File(workDir, coreName);
    File subHome = new File(instDir, "conf");
    assertTrue("Failed to make subdirectory ", subHome.mkdirs());

    // Be sure we pick up sysvars when we create this
    String srcDir = SolrTestCaseJ4.TEST_HOME() + "/collection1/conf";
    FileUtils.copyFile(new File(srcDir, "schema-tiny.xml"), new File(subHome, "schema_ren.xml"));
    FileUtils.copyFile(
        new File(srcDir, "solrconfig-minimal.xml"), new File(subHome, "solrconfig_ren.xml"));
    FileUtils.copyFile(
        new File(srcDir, "solrconfig.snippet.randomindexconfig.xml"),
        new File(subHome, "solrconfig.snippet.randomindexconfig.xml"));

    final CoreContainer cores = h.getCoreContainer();

    final CoreAdminHandler admin = new CoreAdminHandler(cores);

    // create a new core (using CoreAdminHandler) w/ properties
    System.setProperty("INSTDIR_TEST", instDir.getAbsolutePath());
    System.setProperty("CONFIG_TEST", "solrconfig_ren.xml");
    System.setProperty("SCHEMA_TEST", "schema_ren.xml");

    File dataDir = new File(workDir.getAbsolutePath(), "data_diff");
    System.setProperty("DATA_TEST", dataDir.getAbsolutePath());

    SolrQueryResponse resp = new SolrQueryResponse();
    admin.handleRequestBody(
        req(
            CoreAdminParams.ACTION,
            CoreAdminParams.CoreAdminAction.CREATE.toString(),
            CoreAdminParams.NAME,
            getCoreName(),
            CoreAdminParams.INSTANCE_DIR,
            "${INSTDIR_TEST}",
            CoreAdminParams.CONFIG,
            "${CONFIG_TEST}",
            CoreAdminParams.SCHEMA,
            "${SCHEMA_TEST}",
            CoreAdminParams.DATA_DIR,
            "${DATA_TEST}"),
        resp);
    assertNull("Exception on create", resp.getException());

    // Now assert that certain values are properly dereferenced in the process of creating the core,
    // see
    // SOLR-4982.

    // Should NOT be a datadir named ${DATA_TEST} (literal). This is the bug after all
    File badDir = new File(instDir, "${DATA_TEST}");
    assertFalse(
        "Should have substituted the sys var, found file " + badDir.getAbsolutePath(),
        badDir.exists());

    // For the other 3 vars, we couldn't get past creating the core fi dereferencing didn't work
    // correctly.

    // Should have segments in the directory pointed to by the ${DATA_TEST}.
    File test = new File(dataDir, "index");
    assertTrue("Should have found index dir at " + test.getAbsolutePath(), test.exists());
  }

  @Test
  public void testCoreAdminHandler() throws Exception {
    final File workDir = createTempDir().toFile();

    final CoreContainer cores = h.getCoreContainer();

    final CoreAdminHandler admin = new CoreAdminHandler(cores);

    Path instDir;
    try (SolrCore template = cores.getCore("collection1")) {
      assertNotNull(template);
      instDir = template.getCoreDescriptor().getInstanceDir();
    }

    assertTrue("instDir doesn't exist: " + instDir, Files.exists(instDir));
    final File instPropFile = new File(workDir, "instProp");
    FileUtils.copyDirectory(instDir.toFile(), instPropFile);

    SolrQueryResponse resp = new SolrQueryResponse();
    // Sneaking in a test for using a bad core name
    try {
      admin.handleRequestBody(
          req(
              CoreAdminParams.ACTION,
              CoreAdminParams.CoreAdminAction.CREATE.toString(),
              CoreAdminParams.INSTANCE_DIR,
              instPropFile.getAbsolutePath(),
              CoreAdminParams.NAME,
              "ugly$core=name"),
          resp);

    } catch (SolrException se) {
      assertTrue(
          "Expected error message for bad core name.", se.toString().contains("Invalid core"));
    }
    CoreDescriptor cd = cores.getCoreDescriptor("ugly$core=name");
    assertNull("Should NOT have added this core!", cd);

    // create a new core (using CoreAdminHandler) w/ properties

    admin.handleRequestBody(
        req(
            CoreAdminParams.ACTION,
            CoreAdminParams.CoreAdminAction.CREATE.toString(),
            CoreAdminParams.INSTANCE_DIR,
            instPropFile.getAbsolutePath(),
            CoreAdminParams.NAME,
            "props",
            CoreAdminParams.PROPERTY_PREFIX + "hoss",
            "man",
            CoreAdminParams.PROPERTY_PREFIX + "foo",
            "baz"),
        resp);
    assertNull("Exception on create", resp.getException());

    cd = cores.getCoreDescriptor("props");
    assertNotNull("Core not added!", cd);
    assertEquals(cd.getCoreProperty("hoss", null), "man");
    assertEquals(cd.getCoreProperty("foo", null), "baz");

    // attempt to create a bogus core and confirm failure
    ignoreException("Could not load config");
    try {
      resp = new SolrQueryResponse();
      admin.handleRequestBody(
          req(
              CoreAdminParams.ACTION,
              CoreAdminParams.CoreAdminAction.CREATE.toString(),
              CoreAdminParams.NAME,
              "bogus_dir_core",
              CoreAdminParams.INSTANCE_DIR,
              "dir_does_not_exist_127896"),
          resp);
      fail("bogus collection created ok");
    } catch (SolrException e) {
      // :NOOP:
      // :TODO: CoreAdminHandler's exception messages are terrible, otherwise we could assert
      // something useful here
    }
    unIgnoreException("Could not load config");

    // check specifically for status of the failed core name
    resp = new SolrQueryResponse();
    admin.handleRequestBody(
        req(
            CoreAdminParams.ACTION,
            CoreAdminParams.CoreAdminAction.STATUS.toString(),
            CoreAdminParams.CORE,
            "bogus_dir_core"),
        resp);
    Map<String, Exception> failures = (Map<String, Exception>) resp.getValues().get("initFailures");
    assertNotNull("core failures is null", failures);

    NamedList<Object> status = (NamedList<Object>) resp.getValues().get("status");
    assertNotNull("core status is null", status);

    assertEquals("wrong number of core failures", 1, failures.size());
    Exception fail = failures.get("bogus_dir_core");
    assertNotNull("null failure for test core", fail);
    assertTrue(
        "init failure doesn't mention problem: " + fail.getCause().getMessage(),
        0 < fail.getCause().getMessage().indexOf("dir_does_not_exist"));

    assertEquals(
        "bogus_dir_core status isn't empty", 0, ((NamedList) status.get("bogus_dir_core")).size());

    // Try renaming the core, we should fail
    // First assert that the props core exists
    cd = cores.getCoreDescriptor("props");
    assertNotNull("Core disappeared!", cd);

    // now rename it something else just for kicks since we don't actually test this that I could
    // find.
    admin.handleRequestBody(
        req(
            CoreAdminParams.ACTION,
            CoreAdminParams.CoreAdminAction.RENAME.toString(),
            CoreAdminParams.CORE,
            "props",
            CoreAdminParams.OTHER,
            "rename_me"),
        resp);

    cd = cores.getCoreDescriptor("rename_me");
    assertNotNull("Core should have been renamed!", cd);

    // Rename it something bogus and see if you get an exception, the old core is still there and
    // the bogus one isn't
    try {
      admin.handleRequestBody(
          req(
              CoreAdminParams.ACTION,
              CoreAdminParams.CoreAdminAction.RENAME.toString(),
              CoreAdminParams.CORE,
              "rename_me",
              CoreAdminParams.OTHER,
              "bad$name"),
          resp);
    } catch (
        SolrException
            e) { // why the heck does create return a SolrException (admittedly wrapping an IAE)
      assertTrue(
          "Expected error message for bad core name.", e.getMessage().contains("Invalid core"));
    }

    cd = cores.getCoreDescriptor("bad$name");
    assertNull("Core should NOT exist!", cd);

    cd = cores.getCoreDescriptor("rename_me");
    assertNotNull("Core should have been renamed!", cd);

    // :TODO: because of SOLR-3665 we can't ask for status from all cores

  }

  @Test
  public void testDeleteInstanceDir() throws Exception {
    File solrHomeDirectory =
        new File(initCoreDataDir, getClass().getName() + "-corex-" + System.nanoTime());
    solrHomeDirectory.mkdirs();
    copySolrHomeToTemp(solrHomeDirectory, "corex");
    File corex = new File(solrHomeDirectory, "corex");
    FileUtils.write(new File(corex, "core.properties"), "", StandardCharsets.UTF_8);
    JettySolrRunner runner =
        new JettySolrRunner(solrHomeDirectory.getAbsolutePath(), buildJettyConfig("/solr"));
    runner.start();

    try (HttpSolrClient client = getHttpSolrClient(runner.getBaseUrl() + "/corex")) {
      client.setConnectionTimeout(SolrTestCaseJ4.DEFAULT_CONNECTION_TIMEOUT);
      client.setSoTimeout(SolrTestCaseJ4.DEFAULT_CONNECTION_TIMEOUT);
      SolrInputDocument doc = new SolrInputDocument();
      doc.addField("id", "123");
      client.add(doc);
      client.commit();
    }

    try (HttpSolrClient client = getHttpSolrClient(runner.getBaseUrl().toString())) {
      client.setConnectionTimeout(SolrTestCaseJ4.DEFAULT_CONNECTION_TIMEOUT);
      client.setSoTimeout(SolrTestCaseJ4.DEFAULT_CONNECTION_TIMEOUT);
      CoreAdminRequest.Unload req = new CoreAdminRequest.Unload(false);
      req.setDeleteInstanceDir(true);
      req.setCoreName("corex");
      req.process(client);
    }

    runner.stop();

    assertFalse(
        "Instance directory exists after core unload with deleteInstanceDir=true : " + corex,
        corex.exists());
  }

  @Test
  public void testDeleteInstanceDirAfterCreateFailure() throws Exception {
    assumeFalse(
        "Ignore test on windows because it does not delete data directory immediately after unload",
        Constants.WINDOWS);
    File solrHomeDirectory =
        new File(initCoreDataDir, getClass().getName() + "-corex-" + System.nanoTime());
    solrHomeDirectory.mkdirs();
    copySolrHomeToTemp(solrHomeDirectory, "corex");
    File corex = new File(solrHomeDirectory, "corex");
    FileUtils.write(new File(corex, "core.properties"), "", StandardCharsets.UTF_8);
    JettySolrRunner runner =
        new JettySolrRunner(solrHomeDirectory.getAbsolutePath(), buildJettyConfig("/solr"));
    runner.start();

    try (HttpSolrClient client = getHttpSolrClient(runner.getBaseUrl() + "/corex")) {
      client.setConnectionTimeout(SolrTestCaseJ4.DEFAULT_CONNECTION_TIMEOUT);
      client.setSoTimeout(SolrTestCaseJ4.DEFAULT_CONNECTION_TIMEOUT);
      SolrInputDocument doc = new SolrInputDocument();
      doc.addField("id", "123");
      client.add(doc);
      client.commit();
    }

    Path dataDir = null;
    try (HttpSolrClient client = getHttpSolrClient(runner.getBaseUrl().toString())) {
      CoreStatus status = CoreAdminRequest.getCoreStatus("corex", true, client);
      String dataDirectory = status.getDataDirectory();
      dataDir = Paths.get(dataDirectory);
      assertTrue(Files.exists(dataDir));
    }

    File subHome = new File(solrHomeDirectory, "corex" + File.separator + "conf");
    String top = SolrTestCaseJ4.TEST_HOME() + "/collection1/conf";
    FileUtils.copyFile(
        new File(top, "bad-error-solrconfig.xml"), new File(subHome, "solrconfig.xml"));

    try (HttpSolrClient client = getHttpSolrClient(runner.getBaseUrl().toString())) {
      client.setConnectionTimeout(SolrTestCaseJ4.DEFAULT_CONNECTION_TIMEOUT);
      client.setSoTimeout(SolrTestCaseJ4.DEFAULT_CONNECTION_TIMEOUT);
      try {
        CoreAdminRequest.reloadCore("corex", client);
      } catch (Exception e) {
        // this is expected because we put a bad solrconfig -- ignore
      }

      CoreAdminRequest.Unload req = new CoreAdminRequest.Unload(false);
      req.setDeleteDataDir(true);
      req.setDeleteInstanceDir(
          false); // important because the data directory is inside the instance directory
      req.setCoreName("corex");
      req.process(client);
    }

    runner.stop();

    assertTrue(
        "The data directory was not cleaned up on unload after a failed core reload",
        Files.notExists(dataDir));
  }

  @Test
  public void testNonexistentCoreReload() throws Exception {
    final CoreAdminHandler admin = new CoreAdminHandler(h.getCoreContainer());
    SolrQueryResponse resp = new SolrQueryResponse();

    try {
      admin.handleRequestBody(
          req(
              CoreAdminParams.ACTION,
              CoreAdminParams.CoreAdminAction.RELOAD.toString(),
              CoreAdminParams.CORE,
              "non-existent-core"),
          resp);
      fail("Was able to successfully reload non-existent-core");
    } catch (Exception e) {
      assertEquals(
          "Expected error message for non-existent core.",
          "Core with core name [non-existent-core] does not exist.",
          e.getMessage());
    }

    // test null core
    try {
      admin.handleRequestBody(
          req(CoreAdminParams.ACTION, CoreAdminParams.CoreAdminAction.RELOAD.toString()), resp);
      fail("Was able to successfully reload null core");
    } catch (Exception e) {
      if (!(e instanceof SolrException)) {
        fail("Expected SolrException but got " + e);
      }
      assertEquals(
          "Expected error message for non-existent core.",
          "Core with core name [null] does not exist.",
          e.getMessage());
    }
  }
}
@RequiredHistoryLevel(ProcessEngineConfiguration.HISTORY_FULL)
public class MultiTenancyHistoricDecisionInstanceStatisticsQueryTest {

  protected static final String TENANT_ONE = "tenant1";
  protected static final String DISH_DRG_DMN =
      "org/camunda/bpm/engine/test/dmn/deployment/drdDish.dmn11.xml";

  protected static final String DISH_DECISION = "dish-decision";
  protected static final String TEMPERATURE = "temperature";
  protected static final String DAY_TYPE = "dayType";
  protected static final String WEEKEND = "Weekend";
  protected static final String USER_ID = "user";

  protected DecisionService decisionService;
  protected RepositoryService repositoryService;
  protected HistoryService historyService;
  protected IdentityService identityService;

  public ProcessEngineRule engineRule = new ProvidedProcessEngineRule();
  public ProcessEngineTestRule testRule = new ProcessEngineTestRule(engineRule);

  @Rule public RuleChain ruleChain = RuleChain.outerRule(engineRule).around(testRule);

  @Before
  public void setUp() {
    decisionService = engineRule.getDecisionService();
    repositoryService = engineRule.getRepositoryService();
    historyService = engineRule.getHistoryService();
    identityService = engineRule.getIdentityService();

    testRule.deployForTenant(TENANT_ONE, DISH_DRG_DMN);

    decisionService
        .evaluateDecisionByKey(DISH_DECISION)
        .decisionDefinitionTenantId(TENANT_ONE)
        .variables(
            Variables.createVariables().putValue(TEMPERATURE, 21).putValue(DAY_TYPE, WEEKEND))
        .evaluate();
  }

  @Test
  public void testQueryNoAuthenticatedTenants() {
    DecisionRequirementsDefinition decisionRequirementsDefinition =
        repositoryService
            .createDecisionRequirementsDefinitionQuery()
            .tenantIdIn(TENANT_ONE)
            .singleResult();

    identityService.setAuthentication(USER_ID, null, null);

    HistoricDecisionInstanceStatisticsQuery query =
        historyService.createHistoricDecisionInstanceStatisticsQuery(
            decisionRequirementsDefinition.getId());

    assertThat(query.count(), is(0L));
  }

  @Test
  public void testQueryAuthenticatedTenant() {
    DecisionRequirementsDefinition decisionRequirementsDefinition =
        repositoryService
            .createDecisionRequirementsDefinitionQuery()
            .tenantIdIn(TENANT_ONE)
            .singleResult();

    identityService.setAuthentication(USER_ID, null, Arrays.asList(TENANT_ONE));

    HistoricDecisionInstanceStatisticsQuery query =
        historyService.createHistoricDecisionInstanceStatisticsQuery(
            decisionRequirementsDefinition.getId());

    assertThat(query.count(), is(3L));
  }

  @Test
  public void testQueryDisabledTenantCheck() {
    DecisionRequirementsDefinition decisionRequirementsDefinition =
        repositoryService
            .createDecisionRequirementsDefinitionQuery()
            .tenantIdIn(TENANT_ONE)
            .singleResult();

    engineRule.getProcessEngineConfiguration().setTenantCheckEnabled(false);
    identityService.setAuthentication(USER_ID, null, null);

    HistoricDecisionInstanceStatisticsQuery query =
        historyService.createHistoricDecisionInstanceStatisticsQuery(
            decisionRequirementsDefinition.getId());

    assertThat(query.count(), is(3L));
  }
}
public class ValidityCheckingX509ExtendedTrustManagerTest {

  private ValidityCheckingX509ExtendedTrustManager instance =
      new ValidityCheckingX509ExtendedTrustManager();

  public static RSAKeyPairRule key = new RSAKeyPairRule("main");

  public static X509CertificateRule cert =
      new X509CertificateRule("main", key, key, -1, 1, TimeUnit.HOURS);
  public static X509CertificateRule expired =
      new X509CertificateRule("main", key, key, -100, -99, TimeUnit.HOURS);

  @ClassRule public static RuleChain chain = RuleChain.outerRule(key).around(cert).around(expired);

  @Test
  public void checkClientTrusted() throws Exception {
    instance.checkClientTrusted(new X509Certificate[] {cert.certificate()}, "RSA");
  }

  @Test(expected = IllegalArgumentException.class)
  public void checkClientTrusted_nullNonNull() throws Exception {
    instance.checkClientTrusted(null, "RSA");
  }

  @Test(expected = IllegalArgumentException.class)
  public void checkClientTrusted_nonNullNull() throws Exception {
    instance.checkClientTrusted(new X509Certificate[] {cert.certificate()}, null);
  }

  @Test(expected = IllegalArgumentException.class)
  public void checkClientTrusted_nonNullEmpty() throws Exception {
    instance.checkClientTrusted(new X509Certificate[] {cert.certificate()}, "");
  }

  @Test
  public void checkServerTrusted() throws Exception {
    instance.checkServerTrusted(new X509Certificate[] {cert.certificate()}, "RSA");
  }

  @Test(expected = IllegalArgumentException.class)
  public void checkServerTrusted_nullNonNull() throws Exception {
    instance.checkServerTrusted(null, "RSA");
  }

  @Test(expected = IllegalArgumentException.class)
  public void checkServerTrusted_nonNullNull() throws Exception {
    instance.checkServerTrusted(new X509Certificate[] {cert.certificate()}, null);
  }

  @Test(expected = IllegalArgumentException.class)
  public void checkServerTrusted_nonNullEmpty() throws Exception {
    instance.checkServerTrusted(new X509Certificate[] {cert.certificate()}, "");
  }

  @Test
  public void checkClientTrusted1() throws Exception {
    instance.checkClientTrusted(new X509Certificate[] {cert.certificate()}, "RSA", new Socket());
  }

  @Test(expected = IllegalArgumentException.class)
  public void checkClientTrusted1_nullNonNull() throws Exception {
    instance.checkClientTrusted(null, "RSA", new Socket());
  }

  @Test(expected = IllegalArgumentException.class)
  public void checkClientTrusted1_nonNullNull() throws Exception {
    instance.checkClientTrusted(new X509Certificate[] {cert.certificate()}, null, new Socket());
  }

  @Test(expected = IllegalArgumentException.class)
  public void checkClientTrusted1_nonNullEmpty() throws Exception {
    instance.checkClientTrusted(new X509Certificate[] {cert.certificate()}, "", new Socket());
  }

  @Test
  public void checkServerTrusted1() throws Exception {
    instance.checkServerTrusted(new X509Certificate[] {cert.certificate()}, "RSA", new Socket());
  }

  @Test(expected = IllegalArgumentException.class)
  public void checkServerTrusted1_nullNonNull() throws Exception {
    instance.checkServerTrusted(null, "RSA", new Socket());
  }

  @Test(expected = IllegalArgumentException.class)
  public void checkServerTrusted1_nonNullNull() throws Exception {
    instance.checkServerTrusted(new X509Certificate[] {cert.certificate()}, null, new Socket());
  }

  @Test(expected = IllegalArgumentException.class)
  public void checkServerTrusted1_nonNullEmpty() throws Exception {
    instance.checkServerTrusted(new X509Certificate[] {cert.certificate()}, "", new Socket());
  }

  @Test
  public void checkClientTrusted2() throws Exception {
    instance.checkClientTrusted(
        new X509Certificate[] {cert.certificate()}, "RSA", (SSLEngine) null);
  }

  @Test(expected = IllegalArgumentException.class)
  public void checkClientTrusted2_nullNonNull() throws Exception {
    instance.checkClientTrusted(null, "RSA", (SSLEngine) null);
  }

  @Test(expected = IllegalArgumentException.class)
  public void checkClientTrusted2_nonNullNull() throws Exception {
    instance.checkClientTrusted(new X509Certificate[] {cert.certificate()}, null, (SSLEngine) null);
  }

  @Test(expected = IllegalArgumentException.class)
  public void checkClientTrusted2_nonNullEmpty() throws Exception {
    instance.checkClientTrusted(new X509Certificate[] {cert.certificate()}, "", (SSLEngine) null);
  }

  @Test
  public void checkServerTrusted2() throws Exception {
    instance.checkServerTrusted(
        new X509Certificate[] {cert.certificate()}, "RSA", (SSLEngine) null);
  }

  @Test(expected = IllegalArgumentException.class)
  public void checkServerTrusted2_nullNonNull() throws Exception {
    instance.checkServerTrusted(null, "RSA", (SSLEngine) null);
  }

  @Test(expected = IllegalArgumentException.class)
  public void checkServerTrusted2_nonNullNull() throws Exception {
    instance.checkServerTrusted(new X509Certificate[] {cert.certificate()}, null, (SSLEngine) null);
  }

  @Test(expected = IllegalArgumentException.class)
  public void checkServerTrusted2_nonNullEmpty() throws Exception {
    instance.checkServerTrusted(new X509Certificate[] {cert.certificate()}, "", (SSLEngine) null);
  }

  @Test(expected = CertificateException.class)
  public void checkClientExpired() throws Exception {
    instance.checkClientTrusted(new X509Certificate[] {expired.certificate()}, "RSA");
  }

  @Test(expected = CertificateException.class)
  public void checkServerExpired() throws Exception {
    instance.checkServerTrusted(new X509Certificate[] {expired.certificate()}, "RSA");
  }

  @Test(expected = CertificateException.class)
  public void checkClientExpired1() throws Exception {
    instance.checkClientTrusted(new X509Certificate[] {expired.certificate()}, "RSA", new Socket());
  }

  @Test(expected = CertificateException.class)
  public void checkServerExpired1() throws Exception {
    instance.checkServerTrusted(new X509Certificate[] {expired.certificate()}, "RSA", new Socket());
  }

  @Test(expected = CertificateException.class)
  public void checkClientExpired2() throws Exception {
    instance.checkClientTrusted(
        new X509Certificate[] {expired.certificate()}, "RSA", (SSLEngine) null);
  }

  @Test(expected = CertificateException.class)
  public void checkServerExpired2() throws Exception {
    instance.checkServerTrusted(
        new X509Certificate[] {expired.certificate()}, "RSA", (SSLEngine) null);
  }

  @Test
  public void getAcceptedIssuers() throws Exception {
    assertThat(instance.getAcceptedIssuers(), notNullValue());
  }
}
@RunWith(AndroidJUnit4.class)
public class SignInActivityTest {

  public final TestComponentRule component =
      new TestComponentRule(InstrumentationRegistry.getTargetContext());
  public final IntentsTestRule<SignInActivity> main =
      new IntentsTestRule<>(SignInActivity.class, false, false);
  // TestComponentRule needs to go first so we make sure the ApplicationTestComponent is set
  // in the Application before any Activity is launched.
  @Rule public TestRule chain = RuleChain.outerRule(component).around(main);

  private final Account mSelectedAccount =
      new Account("*****@*****.**", SignInActivity.ACCOUNT_TYPE_GOOGLE);

  private UiDevice mDevice;

  @Before
  public void setup() {
    when(component.getMockAccountManager().getAccountsByType(mSelectedAccount.type))
        .thenReturn(new Account[] {mSelectedAccount});
    mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation());
  }

  @Test
  public void checkViewsDisplay() {
    main.launchActivity(SignInActivity.getStartIntent(component.getContext(), false));

    onView(withId(R.id.button_sign_in)).check(matches(isDisplayed()));
    onView(withText(R.string.sign_in_message)).check(matches(isDisplayed()));
    onView(withId(R.id.image_ribot_logo)).check(matches(isDisplayed()));
  }

  @Test
  public void signInSuccessfulNavigatesToWelcome() {
    main.launchActivity(SignInActivity.getStartIntent(component.getContext(), false));
    stubAccountPickerIntent();

    // Stub sign in method in the DataManager
    Ribot ribot = MockModelFabric.newRibot();
    doReturn(Observable.just(ribot)).when(component.getMockDataManager()).signIn(mSelectedAccount);

    onView(withId(R.id.button_sign_in)).perform(click());
    allowPermissionsIfNeeded();

    // Check that it navigates correctly to the welcome screen
    String expectedWelcome =
        main.getActivity().getString(R.string.welcome_greetings, ribot.profile.name.first);
    onView(withText(expectedWelcome)).check(matches(isDisplayed()));
  }

  @Test
  public void signInFailsWithGeneralError() {
    main.launchActivity(SignInActivity.getStartIntent(component.getContext(), false));
    stubAccountPickerIntent();

    // Stub an error when calling sign in
    doReturn(Observable.error(new RuntimeException("Error")))
        .when(component.getMockDataManager())
        .signIn(mSelectedAccount);

    onView(withId(R.id.button_sign_in)).perform(click());
    allowPermissionsIfNeeded();

    onView(withText(R.string.error_sign_in)).check(matches(isDisplayed()));
  }

  @Test
  public void signInFailsWithProfileNotFound() {
    main.launchActivity(SignInActivity.getStartIntent(component.getContext(), false));
    stubAccountPickerIntent();

    // Stub with http 403 error
    HttpException http403Exception = new HttpException(Response.error(403, null));
    doReturn(Observable.error(http403Exception))
        .when(component.getMockDataManager())
        .signIn(mSelectedAccount);

    onView(withId(R.id.button_sign_in)).perform(click());
    allowPermissionsIfNeeded();

    String expectedWelcome =
        main.getActivity().getString(R.string.error_ribot_profile_not_found, mSelectedAccount.name);
    onView(withText(expectedWelcome)).check(matches(isDisplayed()));
  }

  @Test
  public void checkPopUpMessageDisplays() {
    String popUpMessage = "You have been signed out";
    Intent intent = SignInActivity.getStartIntent(component.getContext(), false, popUpMessage);
    main.launchActivity(intent);

    onView(withText(popUpMessage)).check(matches(isDisplayed()));
  }

  private void stubAccountPickerIntent() {
    // Stub the account picker using Espresso intents.
    // It requires the test devices to be signed in into at least 1 Google account.
    Intent data = new Intent();
    data.putExtra(AccountManager.KEY_ACCOUNT_NAME, mSelectedAccount.name);
    ActivityResult result = new ActivityResult(Activity.RESULT_OK, data);
    // The account picker intent is a bit special and it doesn't seem to have an Action or
    // package, so we have to match it by some of the extra keys.
    // This is not ideal but I couldn't find a better way.
    intending(hasExtraWithKey("allowableAccountTypes")).respondWith(result);
  }

  private void allowPermissionsIfNeeded() {
    if (Build.VERSION.SDK_INT >= 23) {
      UiObject allowPermissions = mDevice.findObject(new UiSelector().text("Allow"));
      if (allowPermissions.exists()) {
        try {
          allowPermissions.click();
        } catch (UiObjectNotFoundException e) {
          Timber.w(e, "There is no permissions dialog to interact with ");
        }
      }
    }
  }
}