View Javadoc
1   /**
2    * Copyright 2014 Internet2
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *   http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  /*
17    Copyright (C) 2004-2007 University Corporation for Advanced Internet Development, Inc.
18    Copyright (C) 2004-2007 The University Of Chicago
19  
20    Licensed under the Apache License, Version 2.0 (the "License");
21    you may not use this file except in compliance with the License.
22    You may obtain a copy of the License at
23  
24      http://www.apache.org/licenses/LICENSE-2.0
25  
26    Unless required by applicable law or agreed to in writing, software
27    distributed under the License is distributed on an "AS IS" BASIS,
28    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
29    See the License for the specific language governing permissions and
30    limitations under the License.
31  */
32  
33  package edu.internet2.middleware.grouper.membership;
34  
35  
36  import java.io.StringReader;
37  import java.sql.Timestamp;
38  import java.util.Date;
39  import java.util.Set;
40  
41  import junit.textui.TestRunner;
42  
43  import org.apache.commons.logging.Log;
44  
45  import bsh.Interpreter;
46  
47  import edu.internet2.middleware.grouper.Field;
48  import edu.internet2.middleware.grouper.FieldFinder;
49  import edu.internet2.middleware.grouper.Group;
50  import edu.internet2.middleware.grouper.GrouperSession;
51  import edu.internet2.middleware.grouper.Member;
52  import edu.internet2.middleware.grouper.MemberFinder;
53  import edu.internet2.middleware.grouper.Membership;
54  import edu.internet2.middleware.grouper.MembershipFinder;
55  import edu.internet2.middleware.grouper.Stem;
56  import edu.internet2.middleware.grouper.StemFinder;
57  import edu.internet2.middleware.grouper.SubjectFinder;
58  import edu.internet2.middleware.grouper.attr.AttributeDef;
59  import edu.internet2.middleware.grouper.attr.AttributeDefType;
60  import edu.internet2.middleware.grouper.cfg.GrouperConfig;
61  import edu.internet2.middleware.grouper.changeLog.ChangeLogTempToEntity;
62  import edu.internet2.middleware.grouper.group.GroupSet;
63  import edu.internet2.middleware.grouper.helper.GrouperTest;
64  import edu.internet2.middleware.grouper.helper.R;
65  import edu.internet2.middleware.grouper.helper.SessionHelper;
66  import edu.internet2.middleware.grouper.helper.SubjectTestHelper;
67  import edu.internet2.middleware.grouper.hibernate.AuditControl;
68  import edu.internet2.middleware.grouper.hibernate.GrouperTransactionType;
69  import edu.internet2.middleware.grouper.hibernate.HibernateHandler;
70  import edu.internet2.middleware.grouper.hibernate.HibernateHandlerBean;
71  import edu.internet2.middleware.grouper.hibernate.HibernateSession;
72  import edu.internet2.middleware.grouper.internal.dao.GrouperDAOException;
73  import edu.internet2.middleware.grouper.internal.util.GrouperUuid;
74  import edu.internet2.middleware.grouper.misc.CompositeType;
75  import edu.internet2.middleware.grouper.misc.FindBadMemberships;
76  import edu.internet2.middleware.grouper.misc.GrouperDAOFactory;
77  import edu.internet2.middleware.grouper.pit.PITField;
78  import edu.internet2.middleware.grouper.pit.PITGroup;
79  import edu.internet2.middleware.grouper.pit.PITGroupSet;
80  import edu.internet2.middleware.grouper.pit.PITMembership;
81  import edu.internet2.middleware.grouper.privs.AccessPrivilege;
82  import edu.internet2.middleware.grouper.privs.AttributeDefPrivilege;
83  import edu.internet2.middleware.grouper.privs.NamingPrivilege;
84  import edu.internet2.middleware.grouper.util.GrouperUtil;
85  import edu.internet2.middleware.subject.Subject;
86  
87  /**
88   * @author shilen
89   */
90  public class TestFindBadMemberships extends GrouperTest {
91  
92    @SuppressWarnings("unused")
93    private static final Log LOG = GrouperUtil.getLog(TestFindBadMemberships.class);
94  
95    private GrouperSession grouperSession;
96    private Stem top;
97    private Group owner1;
98    private Group owner2;
99    private Group owner3;
100   private Group owner4;
101   private Group owner5;
102   private Group owner6;
103   private Group owner7;
104   private Group subjEGroup;
105   private Subject subjA;
106   private Subject subjB;
107   private Subject subjC;
108   private Subject subjD;
109   private Subject subjE;
110   private Subject subjF;
111   
112   /**
113    * @param name
114    */
115   public TestFindBadMemberships(String name) {
116     super(name);
117   }
118 
119   /**
120    * @param args
121    */
122   public static void main(String[] args) {
123     TestRunner.run(new TestFindBadMemberships("testWithMissingComposite"));
124   }
125   
126   protected void setUp () {
127     super.setUp();
128     GrouperConfig.retrieveConfig().propertiesOverrideMap().put("findBadMemberships.waitForChangeLogJobProcessTime", "1");
129     FindBadMemberships.clearResults();
130     FindBadMemberships.printErrorsToSTOUT(false);
131   }
132   
133   /**
134    * @throws InterruptedException 
135    * 
136    */
137   public void testBadEffectiveGroupSets() throws InterruptedException {
138     grouperSession = SessionHelper.getRootSession();
139     Stem root = StemFinder.findRootStem(grouperSession);
140     top = root.addChildStem("top", "top");
141     final Group test1 = top.addChildGroup("test1", "test1");
142     final Group test2 = top.addChildGroup("test2", "test2");
143     final Group test3 = top.addChildGroup("test3", "test3");
144     final Group test4 = top.addChildGroup("test4", "test4");
145     final Group test5 = top.addChildGroup("test5", "test5");
146     
147     test1.addMember(test2.toSubject());
148     test2.addMember(test3.toSubject());
149     test4.addMember(test5.toSubject());
150     
151     int correctSize = HibernateSession.bySqlStatic().select(int.class,
152         "select count(1) from grouper_group_set");
153     
154     // now mess up the group sets
155     test3.addMember(test4.toSubject());
156     test2.deleteMember(test3.toSubject());
157     
158     ChangeLogTempToEntity.convertRecords();
159     
160     final String[] state = new String[1];
161     state[0] = "1";
162 
163     // perform these operations in parallel so it messes up the group sets
164     Thread thread1 = new Thread(new Runnable() {
165 
166       public void run() {
167         HibernateSession.callbackHibernateSession(
168             GrouperTransactionType.READ_WRITE_NEW, AuditControl.WILL_NOT_AUDIT, new HibernateHandler() {
169 
170           public Object callback(HibernateHandlerBean hibernateHandlerBean)
171               throws GrouperDAOException {
172 
173             GrouperSession.startRootSession();
174             test2.addMember(test3.toSubject());
175             
176             state[0] = "2";
177             
178             while (true) {
179               if (state[0].equals("2")) {
180                 try {
181                   Thread.sleep(100);
182                 } catch (InterruptedException e) {
183                   // ignore
184                 }
185               } else {
186                 break;
187               }
188             }
189             return null;
190           }
191         });
192       }
193     });
194     
195     thread1.start();
196     
197     Thread thread2 = new Thread(new Runnable() {
198 
199       public void run() {
200         HibernateSession.callbackHibernateSession(
201             GrouperTransactionType.READ_WRITE_NEW, AuditControl.WILL_NOT_AUDIT, new HibernateHandler() {
202 
203           public Object callback(HibernateHandlerBean hibernateHandlerBean)
204               throws GrouperDAOException {
205 
206             GrouperSession.startRootSession();
207             
208             while (true) {
209               if (state[0].equals("1")) {
210                 try {
211                   Thread.sleep(100);
212                 } catch (InterruptedException e) {
213                   // ignore
214                 }
215               } else {
216                 break;
217               }
218             }
219             
220             test3.deleteMember(test4.toSubject());
221             state[0] = "3";
222 
223             return null;
224           }
225         });
226       }
227     });
228     
229     thread2.start();
230 
231     thread1.join();
232     thread2.join();
233     
234     int newSize = HibernateSession.bySqlStatic().select(int.class,
235         "select count(1) from grouper_group_set");
236     
237     // we should have 4 bad group sets
238     assertEquals(correctSize, newSize - 4);
239     
240     ChangeLogTempToEntity.convertRecords();
241     
242     // now check and fix it
243     assertEquals(4, FindBadMemberships.checkAll());
244     String gsh = "importCommands(\"edu.internet2.middleware.grouper.app.gsh\");\nimport edu.internet2.middleware.grouper.*;\nimport edu.internet2.middleware.grouper.misc.*;\n" + FindBadMemberships.gshScript.toString();
245     new Interpreter(new StringReader(gsh), System.out, System.err, false).run();
246     assertEquals(0, FindBadMemberships.checkAll());
247     
248     // verify we don't mess up point in time, there may be changes there to fix pit group sets
249     ChangeLogTempToEntity.convertRecords();
250     new edu.internet2.middleware.grouper.misc.SyncPITTables().showResults(false).syncAllPITTables();
251     ChangeLogTempToEntity.convertRecords();
252 
253     newSize = HibernateSession.bySqlStatic().select(int.class,
254         "select count(1) from grouper_group_set");
255     
256     assertEquals(correctSize, newSize);
257     
258     int pitSize = HibernateSession.bySqlStatic().select(int.class,
259         "select count(1) from grouper_pit_group_set where active='T'");
260     
261     assertEquals(correctSize, pitSize);
262   }
263   
264   /**
265    * @throws Exception
266    */
267   public void testDuplicates() throws Exception {
268     grouperSession = SessionHelper.getRootSession();
269     Stem root = StemFinder.findRootStem(grouperSession);
270     top = root.addChildStem("top", "top");
271     Group test1 = top.addChildGroup("test1", "test1");
272     Group test2 = top.addChildGroup("test2", "test2");
273     Group test3 = top.addChildGroup("test3", "test3");
274     Group test4 = top.addChildGroup("test4", "test4");
275     Group test5 = top.addChildGroup("test5", "test5");
276     
277     Group test7 = top.addChildGroup("test7", "test7");
278     
279     test1.addMember(test2.toSubject());
280     test2.addMember(test3.toSubject());
281     test3.addMember(test4.toSubject());
282     test4.addMember(test5.toSubject());
283     
284     // add to point in time
285     ChangeLogTempToEntity.convertRecords();
286     
287     // all should be good right now
288     assertEquals(0, FindBadMemberships.checkAll());
289     
290     {
291       // 2 with same owner/member/field with 1 having a foreign key
292       GroupSet selfGroupSetTest2 = GrouperDAOFactory.getFactory().getGroupSet().findSelfGroup(test2.getId(), Group.getDefaultList().getId());
293       
294       GroupSet duplicate1 = new GroupSet();
295       duplicate1.setId(GrouperUuid.getUuid());
296       duplicate1.setCreatorId(selfGroupSetTest2.getCreatorId());
297       duplicate1.setCreateTime(selfGroupSetTest2.getCreateTime());
298       duplicate1.setDepth(selfGroupSetTest2.getDepth());
299       duplicate1.setMemberGroupId(selfGroupSetTest2.getMemberGroupId());
300       duplicate1.setOwnerGroupId(selfGroupSetTest2.getOwnerGroupId());
301       duplicate1.setParentId(duplicate1.getId());
302       duplicate1.setFieldId(selfGroupSetTest2.getFieldId());
303       GrouperDAOFactory.getFactory().getGroupSet().save(duplicate1);
304     }
305     
306     {
307       // 3 with same owner/member/field with 1 having a foreign key
308       GroupSet selfGroupSetTest3 = GrouperDAOFactory.getFactory().getGroupSet().findSelfGroup(test3.getId(), Group.getDefaultList().getId());
309       
310       GroupSet duplicate1 = new GroupSet();
311       duplicate1.setId(GrouperUuid.getUuid());
312       duplicate1.setCreatorId(selfGroupSetTest3.getCreatorId());
313       duplicate1.setCreateTime(selfGroupSetTest3.getCreateTime());
314       duplicate1.setDepth(selfGroupSetTest3.getDepth());
315       duplicate1.setMemberGroupId(selfGroupSetTest3.getMemberGroupId());
316       duplicate1.setOwnerGroupId(selfGroupSetTest3.getOwnerGroupId());
317       duplicate1.setParentId(duplicate1.getId());
318       duplicate1.setFieldId(selfGroupSetTest3.getFieldId());
319       GrouperDAOFactory.getFactory().getGroupSet().save(duplicate1);
320       
321       GroupSet duplicate2 = new GroupSet();
322       duplicate2.setId(GrouperUuid.getUuid());
323       duplicate2.setCreatorId(selfGroupSetTest3.getCreatorId());
324       duplicate2.setCreateTime(selfGroupSetTest3.getCreateTime());
325       duplicate2.setDepth(selfGroupSetTest3.getDepth());
326       duplicate2.setMemberGroupId(selfGroupSetTest3.getMemberGroupId());
327       duplicate2.setOwnerGroupId(selfGroupSetTest3.getOwnerGroupId());
328       duplicate2.setParentId(duplicate2.getId());
329       duplicate2.setFieldId(selfGroupSetTest3.getFieldId());
330       GrouperDAOFactory.getFactory().getGroupSet().save(duplicate2);
331     }
332     
333     {
334       // 2 with same owner/member/field, no foreign keys
335       GroupSet selfGroupSetTest7 = GrouperDAOFactory.getFactory().getGroupSet().findSelfGroup(test7.getId(), Group.getDefaultList().getId());
336       
337       GroupSet duplicate1 = new GroupSet();
338       duplicate1.setId(GrouperUuid.getUuid());
339       duplicate1.setCreatorId(selfGroupSetTest7.getCreatorId());
340       duplicate1.setCreateTime(selfGroupSetTest7.getCreateTime());
341       duplicate1.setDepth(selfGroupSetTest7.getDepth());
342       duplicate1.setMemberGroupId(selfGroupSetTest7.getMemberGroupId());
343       duplicate1.setOwnerGroupId(selfGroupSetTest7.getOwnerGroupId());
344       duplicate1.setParentId(duplicate1.getId());
345       duplicate1.setFieldId(selfGroupSetTest7.getFieldId());
346       GrouperDAOFactory.getFactory().getGroupSet().save(duplicate1);
347     }
348     
349     // now check it
350     assertEquals(4, FindBadMemberships.checkAll());
351     String gsh = "importCommands(\"edu.internet2.middleware.grouper.app.gsh\");\nimport edu.internet2.middleware.grouper.*;\nimport edu.internet2.middleware.grouper.misc.*;\n" + FindBadMemberships.gshScript.toString();
352     new Interpreter(new StringReader(gsh), System.out, System.err, false).run();
353     assertEquals(0, FindBadMemberships.checkAll());
354     
355     // verify we don't mess up point in time, there may be changes there to fix pit group sets
356     ChangeLogTempToEntity.convertRecords();
357     new edu.internet2.middleware.grouper.misc.SyncPITTables().showResults(false).syncAllPITTables();
358     ChangeLogTempToEntity.convertRecords();
359   }
360   
361   /**
362    * @throws Exception
363    */
364   public void testGrouperAllMembership() throws Exception {
365     grouperSession = SessionHelper.getRootSession();
366     Stem root = StemFinder.findRootStem(grouperSession);
367     top = root.addChildStem("top", "top");
368     Group test = top.addChildGroup("test", "test");
369     
370     Field badField = Group.getDefaultList();
371     PITField badPITField = GrouperDAOFactory.getFactory().getPITField().findBySourceIdActive(badField.getId(), true);
372 
373     test.grantPriv(SubjectFinder.findAllSubject(), AccessPrivilege.OPTIN);
374     
375     // add to point in time
376     ChangeLogTempToEntity.convertRecords();
377     
378     Membership membership = MembershipFinder.findImmediateMembership(grouperSession, test, SubjectFinder.findAllSubject(), AccessPrivilege.OPTIN.getField(), true);
379     
380     // all should be good right now
381     assertEquals(0, FindBadMemberships.checkAll());
382     
383     // now update to the bad membership
384     HibernateSession.bySqlStatic().executeSql("update grouper_memberships set field_id = '" + badField.getId() + "' where id='" + membership.getImmediateMembershipId() + "'");
385     
386     // update bad pit membership
387     PITMembership pitMembership = GrouperDAOFactory.getFactory().getPITMembership().findBySourceIdUnique(membership.getImmediateMembershipId(), true);
388     pitMembership.setFieldId(badPITField.getId());
389     pitMembership.update();
390     
391     // everything should seem to be okay as far as PIT goes
392     ChangeLogTempToEntity.convertRecords();
393     assertEquals(0, new edu.internet2.middleware.grouper.misc.SyncPITTables().showResults(false).syncAllPITTables());
394     
395     // now check it
396     assertEquals(1, FindBadMemberships.checkAll());
397     String gsh = "importCommands(\"edu.internet2.middleware.grouper.app.gsh\");\nimport edu.internet2.middleware.grouper.*;\nimport edu.internet2.middleware.grouper.misc.*;\n" + FindBadMemberships.gshScript.toString();
398     new Interpreter(new StringReader(gsh), System.out, System.err, false).run();
399     assertEquals(0, FindBadMemberships.checkAll());
400     
401     // verify we don't mess up point in time
402     ChangeLogTempToEntity.convertRecords();
403     assertEquals(0, new edu.internet2.middleware.grouper.misc.SyncPITTables().showResults(false).syncAllPITTables());
404   }
405   
406   /**
407    * @throws Exception
408    */
409   public void testGrouperAllGroupAttrUpdatePrivilege() throws Exception {
410     grouperSession = SessionHelper.getRootSession();
411     Stem root = StemFinder.findRootStem(grouperSession);
412     top = root.addChildStem("top", "top");
413     Group test = top.addChildGroup("test", "test");
414     
415     Field badField = AccessPrivilege.GROUP_ATTR_UPDATE.getField();
416     PITField badPITField = GrouperDAOFactory.getFactory().getPITField().findBySourceIdActive(badField.getId(), true);
417 
418     test.grantPriv(SubjectFinder.findAllSubject(), AccessPrivilege.OPTIN);
419     
420     // add to point in time
421     ChangeLogTempToEntity.convertRecords();
422     
423     Membership membership = MembershipFinder.findImmediateMembership(grouperSession, test, SubjectFinder.findAllSubject(), AccessPrivilege.OPTIN.getField(), true);
424     
425     // all should be good right now
426     assertEquals(0, FindBadMemberships.checkAll());
427     
428     // now update to the bad membership
429     HibernateSession.bySqlStatic().executeSql("update grouper_memberships set field_id = '" + badField.getId() + "' where id='" + membership.getImmediateMembershipId() + "'");
430     
431     // update bad pit membership
432     PITMembership pitMembership = GrouperDAOFactory.getFactory().getPITMembership().findBySourceIdUnique(membership.getImmediateMembershipId(), true);
433     pitMembership.setFieldId(badPITField.getId());
434     pitMembership.update();
435     
436     // everything should seem to be okay as far as PIT goes
437     ChangeLogTempToEntity.convertRecords();
438     assertEquals(0, new edu.internet2.middleware.grouper.misc.SyncPITTables().showResults(false).syncAllPITTables());
439     
440     // now check it
441     assertEquals(1, FindBadMemberships.checkAll());
442     String gsh = "importCommands(\"edu.internet2.middleware.grouper.app.gsh\");\nimport edu.internet2.middleware.grouper.*;\nimport edu.internet2.middleware.grouper.misc.*;\n" + FindBadMemberships.gshScript.toString();
443     new Interpreter(new StringReader(gsh), System.out, System.err, false).run();
444     assertEquals(0, FindBadMemberships.checkAll());
445     
446     // verify we don't mess up point in time
447     ChangeLogTempToEntity.convertRecords();
448     assertEquals(0, new edu.internet2.middleware.grouper.misc.SyncPITTables().showResults(false).syncAllPITTables());
449   }
450   
451   /**
452    * @throws Exception
453    */
454   public void testGrouperAllUpdatePrivilege() throws Exception {
455     grouperSession = SessionHelper.getRootSession();
456     Stem root = StemFinder.findRootStem(grouperSession);
457     top = root.addChildStem("top", "top");
458     Group test = top.addChildGroup("test", "test");
459     
460     Field badField = AccessPrivilege.UPDATE.getField();
461     PITField badPITField = GrouperDAOFactory.getFactory().getPITField().findBySourceIdActive(badField.getId(), true);
462 
463     test.grantPriv(SubjectFinder.findAllSubject(), AccessPrivilege.OPTIN);
464     
465     // add to point in time
466     ChangeLogTempToEntity.convertRecords();
467     
468     Membership membership = MembershipFinder.findImmediateMembership(grouperSession, test, SubjectFinder.findAllSubject(), AccessPrivilege.OPTIN.getField(), true);
469     
470     // all should be good right now
471     assertEquals(0, FindBadMemberships.checkAll());
472     
473     // now update to the bad membership
474     HibernateSession.bySqlStatic().executeSql("update grouper_memberships set field_id = '" + badField.getId() + "' where id='" + membership.getImmediateMembershipId() + "'");
475     
476     // update bad pit membership
477     PITMembership pitMembership = GrouperDAOFactory.getFactory().getPITMembership().findBySourceIdUnique(membership.getImmediateMembershipId(), true);
478     pitMembership.setFieldId(badPITField.getId());
479     pitMembership.update();
480     
481     // everything should seem to be okay as far as PIT goes
482     ChangeLogTempToEntity.convertRecords();
483     assertEquals(0, new edu.internet2.middleware.grouper.misc.SyncPITTables().showResults(false).syncAllPITTables());
484     
485     // now check it
486     assertEquals(1, FindBadMemberships.checkAll());
487     String gsh = "importCommands(\"edu.internet2.middleware.grouper.app.gsh\");\nimport edu.internet2.middleware.grouper.*;\nimport edu.internet2.middleware.grouper.misc.*;\n" + FindBadMemberships.gshScript.toString();
488     new Interpreter(new StringReader(gsh), System.out, System.err, false).run();
489     assertEquals(0, FindBadMemberships.checkAll());
490     
491     // verify we don't mess up point in time
492     ChangeLogTempToEntity.convertRecords();
493     assertEquals(0, new edu.internet2.middleware.grouper.misc.SyncPITTables().showResults(false).syncAllPITTables());
494   }
495   
496   /**
497    * @throws Exception
498    */
499   public void testGrouperAllAdminPrivilege() throws Exception {
500     grouperSession = SessionHelper.getRootSession();
501     Stem root = StemFinder.findRootStem(grouperSession);
502     top = root.addChildStem("top", "top");
503     Group test = top.addChildGroup("test", "test");
504     
505     Field badField = AccessPrivilege.ADMIN.getField();
506     PITField badPITField = GrouperDAOFactory.getFactory().getPITField().findBySourceIdActive(badField.getId(), true);
507 
508     test.grantPriv(SubjectFinder.findAllSubject(), AccessPrivilege.OPTIN);
509     
510     // add to point in time
511     ChangeLogTempToEntity.convertRecords();
512     
513     Membership membership = MembershipFinder.findImmediateMembership(grouperSession, test, SubjectFinder.findAllSubject(), AccessPrivilege.OPTIN.getField(), true);
514     
515     // all should be good right now
516     assertEquals(0, FindBadMemberships.checkAll());
517     
518     // now update to the bad membership
519     HibernateSession.bySqlStatic().executeSql("update grouper_memberships set field_id = '" + badField.getId() + "' where id='" + membership.getImmediateMembershipId() + "'");
520     
521     // update bad pit membership
522     PITMembership pitMembership = GrouperDAOFactory.getFactory().getPITMembership().findBySourceIdUnique(membership.getImmediateMembershipId(), true);
523     pitMembership.setFieldId(badPITField.getId());
524     pitMembership.update();
525     
526     // everything should seem to be okay as far as PIT goes
527     ChangeLogTempToEntity.convertRecords();
528     assertEquals(0, new edu.internet2.middleware.grouper.misc.SyncPITTables().showResults(false).syncAllPITTables());
529     
530     // now check it
531     assertEquals(1, FindBadMemberships.checkAll());
532     String gsh = "importCommands(\"edu.internet2.middleware.grouper.app.gsh\");\nimport edu.internet2.middleware.grouper.*;\nimport edu.internet2.middleware.grouper.misc.*;\n" + FindBadMemberships.gshScript.toString();
533     new Interpreter(new StringReader(gsh), System.out, System.err, false).run();
534     assertEquals(0, FindBadMemberships.checkAll());
535     
536     // verify we don't mess up point in time
537     ChangeLogTempToEntity.convertRecords();
538     assertEquals(0, new edu.internet2.middleware.grouper.misc.SyncPITTables().showResults(false).syncAllPITTables());
539   }
540 
541   /**
542    * Test bad composites without composites
543    */
544   public void testWithoutComposites() {
545     assertEquals(0, FindBadMemberships.checkAll());
546   }
547   
548   /**
549    * @throws Exception
550    */
551   private void setUpComposites() throws Exception {
552     runCompositeMembershipChangeLogConsumer();
553     
554     R r = R.populateRegistry(0, 0, 6);
555     subjA = r.getSubject("a");
556     subjB = r.getSubject("b");
557     subjC = r.getSubject("c");
558     subjD = r.getSubject("d");
559     subjF = r.getSubject("f");
560 
561     grouperSession = SessionHelper.getRootSession();
562     Stem root = StemFinder.findRootStem(grouperSession);
563     top = root.addChildStem("top", "top");
564     
565     subjEGroup = top.addChildGroup("subjE", "subjE");
566     subjEGroup.addMember(subjC);
567     subjE = subjEGroup.toSubject();
568     
569     owner1 = top.addChildGroup("owner1", "owner1");
570     owner2 = top.addChildGroup("owner2", "owner2");
571     owner3 = top.addChildGroup("owner3", "owner3");
572     owner4 = top.addChildGroup("owner4", "owner4");
573     owner5 = top.addChildGroup("owner5", "owner5");
574     owner6 = top.addChildGroup("owner6", "owner6");
575     owner7 = top.addChildGroup("owner7", "owner7");
576     
577     Group left1 = top.addChildGroup("left1", "left1");
578     Group left2 = top.addChildGroup("left2", "left2");
579     Group left3 = top.addChildGroup("left3", "left3");
580     Group left4 = top.addChildGroup("left4", "left4");
581     Group left5 = top.addChildGroup("left5", "left5");
582     Group left6 = top.addChildGroup("left6", "left6");
583     Group left7 = top.addChildGroup("left7", "left7");
584 
585     Group right1 = top.addChildGroup("right1", "right1");
586     Group right2 = top.addChildGroup("right2", "right2");
587     Group right3 = top.addChildGroup("right3", "right3");
588     Group right4 = top.addChildGroup("right4", "right4");
589     Group right5 = top.addChildGroup("right5", "right5");
590     Group right6 = top.addChildGroup("right6", "right6");
591     Group right7 = top.addChildGroup("right7", "right7");
592     
593     owner1.addCompositeMember(CompositeType.UNION, left1, right1);
594     owner2.addCompositeMember(CompositeType.COMPLEMENT, left2, right2);
595     owner3.addCompositeMember(CompositeType.INTERSECTION, left3, right3);
596     owner4.addCompositeMember(CompositeType.UNION, left4, right4);
597     owner5.addCompositeMember(CompositeType.COMPLEMENT, left5, right5);
598     owner6.addCompositeMember(CompositeType.INTERSECTION, left6, right6);
599     owner7.addCompositeMember(CompositeType.UNION, left7, right7);
600     
601     left1.addMember(subjA);
602     left1.addMember(subjB);
603     left1.addMember(subjE);
604     left2.addMember(subjA);
605     left2.addMember(subjB);
606     left2.addMember(subjE);
607     left2.addMember(subjF);
608     right2.addMember(subjB);
609     left3.addMember(subjA);
610     right3.addMember(subjA);
611     
612     left4.addMember(subjA);
613     left4.addMember(subjB);
614     left4.addMember(subjE);
615     left5.addMember(subjA);
616     left5.addMember(subjB);
617     left5.addMember(subjE);
618     right5.addMember(subjB);
619     left6.addMember(subjA);
620     right6.addMember(subjA);
621     
622     runCompositeMembershipChangeLogConsumer();
623   }
624   
625   /**
626    * Test bad composites with composites that are okay
627    * @throws Exception 
628    */
629   public void testWithGoodComposites() throws Exception {
630     setUpComposites();
631     assertEquals(0, FindBadMemberships.checkAll());
632   }
633   
634   /**
635    * Don't want false positives with circular group sets
636    * @throws Exception 
637    */
638   public void testCircular() throws Exception {
639     setUpComposites();
640     Group gA1 = top.addChildGroup("gA1", "gA1");
641     Group gA2 = top.addChildGroup("gA2", "gA2");
642     gA1.addMember(gA2.toSubject());
643     gA2.addMember(gA1.toSubject());
644     
645     Group gB1 = top.addChildGroup("gB1", "gB1");
646     Group gB2 = top.addChildGroup("gB2", "gB2");
647     Group gB3 = top.addChildGroup("gB3", "gB3");
648     gB1.addMember(gB2.toSubject());
649     gB2.addMember(gB3.toSubject());
650     gB3.addMember(gB1.toSubject());
651     
652     Group gC1 = top.addChildGroup("gC1", "gC1");
653     Group gC2 = top.addChildGroup("gC2", "gC2");
654     Group gC3 = top.addChildGroup("gC3", "gC3");
655     Group gC4 = top.addChildGroup("gC4", "gC4");
656     gC1.addMember(gC2.toSubject());
657     gC2.addMember(gC3.toSubject());
658     gC3.addMember(gC4.toSubject());
659     gC4.addMember(gC1.toSubject());
660     
661     Group gD1 = top.addChildGroup("gD1", "gD1");
662     Group gD2 = top.addChildGroup("gD2", "gD2");
663     Group gD3 = top.addChildGroup("gD3", "gD3");
664     gD1.addMember(gD2.toSubject());
665     gD2.addMember(gD3.toSubject());
666     gD3.addMember(gD2.toSubject());
667     
668     Stem sE1 = top.addChildStem("sE1", "sE1");
669     Group gE2 = top.addChildGroup("gE2", "gE2");
670     Group gE3 = top.addChildGroup("gE3", "gE3");
671     sE1.grantPriv(gE2.toSubject(), NamingPrivilege.STEM);
672     gE2.addMember(gE3.toSubject());
673     gE3.addMember(gE2.toSubject());
674     
675     Stem sF1 = top.addChildStem("sF1", "sF1");
676     Group gF2 = top.addChildGroup("gF2", "gF2");
677     Group gF3 = top.addChildGroup("gF3", "gF3");
678     Group gF4 = top.addChildGroup("gF4", "gF4");
679     sF1.grantPriv(gF2.toSubject(), NamingPrivilege.STEM);
680     gF2.addMember(gF3.toSubject());
681     gF3.addMember(gF4.toSubject());
682     gF4.addMember(gF2.toSubject());
683     
684     Group gG1 = top.addChildGroup("gG1", "gG1");
685     gG1.grantPriv(gG1.toSubject(), AccessPrivilege.ADMIN);
686     
687     Group gH1 = top.addChildGroup("gH1", "gH1");
688     Group gH2 = top.addChildGroup("gH2", "gH2");
689     Group gH3 = top.addChildGroup("gH3", "gH3");
690     gH1.grantPriv(gH2.toSubject(), AccessPrivilege.ADMIN);
691     gH2.addMember(gH3.toSubject());
692     gH3.addMember(gH1.toSubject());
693     
694     Group gI1 = top.addChildGroup("gI1", "gI1");
695     Group gI2 = top.addChildGroup("gI2", "gI2");
696     gI1.grantPriv(gI2.toSubject(), AccessPrivilege.ADMIN);
697     gI2.addMember(gI1.toSubject());
698     
699     assertEquals(0, FindBadMemberships.checkAll());
700     
701     // now lets remove some group sets
702     
703     int groupSetCount = HibernateSession.bySqlStatic().select(int.class, "select count(1) from grouper_group_set");
704     
705     // let's delete group sets
706     Set<GroupSet> groupSets = GrouperDAOFactory.getFactory().getGroupSet().findAllByOwnerAndMemberAndField(gH1.getUuid(), gH1.getUuid(), FieldFinder.find("admins", true).getUuid());
707     for (GroupSet gs : groupSets) {
708       if (gs.getDepth() != 0) {
709         gs.delete(false);
710       }
711     }
712     
713     groupSets = GrouperDAOFactory.getFactory().getGroupSet().findAllByOwnerAndMemberAndField(gI1.getUuid(), gI1.getUuid(), FieldFinder.find("admins", true).getUuid());
714     for (GroupSet gs : groupSets) {
715       if (gs.getDepth() != 0) {
716         gs.delete(false);
717       }
718     }
719     
720     // add to point in time
721     ChangeLogTempToEntity.convertRecords();
722 
723     assertEquals(2, FindBadMemberships.checkAll());
724     String gsh = "importCommands(\"edu.internet2.middleware.grouper.app.gsh\");\nimport edu.internet2.middleware.grouper.*;\nimport edu.internet2.middleware.grouper.misc.*;\n" + FindBadMemberships.gshScript.toString();
725     new Interpreter(new StringReader(gsh), System.out, System.err, false).run();
726     assertEquals(0, FindBadMemberships.checkAll());
727     
728     // verify we don't mess up point in time
729     ChangeLogTempToEntity.convertRecords();
730     assertEquals(0, new edu.internet2.middleware.grouper.misc.SyncPITTables().showResults(false).syncAllPITTables());
731     
732     // verify counts
733     int newGroupSetCount = HibernateSession.bySqlStatic().select(int.class, "select count(1) from grouper_group_set");
734     int newPitGroupSetCountActive = HibernateSession.bySqlStatic().select(int.class, "select count(1) from grouper_pit_group_set where active='T'");
735     assertEquals(groupSetCount, newGroupSetCount);
736     assertEquals(groupSetCount, newPitGroupSetCountActive);
737   }
738   
739   /**
740    * Test bad composites when there are missing composites
741    * @throws Exception
742    */
743   public void testWithMissingComposite() throws Exception {
744     setUpComposites();
745     
746     Membership ms1 = MembershipFinder.findCompositeMembership(grouperSession, owner1, subjC, true);
747     Membership ms2 = MembershipFinder.findCompositeMembership(grouperSession, owner2, subjF, true);
748     Membership ms3 = MembershipFinder.findCompositeMembership(grouperSession, owner3, subjA, true);
749     
750     Membership ms4 = MembershipFinder.findCompositeMembership(grouperSession, owner2, subjE, false);
751     assertNull(ms4);
752     
753     ms1.delete();
754     ms2.delete();
755     ms3.delete();
756     
757     ChangeLogTempToEntity.convertRecords();
758     
759     assertEquals(3, FindBadMemberships.checkAll());
760     String gsh = "import edu.internet2.middleware.grouper.*;\nimport edu.internet2.middleware.grouper.misc.*;\n" + FindBadMemberships.gshScript.toString();
761     new Interpreter(new StringReader(gsh), System.out, System.err, false).run();
762     assertEquals(0, FindBadMemberships.checkAll());
763     
764     // verify we don't mess up point in time
765     ChangeLogTempToEntity.convertRecords();
766     assertEquals(0, new edu.internet2.middleware.grouper.misc.SyncPITTables().showResults(false).syncAllPITTables());
767   }
768   
769   /**
770    * Test bad composites when there are extra composites
771    * @throws Exception
772    */
773   public void testWithExtraComposite() throws Exception {
774     setUpComposites();
775     
776     Membership ms1 = MembershipFinder.findCompositeMembership(grouperSession, owner1, subjC, true);
777     Membership ms2 = MembershipFinder.findCompositeMembership(grouperSession, owner2, subjF, true);
778     Membership ms3 = MembershipFinder.findCompositeMembership(grouperSession, owner3, subjA, true);
779     
780     ms1.setHibernateVersionNumber(-1L);
781     ms2.setHibernateVersionNumber(-1L);
782     ms3.setHibernateVersionNumber(-1L);
783     
784     ms1.setImmediateMembershipId(GrouperUuid.getUuid());
785     ms2.setImmediateMembershipId(GrouperUuid.getUuid());
786     ms3.setImmediateMembershipId(GrouperUuid.getUuid());
787     
788     Member member = MemberFinder.findBySubject(grouperSession, subjD, true);
789     ms1.setMemberUuid(member.getUuid());
790     ms2.setMemberUuid(member.getUuid());
791     ms3.setMemberUuid(member.getUuid());
792     
793     GrouperDAOFactory.getFactory().getMembership().save(ms1);
794     GrouperDAOFactory.getFactory().getMembership().save(ms2);
795     GrouperDAOFactory.getFactory().getMembership().save(ms3);
796     
797     ChangeLogTempToEntity.convertRecords();
798 
799     assertEquals(3, FindBadMemberships.checkAll());
800     String gsh = "import edu.internet2.middleware.grouper.*;\nimport edu.internet2.middleware.grouper.misc.*;\n" + FindBadMemberships.gshScript.toString();
801     new Interpreter(new StringReader(gsh), System.out, System.err, false).run();
802     assertEquals(0, FindBadMemberships.checkAll());
803     
804     // verify we don't mess up point in time
805     ChangeLogTempToEntity.convertRecords();
806     assertEquals(0, new edu.internet2.middleware.grouper.misc.SyncPITTables().showResults(false).syncAllPITTables());
807   }
808   
809   /**
810    * Test bad composites when composites have the wrong member, but the number of memberships
811    * is still the same.
812    * @throws Exception
813    */
814   public void testWithWrongComposite() throws Exception {
815     setUpComposites();
816     
817     Membership ms1 = MembershipFinder.findCompositeMembership(grouperSession, owner1, subjC, true);
818     Membership ms2 = MembershipFinder.findCompositeMembership(grouperSession, owner2, subjF, true);
819     Membership ms3 = MembershipFinder.findCompositeMembership(grouperSession, owner3, subjA, true);
820     
821     Member member = MemberFinder.findBySubject(grouperSession, subjD, true);
822     ms1.setMemberUuid(member.getUuid());
823     ms2.setMemberUuid(member.getUuid());
824     ms3.setMemberUuid(member.getUuid());
825     
826     GrouperDAOFactory.getFactory().getMembership().update(ms1);
827     GrouperDAOFactory.getFactory().getMembership().update(ms2);
828     GrouperDAOFactory.getFactory().getMembership().update(ms3);
829     
830     ChangeLogTempToEntity.convertRecords();
831     
832     assertEquals(6, FindBadMemberships.checkAll());
833     String gsh = "import edu.internet2.middleware.grouper.*;\nimport edu.internet2.middleware.grouper.misc.*;\n" + FindBadMemberships.gshScript.toString();
834     new Interpreter(new StringReader(gsh), System.out, System.err, false).run();
835     assertEquals(0, FindBadMemberships.checkAll());
836     
837     // verify we don't mess up point in time
838     ChangeLogTempToEntity.convertRecords();
839     assertEquals(0, new edu.internet2.middleware.grouper.misc.SyncPITTables().showResults(false).syncAllPITTables());
840   }
841   
842   /**
843    * Test bad composites when composites have the wrong type.
844    * @throws Exception
845    */
846   public void testWithWrongType() throws Exception {
847     setUpComposites();
848     
849     Membership ms1 = MembershipFinder.findCompositeMembership(grouperSession, owner1, subjC, true);
850     Membership ms2 = MembershipFinder.findCompositeMembership(grouperSession, owner2, subjF, true);
851     Membership ms3 = MembershipFinder.findCompositeMembership(grouperSession, owner3, subjA, true);
852     
853     ms1.setType(MembershipType.IMMEDIATE.getTypeString());
854     ms2.setType(MembershipType.IMMEDIATE.getTypeString());
855     ms3.setType(MembershipType.IMMEDIATE.getTypeString());
856     
857     ms1.setViaCompositeId(null);
858     ms2.setViaCompositeId(null);
859     ms3.setViaCompositeId(null);
860     
861     GrouperDAOFactory.getFactory().getMembership().update(ms1);
862     GrouperDAOFactory.getFactory().getMembership().update(ms2);
863     GrouperDAOFactory.getFactory().getMembership().update(ms3);
864     
865     ChangeLogTempToEntity.convertRecords();
866 
867     assertEquals(6, FindBadMemberships.checkAll());
868     String gsh = "import edu.internet2.middleware.grouper.*;\nimport edu.internet2.middleware.grouper.misc.*;\n" + FindBadMemberships.gshScript.toString();
869     new Interpreter(new StringReader(gsh), System.out, System.err, false).run();
870     assertEquals(0, FindBadMemberships.checkAll());
871     
872     // verify we don't mess up point in time
873     ChangeLogTempToEntity.convertRecords();
874     assertEquals(0, new edu.internet2.middleware.grouper.misc.SyncPITTables().showResults(false).syncAllPITTables());
875   }
876   
877   /**
878    * Test bad composites when composites have the wrong type.
879    * @throws Exception
880    */
881   public void testWithWrongType2() throws Exception {
882     setUpComposites();
883     
884     Membership ms1 = MembershipFinder.findImmediateMembership(grouperSession, subjEGroup, subjC, true);
885     
886     ms1.setType(MembershipType.COMPOSITE.getTypeString());
887     ms1.setViaCompositeId(owner1.getComposite(true).getUuid());
888     
889     GrouperDAOFactory.getFactory().getMembership().update(ms1);
890     
891     ChangeLogTempToEntity.convertRecords();
892 
893     assertEquals(1, FindBadMemberships.checkAll());
894     String gsh = "import edu.internet2.middleware.grouper.*;\nimport edu.internet2.middleware.grouper.misc.*;\n" + FindBadMemberships.gshScript.toString();
895     new Interpreter(new StringReader(gsh), System.out, System.err, false).run();
896     
897     // now we have 4 more bad memberships since we just deleted subjEGroup -> subjC
898     FindBadMemberships.clearResults();
899     assertEquals(4, FindBadMemberships.checkAll());
900     gsh = "import edu.internet2.middleware.grouper.*;\nimport edu.internet2.middleware.grouper.misc.*;\n" + FindBadMemberships.gshScript.toString();
901     new Interpreter(new StringReader(gsh), System.out, System.err, false).run();
902     assertEquals(0, FindBadMemberships.checkAll());
903 
904     // verify we don't mess up point in time
905     ChangeLogTempToEntity.convertRecords();
906     assertEquals(0, new edu.internet2.middleware.grouper.misc.SyncPITTables().showResults(false).syncAllPITTables());
907   }
908   
909   /**
910    * Test bad composites when composites have the wrong viaCompositeId.
911    * @throws Exception
912    */
913   public void testWithWrongViaCompositeId() throws Exception {
914     setUpComposites();
915     
916     Membership ms1 = MembershipFinder.findCompositeMembership(grouperSession, owner1, subjC, true);
917     
918     ms1.setViaCompositeId(owner2.getComposite(true).getUuid());
919     
920     GrouperDAOFactory.getFactory().getMembership().update(ms1);
921     
922     ChangeLogTempToEntity.convertRecords();
923 
924     assertEquals(1, FindBadMemberships.checkAll());
925     String gsh = "import edu.internet2.middleware.grouper.*;\nimport edu.internet2.middleware.grouper.misc.*;\n" + FindBadMemberships.gshScript.toString();
926     new Interpreter(new StringReader(gsh), System.out, System.err, false).run();
927     
928     // now we have 1 more bad membership since we just deleted owner1 -> subjC
929     FindBadMemberships.clearResults();
930     assertEquals(1, FindBadMemberships.checkAll());
931     gsh = "import edu.internet2.middleware.grouper.*;\nimport edu.internet2.middleware.grouper.misc.*;\n" + FindBadMemberships.gshScript.toString();
932     new Interpreter(new StringReader(gsh), System.out, System.err, false).run();
933     assertEquals(0, FindBadMemberships.checkAll());
934 
935     // verify we don't mess up point in time
936     ChangeLogTempToEntity.convertRecords();
937     assertEquals(0, new edu.internet2.middleware.grouper.misc.SyncPITTables().showResults(false).syncAllPITTables());
938   }
939   
940   /**
941    * Test group sets using default field and depth=0 that have the wrong type
942    * @throws Exception
943    */
944   public void testWithWrongGroupSetType() throws Exception {
945     setUpComposites();
946     
947     GroupSet gs1 = GrouperDAOFactory.getFactory().getGroupSet().findSelfGroup(owner1.getId(), Group.getDefaultList().getUuid());
948     GroupSet gs2 = GrouperDAOFactory.getFactory().getGroupSet().findSelfGroup(owner2.getId(), Group.getDefaultList().getUuid());
949     GroupSet gs3 = GrouperDAOFactory.getFactory().getGroupSet().findSelfGroup(owner3.getId(), Group.getDefaultList().getUuid());
950     GroupSet gs4 = GrouperDAOFactory.getFactory().getGroupSet().findSelfGroup(subjEGroup.getId(), Group.getDefaultList().getUuid());
951     
952     gs1.setType("immediate");
953     gs2.setType("immediate");
954     gs3.setType("immediate");
955     gs4.setType("composite");
956     
957     GrouperDAOFactory.getFactory().getGroupSet().update(gs1);
958     GrouperDAOFactory.getFactory().getGroupSet().update(gs2);
959     GrouperDAOFactory.getFactory().getGroupSet().update(gs3);
960     GrouperDAOFactory.getFactory().getGroupSet().update(gs4);
961     
962     ChangeLogTempToEntity.convertRecords();
963 
964     assertEquals(4, FindBadMemberships.checkAll());
965     String gsh = "importCommands(\"edu.internet2.middleware.grouper.app.gsh\");\nimport edu.internet2.middleware.grouper.*;\nimport edu.internet2.middleware.grouper.misc.*;\n" + FindBadMemberships.gshScript.toString();
966     new Interpreter(new StringReader(gsh), System.out, System.err, false).run();
967     assertEquals(0, FindBadMemberships.checkAll());
968     
969     // verify we don't mess up point in time
970     ChangeLogTempToEntity.convertRecords();
971     assertEquals(0, new edu.internet2.middleware.grouper.misc.SyncPITTables().showResults(false).syncAllPITTables());
972   }
973 
974   /**
975    * Test scenario where a composite group has group sets
976    * @throws Exception
977    */
978   public void testWithBadGroupSetsForComposites() throws Exception {
979     setUpComposites();
980     
981     Group g1 = top.addChildGroup("g1", "g1");
982     Group g2 = top.addChildGroup("g2", "g2");
983     Group g3 = top.addChildGroup("g3", "g3");
984     Group g4 = top.addChildGroup("g4", "g4");
985     g1.addMember(g2.toSubject());
986     g2.addMember(owner2.toSubject());
987     g3.addMember(g4.toSubject());
988     owner1.grantPriv(g3.toSubject(), AccessPrivilege.READ); // group sets created by this are good..
989     
990     ChangeLogTempToEntity.convertRecords();
991 
992     int groupSetCount = HibernateSession.bySqlStatic().select(int.class, "select count(1) from grouper_group_set");
993     int pitGroupSetCountTotal = HibernateSession.bySqlStatic().select(int.class, "select count(1) from grouper_pit_group_set");
994     int pitGroupSetCountActive = HibernateSession.bySqlStatic().select(int.class, "select count(1) from grouper_pit_group_set where active='T'");
995     
996     // add groupSet owner2 -> g3
997     GroupSet gs1 = new GroupSet();
998     gs1.setId(GrouperUuid.getUuid());
999     gs1.setCreatorId(GrouperSession.staticGrouperSession().getMemberUuid());
1000     gs1.setDepth(1);
1001     gs1.setFieldId(Group.getDefaultList().getUuid());
1002     gs1.setMemberGroupId(g3.getUuid());
1003     gs1.setType(MembershipType.EFFECTIVE.getTypeString());
1004     gs1.setOwnerGroupId(owner2.getUuid());
1005     gs1.setParentId(GrouperDAOFactory.getFactory().getGroupSet().findSelfGroup(owner2.getUuid(), Group.getDefaultList().getUuid()).getId());
1006     GrouperDAOFactory.getFactory().getGroupSet().save(gs1);
1007     
1008     // add to pit
1009     ChangeLogTempToEntity.convertRecords();
1010     
1011     int newGroupSetCount = HibernateSession.bySqlStatic().select(int.class, "select count(1) from grouper_group_set");
1012     int newPitGroupSetCountTotal = HibernateSession.bySqlStatic().select(int.class, "select count(1) from grouper_pit_group_set");
1013     int newPitGroupSetCountActive = HibernateSession.bySqlStatic().select(int.class, "select count(1) from grouper_pit_group_set where active='T'");
1014     
1015     assertEquals(groupSetCount + 6, newGroupSetCount);
1016     assertEquals(pitGroupSetCountTotal + 6, newPitGroupSetCountTotal);
1017     assertEquals(pitGroupSetCountActive + 6, newPitGroupSetCountActive);
1018         
1019     assertEquals(1, FindBadMemberships.checkAll());
1020     String gsh = "import edu.internet2.middleware.grouper.*;\nimport edu.internet2.middleware.grouper.misc.*;\n" + FindBadMemberships.gshScript.toString();
1021     new Interpreter(new StringReader(gsh), System.out, System.err, false).run();
1022     assertEquals(0, FindBadMemberships.checkAll());
1023     
1024     // verify we don't mess up point in time
1025     ChangeLogTempToEntity.convertRecords();
1026     assertEquals(0, new edu.internet2.middleware.grouper.misc.SyncPITTables().showResults(false).syncAllPITTables());
1027     
1028     // check counts again..
1029     newGroupSetCount = HibernateSession.bySqlStatic().select(int.class, "select count(1) from grouper_group_set");
1030     newPitGroupSetCountTotal = HibernateSession.bySqlStatic().select(int.class, "select count(1) from grouper_pit_group_set");
1031     newPitGroupSetCountActive = HibernateSession.bySqlStatic().select(int.class, "select count(1) from grouper_pit_group_set where active='T'");
1032     
1033     assertEquals(groupSetCount, newGroupSetCount);
1034     assertEquals(pitGroupSetCountTotal + 6, newPitGroupSetCountTotal);
1035     assertEquals(pitGroupSetCountActive, newPitGroupSetCountActive);
1036   }
1037   
1038   /**
1039    * @throws Exception 
1040    */
1041   public void testWithIncompleteGroupSetHierarchyAttrDefPrivs() throws Exception { 
1042     setUpComposites();
1043     
1044     Group g1 = top.addChildGroup("g1", "g1");
1045     Group g2 = top.addChildGroup("g2", "g2");
1046     Group g3 = top.addChildGroup("g3", "g3");
1047     Group g4 = top.addChildGroup("g4", "g4");
1048     Group g5 = top.addChildGroup("g5", "g5");
1049     Group g6 = top.addChildGroup("g6", "g6");
1050     
1051     Group g2b = top.addChildGroup("g2b", "g2b");
1052     Stem s2 = top.addChildStem("s2", "s2");
1053     AttributeDef a2 = top.addChildAttributeDef("a2", AttributeDefType.attr);
1054     
1055     // add some members...
1056     g1.addMember(SubjectTestHelper.SUBJ0);
1057     g2.addMember(SubjectTestHelper.SUBJ1);
1058     g3.addMember(SubjectTestHelper.SUBJ2);
1059     g4.addMember(SubjectTestHelper.SUBJ3);
1060     g5.addMember(SubjectTestHelper.SUBJ4);
1061     g6.addMember(SubjectTestHelper.SUBJ5);
1062     
1063     // add group sets now
1064     g1.addMember(g2.toSubject());
1065     g2.addMember(g3.toSubject());
1066     g3.addMember(g4.toSubject());
1067     g4.addMember(g5.toSubject());
1068     g5.addMember(g6.toSubject());
1069     g2b.grantPriv(g3.toSubject(), AccessPrivilege.ADMIN);
1070     s2.grantPriv(g3.toSubject(), NamingPrivilege.STEM);
1071     a2.getPrivilegeDelegate().grantPriv(g3.toSubject(), AttributeDefPrivilege.ATTR_READ, true);
1072     
1073     int groupSetCount = HibernateSession.bySqlStatic().select(int.class, "select count(1) from grouper_group_set");
1074     
1075     // let's delete group sets (assume race condition between g2 -> g3 (attr def priv) and g3 -> g4)
1076     GrouperDAOFactory.getFactory().getGroupSet().findAllByOwnerAndMemberAndField(a2.getUuid(), g6.getUuid(), FieldFinder.find("attrReaders", true).getUuid()).iterator().next().delete(false);
1077     GrouperDAOFactory.getFactory().getGroupSet().findAllByOwnerAndMemberAndField(a2.getUuid(), g5.getUuid(), FieldFinder.find("attrReaders", true).getUuid()).iterator().next().delete(false);
1078     GrouperDAOFactory.getFactory().getGroupSet().findAllByOwnerAndMemberAndField(a2.getUuid(), g4.getUuid(), FieldFinder.find("attrReaders", true).getUuid()).iterator().next().delete(false);
1079 
1080     // add to point in time
1081     ChangeLogTempToEntity.convertRecords();
1082 
1083     assertEquals(1, FindBadMemberships.checkAll());
1084     String gsh = "importCommands(\"edu.internet2.middleware.grouper.app.gsh\");\nimport edu.internet2.middleware.grouper.*;\nimport edu.internet2.middleware.grouper.misc.*;\n" + FindBadMemberships.gshScript.toString();
1085     new Interpreter(new StringReader(gsh), System.out, System.err, false).run();
1086     assertEquals(0, FindBadMemberships.checkAll());
1087     
1088     // verify we don't mess up point in time
1089     ChangeLogTempToEntity.convertRecords();
1090     assertEquals(0, new edu.internet2.middleware.grouper.misc.SyncPITTables().showResults(false).syncAllPITTables());
1091     
1092     // verify counts
1093     int newGroupSetCount = HibernateSession.bySqlStatic().select(int.class, "select count(1) from grouper_group_set");
1094     int newPitGroupSetCountActive = HibernateSession.bySqlStatic().select(int.class, "select count(1) from grouper_pit_group_set where active='T'");
1095     assertEquals(groupSetCount, newGroupSetCount);
1096     assertEquals(groupSetCount, newPitGroupSetCountActive);
1097   }
1098   
1099   /**
1100    * @throws Exception 
1101    */
1102   public void testWithIncompleteGroupSetHierarchyStemPrivs() throws Exception { 
1103     setUpComposites();
1104     
1105     Group g1 = top.addChildGroup("g1", "g1");
1106     Group g2 = top.addChildGroup("g2", "g2");
1107     Group g3 = top.addChildGroup("g3", "g3");
1108     Group g4 = top.addChildGroup("g4", "g4");
1109     Group g5 = top.addChildGroup("g5", "g5");
1110     Group g6 = top.addChildGroup("g6", "g6");
1111     
1112     Group g2b = top.addChildGroup("g2b", "g2b");
1113     Stem s2 = top.addChildStem("s2", "s2");
1114     AttributeDef a2 = top.addChildAttributeDef("a2", AttributeDefType.attr);
1115     
1116     // add some members...
1117     g1.addMember(SubjectTestHelper.SUBJ0);
1118     g2.addMember(SubjectTestHelper.SUBJ1);
1119     g3.addMember(SubjectTestHelper.SUBJ2);
1120     g4.addMember(SubjectTestHelper.SUBJ3);
1121     g5.addMember(SubjectTestHelper.SUBJ4);
1122     g6.addMember(SubjectTestHelper.SUBJ5);
1123     
1124     // add group sets now
1125     g1.addMember(g2.toSubject());
1126     g2.addMember(g3.toSubject());
1127     g3.addMember(g4.toSubject());
1128     g4.addMember(g5.toSubject());
1129     g5.addMember(g6.toSubject());
1130     g2b.grantPriv(g3.toSubject(), AccessPrivilege.ADMIN);
1131     s2.grantPriv(g3.toSubject(), NamingPrivilege.STEM);
1132     a2.getPrivilegeDelegate().grantPriv(g3.toSubject(), AttributeDefPrivilege.ATTR_READ, true);
1133     
1134     int groupSetCount = HibernateSession.bySqlStatic().select(int.class, "select count(1) from grouper_group_set");
1135     
1136     // let's delete group sets (assume race condition between g2 -> g3 (stem priv) and g4 -> g5)
1137     GrouperDAOFactory.getFactory().getGroupSet().findAllByOwnerAndMemberAndField(s2.getUuid(), g6.getUuid(), FieldFinder.find("stemmers", true).getUuid()).iterator().next().delete(false);
1138     GrouperDAOFactory.getFactory().getGroupSet().findAllByOwnerAndMemberAndField(s2.getUuid(), g5.getUuid(), FieldFinder.find("stemmers", true).getUuid()).iterator().next().delete(false);
1139     
1140     // add to point in time
1141     ChangeLogTempToEntity.convertRecords();
1142 
1143     assertEquals(1, FindBadMemberships.checkAll());
1144     String gsh = "importCommands(\"edu.internet2.middleware.grouper.app.gsh\");\nimport edu.internet2.middleware.grouper.*;\nimport edu.internet2.middleware.grouper.misc.*;\n" + FindBadMemberships.gshScript.toString();
1145     new Interpreter(new StringReader(gsh), System.out, System.err, false).run();
1146     assertEquals(0, FindBadMemberships.checkAll());
1147     
1148     // verify we don't mess up point in time
1149     ChangeLogTempToEntity.convertRecords();
1150     assertEquals(0, new edu.internet2.middleware.grouper.misc.SyncPITTables().showResults(false).syncAllPITTables());
1151     
1152     // verify counts
1153     int newGroupSetCount = HibernateSession.bySqlStatic().select(int.class, "select count(1) from grouper_group_set");
1154     int newPitGroupSetCountActive = HibernateSession.bySqlStatic().select(int.class, "select count(1) from grouper_pit_group_set where active='T'");
1155     assertEquals(groupSetCount, newGroupSetCount);
1156     assertEquals(groupSetCount, newPitGroupSetCountActive);
1157   }
1158   
1159   /**
1160    * @throws Exception 
1161    */
1162   public void testWithIncompleteGroupSetHierarchyGroupMembers() throws Exception { 
1163     setUpComposites();
1164     
1165     Group g1 = top.addChildGroup("g1", "g1");
1166     Group g2 = top.addChildGroup("g2", "g2");
1167     Group g3 = top.addChildGroup("g3", "g3");
1168     Group g4 = top.addChildGroup("g4", "g4");
1169     Group g5 = top.addChildGroup("g5", "g5");
1170     Group g6 = top.addChildGroup("g6", "g6");
1171     
1172     Group g2b = top.addChildGroup("g2b", "g2b");
1173     Stem s2 = top.addChildStem("s2", "s2");
1174     AttributeDef a2 = top.addChildAttributeDef("a2", AttributeDefType.attr);
1175     
1176     // add some members...
1177     g1.addMember(SubjectTestHelper.SUBJ0);
1178     g2.addMember(SubjectTestHelper.SUBJ1);
1179     g3.addMember(SubjectTestHelper.SUBJ2);
1180     g4.addMember(SubjectTestHelper.SUBJ3);
1181     g5.addMember(SubjectTestHelper.SUBJ4);
1182     g6.addMember(SubjectTestHelper.SUBJ5);
1183     
1184     // add group sets now
1185     g1.addMember(g2.toSubject());
1186     g2.addMember(g3.toSubject());
1187     g3.addMember(g4.toSubject());
1188     g4.addMember(g5.toSubject());
1189     g5.addMember(g6.toSubject());
1190     g2b.grantPriv(g3.toSubject(), AccessPrivilege.ADMIN);
1191     s2.grantPriv(g3.toSubject(), NamingPrivilege.STEM);
1192     a2.getPrivilegeDelegate().grantPriv(g3.toSubject(), AttributeDefPrivilege.ATTR_READ, true);
1193     
1194     int groupSetCount = HibernateSession.bySqlStatic().select(int.class, "select count(1) from grouper_group_set");
1195     
1196     // let's delete group sets (assume race condition between g2 -> g3 and g4 -> g5)
1197     GrouperDAOFactory.getFactory().getGroupSet().findAllByOwnerAndMemberAndField(g2.getUuid(), g6.getUuid(), FieldFinder.find("members", true).getUuid()).iterator().next().delete(false);
1198     GrouperDAOFactory.getFactory().getGroupSet().findAllByOwnerAndMemberAndField(g2.getUuid(), g5.getUuid(), FieldFinder.find("members", true).getUuid()).iterator().next().delete(false);
1199     GrouperDAOFactory.getFactory().getGroupSet().findAllByOwnerAndMemberAndField(g1.getUuid(), g6.getUuid(), FieldFinder.find("members", true).getUuid()).iterator().next().delete(false);
1200     GrouperDAOFactory.getFactory().getGroupSet().findAllByOwnerAndMemberAndField(g1.getUuid(), g5.getUuid(), FieldFinder.find("members", true).getUuid()).iterator().next().delete(false);
1201     
1202     // add to point in time
1203     ChangeLogTempToEntity.convertRecords();
1204 
1205     assertEquals(1, FindBadMemberships.checkAll());
1206     String gsh = "importCommands(\"edu.internet2.middleware.grouper.app.gsh\");\nimport edu.internet2.middleware.grouper.*;\nimport edu.internet2.middleware.grouper.misc.*;\n" + FindBadMemberships.gshScript.toString();
1207     new Interpreter(new StringReader(gsh), System.out, System.err, false).run();
1208     assertEquals(0, FindBadMemberships.checkAll());
1209     
1210     // verify we don't mess up point in time
1211     ChangeLogTempToEntity.convertRecords();
1212     assertEquals(0, new edu.internet2.middleware.grouper.misc.SyncPITTables().showResults(false).syncAllPITTables());
1213     
1214     // verify counts
1215     int newGroupSetCount = HibernateSession.bySqlStatic().select(int.class, "select count(1) from grouper_group_set");
1216     int newPitGroupSetCountActive = HibernateSession.bySqlStatic().select(int.class, "select count(1) from grouper_pit_group_set where active='T'");
1217     assertEquals(groupSetCount, newGroupSetCount);
1218     assertEquals(groupSetCount, newPitGroupSetCountActive);
1219   }
1220   
1221   /**
1222    * @throws Exception 
1223    */
1224   public void testWithIncompleteGroupSetHierarchyGroupPrivs() throws Exception { 
1225     setUpComposites();
1226     
1227     Group g1 = top.addChildGroup("g1", "g1");
1228     Group g2 = top.addChildGroup("g2", "g2");
1229     Group g3 = top.addChildGroup("g3", "g3");
1230     Group g4 = top.addChildGroup("g4", "g4");
1231     Group g5 = top.addChildGroup("g5", "g5");
1232     Group g6 = top.addChildGroup("g6", "g6");
1233     
1234     Group g2b = top.addChildGroup("g2b", "g2b");
1235     Stem s2 = top.addChildStem("s2", "s2");
1236     AttributeDef a2 = top.addChildAttributeDef("a2", AttributeDefType.attr);
1237     
1238     // add some members...
1239     g1.addMember(SubjectTestHelper.SUBJ0);
1240     g2.addMember(SubjectTestHelper.SUBJ1);
1241     g3.addMember(SubjectTestHelper.SUBJ2);
1242     g4.addMember(SubjectTestHelper.SUBJ3);
1243     g5.addMember(SubjectTestHelper.SUBJ4);
1244     g6.addMember(SubjectTestHelper.SUBJ5);
1245     
1246     // add group sets now
1247     g1.addMember(g2.toSubject());
1248     g2.addMember(g3.toSubject());
1249     g3.addMember(g4.toSubject());
1250     g4.addMember(g5.toSubject());
1251     g5.addMember(g6.toSubject());
1252     g2b.grantPriv(g3.toSubject(), AccessPrivilege.ADMIN);
1253     s2.grantPriv(g3.toSubject(), NamingPrivilege.STEM);
1254     a2.getPrivilegeDelegate().grantPriv(g3.toSubject(), AttributeDefPrivilege.ATTR_READ, true);
1255     
1256     int groupSetCount = HibernateSession.bySqlStatic().select(int.class, "select count(1) from grouper_group_set");
1257     
1258     // let's delete group sets (assume race condition between g2 -> g3 (group priv) and g4 -> g5)
1259     GrouperDAOFactory.getFactory().getGroupSet().findAllByOwnerAndMemberAndField(g2b.getUuid(), g6.getUuid(), FieldFinder.find("admins", true).getUuid()).iterator().next().delete(false);
1260     GrouperDAOFactory.getFactory().getGroupSet().findAllByOwnerAndMemberAndField(g2b.getUuid(), g5.getUuid(), FieldFinder.find("admins", true).getUuid()).iterator().next().delete(false);
1261     
1262     // add to point in time
1263     ChangeLogTempToEntity.convertRecords();
1264 
1265     assertEquals(1, FindBadMemberships.checkAll());
1266     String gsh = "importCommands(\"edu.internet2.middleware.grouper.app.gsh\");\nimport edu.internet2.middleware.grouper.*;\nimport edu.internet2.middleware.grouper.misc.*;\n" + FindBadMemberships.gshScript.toString();
1267     new Interpreter(new StringReader(gsh), System.out, System.err, false).run();
1268     assertEquals(0, FindBadMemberships.checkAll());
1269     
1270     // verify we don't mess up point in time
1271     ChangeLogTempToEntity.convertRecords();
1272     assertEquals(0, new edu.internet2.middleware.grouper.misc.SyncPITTables().showResults(false).syncAllPITTables());
1273     
1274     // verify counts
1275     int newGroupSetCount = HibernateSession.bySqlStatic().select(int.class, "select count(1) from grouper_group_set");
1276     int newPitGroupSetCountActive = HibernateSession.bySqlStatic().select(int.class, "select count(1) from grouper_pit_group_set where active='T'");
1277     assertEquals(groupSetCount, newGroupSetCount);
1278     assertEquals(groupSetCount, newPitGroupSetCountActive);
1279   }
1280   
1281   /**
1282    * @throws Exception 
1283    */
1284   public void testWithIncompleteGroupSetHierarchyAllTypes() throws Exception { 
1285     setUpComposites();
1286     
1287     Group g1 = top.addChildGroup("g1", "g1");
1288     Group g2 = top.addChildGroup("g2", "g2");
1289     Group g3 = top.addChildGroup("g3", "g3");
1290     Group g4 = top.addChildGroup("g4", "g4");
1291     Group g5 = top.addChildGroup("g5", "g5");
1292     Group g6 = top.addChildGroup("g6", "g6");
1293     
1294     Group g2b = top.addChildGroup("g2b", "g2b");
1295     Stem s2 = top.addChildStem("s2", "s2");
1296     AttributeDef a2 = top.addChildAttributeDef("a2", AttributeDefType.attr);
1297     
1298     // add some members...
1299     g1.addMember(SubjectTestHelper.SUBJ0);
1300     g2.addMember(SubjectTestHelper.SUBJ1);
1301     g3.addMember(SubjectTestHelper.SUBJ2);
1302     g4.addMember(SubjectTestHelper.SUBJ3);
1303     g5.addMember(SubjectTestHelper.SUBJ4);
1304     g6.addMember(SubjectTestHelper.SUBJ5);
1305     
1306     // add group sets now
1307     g1.addMember(g2.toSubject());
1308     g2.addMember(g3.toSubject());
1309     g3.addMember(g4.toSubject());
1310     g4.addMember(g5.toSubject());
1311     g5.addMember(g6.toSubject());
1312     g2b.grantPriv(g3.toSubject(), AccessPrivilege.ADMIN);
1313     s2.grantPriv(g3.toSubject(), NamingPrivilege.STEM);
1314     a2.getPrivilegeDelegate().grantPriv(g3.toSubject(), AttributeDefPrivilege.ATTR_READ, true);
1315     
1316     int groupSetCount = HibernateSession.bySqlStatic().select(int.class, "select count(1) from grouper_group_set");
1317     
1318     // let's delete group sets
1319     GrouperDAOFactory.getFactory().getGroupSet().findAllByOwnerAndMemberAndField(s2.getUuid(), g6.getUuid(), FieldFinder.find("stemmers", true).getUuid()).iterator().next().delete(false);
1320     GrouperDAOFactory.getFactory().getGroupSet().findAllByOwnerAndMemberAndField(s2.getUuid(), g5.getUuid(), FieldFinder.find("stemmers", true).getUuid()).iterator().next().delete(false);
1321     GrouperDAOFactory.getFactory().getGroupSet().findAllByOwnerAndMemberAndField(a2.getUuid(), g6.getUuid(), FieldFinder.find("attrReaders", true).getUuid()).iterator().next().delete(false);
1322     GrouperDAOFactory.getFactory().getGroupSet().findAllByOwnerAndMemberAndField(a2.getUuid(), g5.getUuid(), FieldFinder.find("attrReaders", true).getUuid()).iterator().next().delete(false);
1323     GrouperDAOFactory.getFactory().getGroupSet().findAllByOwnerAndMemberAndField(a2.getUuid(), g4.getUuid(), FieldFinder.find("attrReaders", true).getUuid()).iterator().next().delete(false);
1324     GrouperDAOFactory.getFactory().getGroupSet().findAllByOwnerAndMemberAndField(g2b.getUuid(), g6.getUuid(), FieldFinder.find("admins", true).getUuid()).iterator().next().delete(false);
1325     GrouperDAOFactory.getFactory().getGroupSet().findAllByOwnerAndMemberAndField(g2b.getUuid(), g5.getUuid(), FieldFinder.find("admins", true).getUuid()).iterator().next().delete(false);
1326     GrouperDAOFactory.getFactory().getGroupSet().findAllByOwnerAndMemberAndField(g2.getUuid(), g6.getUuid(), FieldFinder.find("members", true).getUuid()).iterator().next().delete(false);
1327     GrouperDAOFactory.getFactory().getGroupSet().findAllByOwnerAndMemberAndField(g2.getUuid(), g5.getUuid(), FieldFinder.find("members", true).getUuid()).iterator().next().delete(false);
1328     GrouperDAOFactory.getFactory().getGroupSet().findAllByOwnerAndMemberAndField(g1.getUuid(), g6.getUuid(), FieldFinder.find("members", true).getUuid()).iterator().next().delete(false);
1329     GrouperDAOFactory.getFactory().getGroupSet().findAllByOwnerAndMemberAndField(g1.getUuid(), g5.getUuid(), FieldFinder.find("members", true).getUuid()).iterator().next().delete(false);
1330     
1331     // add to point in time
1332     ChangeLogTempToEntity.convertRecords();
1333 
1334     // should have issues for g3 -> g4 and g4 -> g5
1335     assertEquals(2, FindBadMemberships.checkAll());
1336     String gsh = "importCommands(\"edu.internet2.middleware.grouper.app.gsh\");\nimport edu.internet2.middleware.grouper.*;\nimport edu.internet2.middleware.grouper.misc.*;\n" + FindBadMemberships.gshScript.toString();
1337     new Interpreter(new StringReader(gsh), System.out, System.err, false).run();
1338     assertEquals(0, FindBadMemberships.checkAll());
1339     
1340     // verify we don't mess up point in time
1341     ChangeLogTempToEntity.convertRecords();
1342     assertEquals(0, new edu.internet2.middleware.grouper.misc.SyncPITTables().showResults(false).syncAllPITTables());
1343     
1344     // verify counts
1345     int newGroupSetCount = HibernateSession.bySqlStatic().select(int.class, "select count(1) from grouper_group_set");
1346     int newPitGroupSetCountActive = HibernateSession.bySqlStatic().select(int.class, "select count(1) from grouper_pit_group_set where active='T'");
1347     assertEquals(groupSetCount, newGroupSetCount);
1348     assertEquals(groupSetCount, newPitGroupSetCountActive);
1349   }
1350   
1351   /**
1352    * @throws Exception
1353    */
1354   public void testDeletedGroupAsMember() throws Exception {
1355     grouperSession = SessionHelper.getRootSession();
1356     Stem root = StemFinder.findRootStem(grouperSession);
1357     top = root.addChildStem("top", "top");
1358     
1359     // we will delete g2 but leave membership from g1 -> g2.
1360     Group g1 = top.addChildGroup("g1", "g1");
1361     Group g2 = top.addChildGroup("g2", "g2");
1362     g1.addMember(g2.toSubject());
1363     
1364     Membership membership = MembershipFinder.findImmediateMembership(grouperSession, g1, g2.toSubject(), true);
1365 
1366     ChangeLogTempToEntity.convertRecords();
1367     g2.delete();
1368     ChangeLogTempToEntity.convertRecords();
1369 
1370     int originalMembershipCount = HibernateSession.bySqlStatic().select(int.class, "select count(1) from grouper_memberships");
1371 
1372     // save bad membership -- we need to disable the membership first or the save will try to add group sets
1373     membership.setHibernateVersionNumber(-1L);
1374     membership.setEnabled(false);
1375     membership.setDisabledTime(new Timestamp(new Date().getTime() - 10000));
1376     GrouperDAOFactory.getFactory().getMembership().save(membership);
1377 
1378     // now make the membership active again (just so we can test the pit sync as well)
1379     HibernateSession.bySqlStatic().executeSql("update grouper_memberships set enabled='T', disabled_timestamp=null where id='" + membership.getImmediateMembershipId() + "'");
1380     
1381     // update bad pit membership
1382     PITMembership pitMembership = GrouperDAOFactory.getFactory().getPITMembership().findBySourceIdUnique(membership.getImmediateMembershipId(), true);
1383     pitMembership.setActiveDb("T");
1384     pitMembership.setEndTimeDb(null);
1385     pitMembership.update();
1386     
1387     int newMembershipCount = HibernateSession.bySqlStatic().select(int.class, "select count(1) from grouper_memberships");
1388     assertEquals(originalMembershipCount + 1, newMembershipCount);
1389     
1390     assertEquals(1, FindBadMemberships.checkAll());
1391     String gsh = "importCommands(\"edu.internet2.middleware.grouper.app.gsh\");\nimport edu.internet2.middleware.grouper.*;\nimport edu.internet2.middleware.grouper.misc.*;\n" + FindBadMemberships.gshScript.toString();
1392     new Interpreter(new StringReader(gsh), System.out, System.err, false).run();
1393     assertEquals(0, FindBadMemberships.checkAll());
1394     
1395     newMembershipCount = HibernateSession.bySqlStatic().select(int.class, "select count(1) from grouper_memberships");
1396     assertEquals(originalMembershipCount, newMembershipCount);
1397  
1398     // pit sync should work
1399     assertEquals(1, new edu.internet2.middleware.grouper.misc.SyncPITTables().showResults(false).syncAllPITTables());
1400     ChangeLogTempToEntity.convertRecords();
1401     assertEquals(0, new edu.internet2.middleware.grouper.misc.SyncPITTables().showResults(false).syncAllPITTables());
1402     
1403     pitMembership = GrouperDAOFactory.getFactory().getPITMembership().findBySourceIdUnique(membership.getImmediateMembershipId(), true);
1404     assertEquals("F", pitMembership.getActiveDb());
1405     assertNotNull(pitMembership.getEndTimeDb());
1406     
1407     // should be able to delete g1
1408     grouperSession = SessionHelper.getRootSession();
1409     g1.delete();
1410     ChangeLogTempToEntity.convertRecords();
1411   }
1412   
1413   /**
1414    * The difference here is that we're expecting that deleting the group will do the right thing 
1415    * (instead of running bad membership finder).
1416    * @throws Exception
1417    */
1418   public void testDeletedGroupAsMember2() throws Exception {
1419     grouperSession = SessionHelper.getRootSession();
1420     Stem root = StemFinder.findRootStem(grouperSession);
1421     top = root.addChildStem("top", "top");
1422     
1423     // we will delete g2 but leave membership from g1 -> g2.
1424     Group g1 = top.addChildGroup("g1", "g1");
1425     Group g2 = top.addChildGroup("g2", "g2");
1426     Subject g2Subject = g2.toSubject();
1427     g1.addMember(g2Subject);
1428     
1429     g1.revokePriv(AccessPrivilege.READ);
1430     g1.revokePriv(AccessPrivilege.VIEW);
1431     g1.revokePriv(AccessPrivilege.ADMIN);
1432     
1433     Membership membership = MembershipFinder.findImmediateMembership(grouperSession, g1, g2.toSubject(), true);
1434 
1435     ChangeLogTempToEntity.convertRecords();
1436     g2.delete();
1437     ChangeLogTempToEntity.convertRecords();
1438 
1439     int originalMembershipCount = HibernateSession.bySqlStatic().select(int.class, "select count(1) from grouper_memberships");
1440 
1441     // save bad membership -- we need to disable the membership first or the save will try to add group sets
1442     membership.setHibernateVersionNumber(-1L);
1443     membership.setEnabled(false);
1444     membership.setDisabledTime(new Timestamp(new Date().getTime() - 10000));
1445     GrouperDAOFactory.getFactory().getMembership().save(membership);
1446 
1447     // now make the membership active again (just so we can test the pit as well)
1448     HibernateSession.bySqlStatic().executeSql("update grouper_memberships set enabled='T', disabled_timestamp=null where id='" + membership.getImmediateMembershipId() + "'");
1449     
1450     // update bad pit membership
1451     PITMembership pitMembership = GrouperDAOFactory.getFactory().getPITMembership().findBySourceIdUnique(membership.getImmediateMembershipId(), true);
1452     pitMembership.setActiveDb("T");
1453     pitMembership.setEndTimeDb(null);
1454     pitMembership.update();
1455     
1456     int newMembershipCount = HibernateSession.bySqlStatic().select(int.class, "select count(1) from grouper_memberships");
1457     assertEquals(originalMembershipCount + 1, newMembershipCount);
1458 
1459     g1.delete();
1460 
1461     newMembershipCount = HibernateSession.bySqlStatic().select(int.class, "select count(1) from grouper_memberships");
1462     assertEquals(originalMembershipCount, newMembershipCount);
1463  
1464     // change log should work
1465     ChangeLogTempToEntity.convertRecords();
1466 
1467     // pit sync should work
1468     assertEquals(0, new edu.internet2.middleware.grouper.misc.SyncPITTables().showResults(false).syncAllPITTables());
1469     
1470     pitMembership = GrouperDAOFactory.getFactory().getPITMembership().findBySourceIdUnique(membership.getImmediateMembershipId(), true);
1471     assertEquals("F", pitMembership.getActiveDb());
1472     assertNotNull(pitMembership.getEndTimeDb());
1473   }
1474 }
1475