Path: blob/master/test/jdk/javax/security/auth/Subject/SubjectNullTests.java
41154 views
/*1* Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*/2223/*24* @test25* @bug 801508126* @modules java.management27* java.security.jgss28* @compile Subject.java29* @compile SubjectNullTests.java30* @build SubjectNullTests31* @run main SubjectNullTests32* @summary javax.security.auth.Subject.toString() throws NPE33*/3435import java.io.File;36import java.io.ByteArrayInputStream;37import java.io.FileInputStream;38import java.io.ObjectInputStream;39import java.io.IOException;40import java.security.Principal;41import java.util.Arrays;42import java.util.Collection;43import java.util.HashSet;44import java.util.LinkedList;45import java.util.List;46import java.util.Set;47import javax.management.remote.JMXPrincipal;48import javax.security.auth.Subject;49import javax.security.auth.x500.X500Principal;50import javax.security.auth.kerberos.KerberosPrincipal;5152public class SubjectNullTests {5354// Value templates for the constructor55private static Principal[] princVals = {56new X500Principal("CN=Tom Sawyer, ST=Missouri, C=US"),57new JMXPrincipal("Huckleberry Finn"),58new KerberosPrincipal("mtwain/[email protected]")59};60private static String[] pubVals = {"tsawyer", "hfinn", "mtwain"};61private static String[] privVals = {"th3R!v3r", "oNth3R4ft", "5Cl3M3nz"};6263// Templates for collection-based modifiers for the Subject64private static Principal[] tmplAddPrincs = {65new X500Principal("CN=John Doe, O=Bogus Corp."),66new KerberosPrincipal("jdoe/[email protected]")67};68private static String[] tmplAddPubVals = {"jdoe", "djoe"};69private static String[] tmplAddPrvVals = {"b4dpa55w0rd", "pass123"};7071/**72* Byte arrays used for deserialization:73* These byte arrays contain serialized Subjects and SecureSets,74* either with or without nulls. These use75* jjjjj.security.auth.Subject, which is a modified Subject76* implementation that allows the addition of null elements77*/78private static final byte[] SUBJ_NO_NULL =79jjjjj.security.auth.Subject.enc(makeSubjWithNull(false));80private static final byte[] SUBJ_WITH_NULL =81jjjjj.security.auth.Subject.enc(makeSubjWithNull(true));82private static final byte[] PRIN_NO_NULL =83jjjjj.security.auth.Subject.enc(makeSecSetWithNull(false));84private static final byte[] PRIN_WITH_NULL =85jjjjj.security.auth.Subject.enc(makeSecSetWithNull(true));8687/**88* Method to allow creation of a subject that can optionally89* insert a null reference into the principals Set.90*/91private static jjjjj.security.auth.Subject makeSubjWithNull(92boolean nullPrinc) {93Set<Principal> setPrinc = new HashSet<>(Arrays.asList(princVals));94if (nullPrinc) {95setPrinc.add(null);96}9798return (new jjjjj.security.auth.Subject(setPrinc));99}100101/**102* Method to allow creation of a SecureSet that can optionally103* insert a null reference.104*/105private static Set<Principal> makeSecSetWithNull(boolean nullPrinc) {106Set<Principal> setPrinc = new HashSet<>(Arrays.asList(princVals));107if (nullPrinc) {108setPrinc.add(null);109}110111jjjjj.security.auth.Subject subj =112new jjjjj.security.auth.Subject(setPrinc);113114return subj.getPrincipals();115}116117/**118* Construct a subject, and optionally place a null in any one119* of the three Sets used to initialize a Subject's values120*/121private static Subject makeSubj(boolean nullPrinc, boolean nullPub,122boolean nullPriv) {123Set<Principal> setPrinc = new HashSet<>(Arrays.asList(princVals));124Set<String> setPubCreds = new HashSet<>(Arrays.asList(pubVals));125Set<String> setPrvCreds = new HashSet<>(Arrays.asList(privVals));126127if (nullPrinc) {128setPrinc.add(null);129}130131if (nullPub) {132setPubCreds.add(null);133}134135if (nullPriv) {136setPrvCreds.add(null);137}138139return (new Subject(false, setPrinc, setPubCreds, setPrvCreds));140}141142/**143* Provide a simple interface for abstracting collection-on-collection144* functions145*/146public interface Function {147boolean execCollection(Set<?> subjSet, Collection<?> actorData);148}149150public static final Function methAdd = new Function() {151@SuppressWarnings("unchecked")152@Override153public boolean execCollection(Set<?> subjSet, Collection<?> actorData) {154return subjSet.addAll((Collection)actorData);155}156};157158public static final Function methContains = new Function() {159@Override160public boolean execCollection(Set<?> subjSet, Collection<?> actorData) {161return subjSet.containsAll(actorData);162}163};164165public static final Function methRemove = new Function() {166@Override167public boolean execCollection(Set<?> subjSet, Collection<?> actorData) {168return subjSet.removeAll(actorData);169}170};171172public static final Function methRetain = new Function() {173@Override174public boolean execCollection(Set<?> subjSet, Collection<?> actorData) {175return subjSet.retainAll(actorData);176}177};178179/**180* Run a test using a specified Collection method upon a Subject's181* SecureSet fields. This method expects NullPointerExceptions182* to be thrown, and throws RuntimeException when the operation183* succeeds184*/185private static void nullTestCollection(Function meth, Set<?> subjSet,186Collection<?> actorData) {187try {188meth.execCollection(subjSet, actorData);189throw new RuntimeException("Failed to throw NullPointerException");190} catch (NullPointerException npe) {191System.out.println("Caught expected NullPointerException [PASS]");192}193}194195/**196* Run a test using a specified Collection method upon a Subject's197* SecureSet fields. This method expects the function and arguments198* passed in to complete without exception. It returns false199* if either an exception occurs or the result of the operation is200* false.201*/202private static boolean validTestCollection(Function meth, Set<?> subjSet,203Collection<?> actorData) {204boolean result = false;205206try {207result = meth.execCollection(subjSet, actorData);208} catch (Exception exc) {209System.out.println("Caught exception " + exc);210}211212return result;213}214215/**216* Deserialize an object from a byte array.217*218* @param type The {@code Class} that the serialized file is supposed219* to contain.220* @param serBuffer The byte array containing the serialized object data221*222* @return An object of the type specified in the {@code type} parameter223*/224private static <T> T deserializeBuffer(Class<T> type, byte[] serBuffer)225throws IOException, ClassNotFoundException {226227ByteArrayInputStream bis = new ByteArrayInputStream(serBuffer);228ObjectInputStream ois = new ObjectInputStream(bis);229230T newObj = type.cast(ois.readObject());231ois.close();232bis.close();233234return newObj;235}236237private static void testCTOR() {238System.out.println("------ constructor ------");239240try {241// Case 1: Create a subject with a null principal242// Expected result: NullPointerException243Subject mtSubj = makeSubj(true, false, false);244throw new RuntimeException(245"constructor [principal w/ null]: Failed to throw NPE");246} catch (NullPointerException npe) {247System.out.println("constructor [principal w/ null]: " +248"NullPointerException [PASS]");249}250251try {252// Case 2: Create a subject with a null public credential element253// Expected result: NullPointerException254Subject mtSubj = makeSubj(false, true, false);255throw new RuntimeException(256"constructor [pub cred w/ null]: Failed to throw NPE");257} catch (NullPointerException npe) {258System.out.println("constructor [pub cred w/ null]: " +259"NullPointerException [PASS]");260}261262try {263// Case 3: Create a subject with a null private credential element264// Expected result: NullPointerException265Subject mtSubj = makeSubj(false, false, true);266throw new RuntimeException(267"constructor [priv cred w/ null]: Failed to throw NPE");268} catch (NullPointerException npe) {269System.out.println("constructor [priv cred w/ null]: " +270"NullPointerException [PASS]");271}272273// Case 4: Create a new subject using the principals, public274// and private credentials from another well-formed subject275// Expected result: Successful construction276Subject srcSubj = makeSubj(false, false, false);277Subject mtSubj = new Subject(false, srcSubj.getPrincipals(),278srcSubj.getPublicCredentials(),279srcSubj.getPrivateCredentials());280System.out.println("Construction from another well-formed Subject's " +281"principals/creds [PASS]");282}283284@SuppressWarnings("unchecked")285private static void testDeserialize() throws Exception {286System.out.println("------ deserialize -----");287288Subject subj = null;289Set<Principal> prin = null;290291// Case 1: positive deserialization test of a Subject292// Expected result: well-formed Subject293subj = deserializeBuffer(Subject.class, SUBJ_NO_NULL);294System.out.println("Positive deserialization test (Subject) passed");295296// Case 2: positive deserialization test of a SecureSet297// Expected result: well-formed Set298prin = deserializeBuffer(Set.class, PRIN_NO_NULL);299System.out.println("Positive deserialization test (SecureSet) passed");300301System.out.println(302"* Testing deserialization with null-poisoned objects");303// Case 3: deserialization test of a null-poisoned Subject304// Expected result: NullPointerException305try {306subj = deserializeBuffer(Subject.class, SUBJ_WITH_NULL);307throw new RuntimeException("Failed to throw NullPointerException");308} catch (NullPointerException npe) {309System.out.println("Caught expected NullPointerException [PASS]");310}311312// Case 4: deserialization test of a null-poisoned SecureSet313// Expected result: NullPointerException314try {315prin = deserializeBuffer(Set.class, PRIN_WITH_NULL);316throw new RuntimeException("Failed to throw NullPointerException");317} catch (NullPointerException npe) {318System.out.println("Caught expected NullPointerException [PASS]");319}320}321322private static void testAdd() {323System.out.println("------ add() ------");324// Create a well formed subject325Subject mtSubj = makeSubj(false, false, false);326327try {328// Case 1: Attempt to add null values to principal329// Expected result: NullPointerException330mtSubj.getPrincipals().add(null);331throw new RuntimeException(332"PRINCIPAL add(null): Failed to throw NPE");333} catch (NullPointerException npe) {334System.out.println(335"PRINCIPAL add(null): NullPointerException [PASS]");336}337338try {339// Case 2: Attempt to add null into the public creds340// Expected result: NullPointerException341mtSubj.getPublicCredentials().add(null);342throw new RuntimeException(343"PUB CRED add(null): Failed to throw NPE");344} catch (NullPointerException npe) {345System.out.println(346"PUB CRED add(null): NullPointerException [PASS]");347}348349try {350// Case 3: Attempt to add null into the private creds351// Expected result: NullPointerException352mtSubj.getPrivateCredentials().add(null);353throw new RuntimeException(354"PRIV CRED add(null): Failed to throw NPE");355} catch (NullPointerException npe) {356System.out.println(357"PRIV CRED add(null): NullPointerException [PASS]");358}359}360361private static void testRemove() {362System.out.println("------ remove() ------");363// Create a well formed subject364Subject mtSubj = makeSubj(false, false, false);365366try {367// Case 1: Attempt to remove null values from principal368// Expected result: NullPointerException369mtSubj.getPrincipals().remove(null);370throw new RuntimeException(371"PRINCIPAL remove(null): Failed to throw NPE");372} catch (NullPointerException npe) {373System.out.println(374"PRINCIPAL remove(null): NullPointerException [PASS]");375}376377try {378// Case 2: Attempt to remove null from the public creds379// Expected result: NullPointerException380mtSubj.getPublicCredentials().remove(null);381throw new RuntimeException(382"PUB CRED remove(null): Failed to throw NPE");383} catch (NullPointerException npe) {384System.out.println(385"PUB CRED remove(null): NullPointerException [PASS]");386}387388try {389// Case 3: Attempt to remove null from the private creds390// Expected result: NullPointerException391mtSubj.getPrivateCredentials().remove(null);392throw new RuntimeException(393"PRIV CRED remove(null): Failed to throw NPE");394} catch (NullPointerException npe) {395System.out.println(396"PRIV CRED remove(null): NullPointerException [PASS]");397}398}399400private static void testContains() {401System.out.println("------ contains() ------");402// Create a well formed subject403Subject mtSubj = makeSubj(false, false, false);404405try {406// Case 1: Attempt to check for null values in principals407// Expected result: NullPointerException408mtSubj.getPrincipals().contains(null);409throw new RuntimeException(410"PRINCIPAL contains(null): Failed to throw NPE");411} catch (NullPointerException npe) {412System.out.println(413"PRINCIPAL contains(null): NullPointerException [PASS]");414}415416try {417// Case 2: Attempt to check for null in public creds418// Expected result: NullPointerException419mtSubj.getPublicCredentials().contains(null);420throw new RuntimeException(421"PUB CRED contains(null): Failed to throw NPE");422} catch (NullPointerException npe) {423System.out.println(424"PUB CRED contains(null): NullPointerException [PASS]");425}426427try {428// Case 3: Attempt to check for null in private creds429// Expected result: NullPointerException430mtSubj.getPrivateCredentials().contains(null);431throw new RuntimeException(432"PRIV CRED contains(null): Failed to throw NPE");433} catch (NullPointerException npe) {434System.out.println(435"PRIV CRED contains(null): NullPointerException [PASS]");436}437}438439private static void testAddAll() {440// Create a well formed subject and additional collections441Subject mtSubj = makeSubj(false, false, false);442Set<Principal> morePrincs = new HashSet<>(Arrays.asList(tmplAddPrincs));443Set<Object> morePubVals = new HashSet<>(Arrays.asList(tmplAddPubVals));444Set<Object> morePrvVals = new HashSet<>(Arrays.asList(tmplAddPrvVals));445446// Run one success test for each Subject family to verify the447// overloaded method works as intended.448Set<Principal> setPrin = mtSubj.getPrincipals();449Set<Object> setPubCreds = mtSubj.getPublicCredentials();450Set<Object> setPrvCreds = mtSubj.getPrivateCredentials();451int prinOrigSize = setPrin.size();452int pubOrigSize = setPubCreds.size();453int prvOrigSize = setPrvCreds.size();454455System.out.println("------ addAll() -----");456457// Add the new members, then check the resulting size of the458// Subject attributes to verify they've increased by the proper459// amounts.460if ((validTestCollection(methAdd, setPrin, morePrincs) != true) ||461(setPrin.size() != prinOrigSize + morePrincs.size()))462{463throw new RuntimeException("Failed addAll() on principals");464}465if ((validTestCollection(methAdd, setPubCreds,466morePubVals) != true) ||467(setPubCreds.size() != pubOrigSize + morePubVals.size()))468{469throw new RuntimeException("Failed addAll() on public creds");470}471if ((validTestCollection(methAdd, setPrvCreds,472morePrvVals) != true) ||473(setPrvCreds.size() != prvOrigSize + morePrvVals.size()))474{475throw new RuntimeException("Failed addAll() on private creds");476}477System.out.println("Positive addAll() test passed");478479// Now add null elements into each container, then retest480morePrincs.add(null);481morePubVals.add(null);482morePrvVals.add(null);483484System.out.println("* Testing addAll w/ null values on Principals");485nullTestCollection(methAdd, mtSubj.getPrincipals(), null);486nullTestCollection(methAdd, mtSubj.getPrincipals(), morePrincs);487488System.out.println("* Testing addAll w/ null values on Public Creds");489nullTestCollection(methAdd, mtSubj.getPublicCredentials(), null);490nullTestCollection(methAdd, mtSubj.getPublicCredentials(),491morePubVals);492493System.out.println("* Testing addAll w/ null values on Private Creds");494nullTestCollection(methAdd, mtSubj.getPrivateCredentials(), null);495nullTestCollection(methAdd, mtSubj.getPrivateCredentials(),496morePrvVals);497}498499private static void testRemoveAll() {500// Create a well formed subject and additional collections501Subject mtSubj = makeSubj(false, false, false);502Set<Principal> remPrincs = new HashSet<>();503Set<Object> remPubVals = new HashSet<>();504Set<Object> remPrvVals = new HashSet<>();505506remPrincs.add(new KerberosPrincipal("mtwain/[email protected]"));507remPubVals.add("mtwain");508remPrvVals.add("5Cl3M3nz");509510// Run one success test for each Subject family to verify the511// overloaded method works as intended.512Set<Principal> setPrin = mtSubj.getPrincipals();513Set<Object> setPubCreds = mtSubj.getPublicCredentials();514Set<Object> setPrvCreds = mtSubj.getPrivateCredentials();515int prinOrigSize = setPrin.size();516int pubOrigSize = setPubCreds.size();517int prvOrigSize = setPrvCreds.size();518519System.out.println("------ removeAll() -----");520521// Remove the specified members, then check the resulting size of the522// Subject attributes to verify they've decreased by the proper523// amounts.524if ((validTestCollection(methRemove, setPrin, remPrincs) != true) ||525(setPrin.size() != prinOrigSize - remPrincs.size()))526{527throw new RuntimeException("Failed removeAll() on principals");528}529if ((validTestCollection(methRemove, setPubCreds,530remPubVals) != true) ||531(setPubCreds.size() != pubOrigSize - remPubVals.size()))532{533throw new RuntimeException("Failed removeAll() on public creds");534}535if ((validTestCollection(methRemove, setPrvCreds,536remPrvVals) != true) ||537(setPrvCreds.size() != prvOrigSize - remPrvVals.size()))538{539throw new RuntimeException("Failed removeAll() on private creds");540}541System.out.println("Positive removeAll() test passed");542543// Now add null elements into each container, then retest544remPrincs.add(null);545remPubVals.add(null);546remPrvVals.add(null);547548System.out.println("* Testing removeAll w/ null values on Principals");549nullTestCollection(methRemove, mtSubj.getPrincipals(), null);550nullTestCollection(methRemove, mtSubj.getPrincipals(), remPrincs);551552System.out.println(553"* Testing removeAll w/ null values on Public Creds");554nullTestCollection(methRemove, mtSubj.getPublicCredentials(), null);555nullTestCollection(methRemove, mtSubj.getPublicCredentials(),556remPubVals);557558System.out.println(559"* Testing removeAll w/ null values on Private Creds");560nullTestCollection(methRemove, mtSubj.getPrivateCredentials(), null);561nullTestCollection(methRemove, mtSubj.getPrivateCredentials(),562remPrvVals);563}564565private static void testContainsAll() {566// Create a well formed subject and additional collections567Subject mtSubj = makeSubj(false, false, false);568Set<Principal> testPrincs = new HashSet<>(Arrays.asList(princVals));569Set<Object> testPubVals = new HashSet<>(Arrays.asList(pubVals));570Set<Object> testPrvVals = new HashSet<>(Arrays.asList(privVals));571572System.out.println("------ containsAll() -----");573574// Run one success test for each Subject family to verify the575// overloaded method works as intended.576if ((validTestCollection(methContains, mtSubj.getPrincipals(),577testPrincs) == false) &&578(validTestCollection(methContains, mtSubj.getPublicCredentials(),579testPubVals) == false) &&580(validTestCollection(methContains,581mtSubj.getPrivateCredentials(), testPrvVals) == false)) {582throw new RuntimeException("Valid containsAll() check failed");583}584System.out.println("Positive containsAll() test passed");585586// Now let's add a null into each collection and watch the fireworks.587testPrincs.add(null);588testPubVals.add(null);589testPrvVals.add(null);590591System.out.println(592"* Testing containsAll w/ null values on Principals");593nullTestCollection(methContains, mtSubj.getPrincipals(), null);594nullTestCollection(methContains, mtSubj.getPrincipals(), testPrincs);595596System.out.println(597"* Testing containsAll w/ null values on Public Creds");598nullTestCollection(methContains, mtSubj.getPublicCredentials(),599null);600nullTestCollection(methContains, mtSubj.getPublicCredentials(),601testPubVals);602603System.out.println(604"* Testing containsAll w/ null values on Private Creds");605nullTestCollection(methContains, mtSubj.getPrivateCredentials(),606null);607nullTestCollection(methContains, mtSubj.getPrivateCredentials(),608testPrvVals);609}610611private static void testRetainAll() {612// Create a well formed subject and additional collections613Subject mtSubj = makeSubj(false, false, false);614Set<Principal> remPrincs = new HashSet<>(Arrays.asList(tmplAddPrincs));615Set<Object> remPubVals = new HashSet<>(Arrays.asList(tmplAddPubVals));616Set<Object> remPrvVals = new HashSet<>(Arrays.asList(tmplAddPrvVals));617618// Add in values that exist within the Subject619remPrincs.add(princVals[2]);620remPubVals.add(pubVals[2]);621remPrvVals.add(privVals[2]);622623// Run one success test for each Subject family to verify the624// overloaded method works as intended.625Set<Principal> setPrin = mtSubj.getPrincipals();626Set<Object> setPubCreds = mtSubj.getPublicCredentials();627Set<Object> setPrvCreds = mtSubj.getPrivateCredentials();628int prinOrigSize = setPrin.size();629int pubOrigSize = setPubCreds.size();630int prvOrigSize = setPrvCreds.size();631632System.out.println("------ retainAll() -----");633634// Retain the specified members (those that exist in the Subject)635// and validate the results.636if (validTestCollection(methRetain, setPrin, remPrincs) == false ||637setPrin.size() != 1 || setPrin.contains(princVals[2]) == false)638{639throw new RuntimeException("Failed retainAll() on principals");640}641642if (validTestCollection(methRetain, setPubCreds,643remPubVals) == false ||644setPubCreds.size() != 1 ||645setPubCreds.contains(pubVals[2]) == false)646{647throw new RuntimeException("Failed retainAll() on public creds");648}649if (validTestCollection(methRetain, setPrvCreds,650remPrvVals) == false ||651setPrvCreds.size() != 1 ||652setPrvCreds.contains(privVals[2]) == false)653{654throw new RuntimeException("Failed retainAll() on private creds");655}656System.out.println("Positive retainAll() test passed");657658// Now add null elements into each container, then retest659remPrincs.add(null);660remPubVals.add(null);661remPrvVals.add(null);662663System.out.println("* Testing retainAll w/ null values on Principals");664nullTestCollection(methRetain, mtSubj.getPrincipals(), null);665nullTestCollection(methRetain, mtSubj.getPrincipals(), remPrincs);666667System.out.println(668"* Testing retainAll w/ null values on Public Creds");669nullTestCollection(methRetain, mtSubj.getPublicCredentials(), null);670nullTestCollection(methRetain, mtSubj.getPublicCredentials(),671remPubVals);672673System.out.println(674"* Testing retainAll w/ null values on Private Creds");675nullTestCollection(methRetain, mtSubj.getPrivateCredentials(), null);676nullTestCollection(methRetain, mtSubj.getPrivateCredentials(),677remPrvVals);678}679680private static void testIsEmpty() {681Subject populatedSubj = makeSubj(false, false, false);682Subject emptySubj = new Subject();683684System.out.println("------ isEmpty() -----");685686if (populatedSubj.getPrincipals().isEmpty()) {687throw new RuntimeException(688"Populated Subject Principals incorrectly returned empty");689}690if (emptySubj.getPrincipals().isEmpty() == false) {691throw new RuntimeException(692"Empty Subject Principals incorrectly returned non-empty");693}694System.out.println("isEmpty() test passed");695}696697private static void testSecureSetEquals() {698System.out.println("------ SecureSet.equals() -----");699700Subject subj = makeSubj(false, false, false);701Subject subjComp = makeSubj(false, false, false);702703// Case 1: null comparison [expect false]704if (subj.getPublicCredentials().equals(null) != false) {705throw new RuntimeException(706"equals(null) incorrectly returned true");707}708709// Case 2: Self-comparison [expect true]710Set<Principal> princs = subj.getPrincipals();711princs.equals(subj.getPrincipals());712713// Case 3: Comparison with non-Set type [expect false]714List<Principal> listPrinc = new LinkedList<>(Arrays.asList(princVals));715if (subj.getPublicCredentials().equals(listPrinc) != false) {716throw new RuntimeException(717"equals([Non-Set]) incorrectly returned true");718}719720// Case 4: SecureSets of differing sizes [expect false]721Subject subj1princ = new Subject();722Subject subj2princ = new Subject();723subj1princ.getPrincipals().add(724new X500Principal("CN=Tom Sawyer, ST=Missouri, C=US"));725subj1princ.getPrincipals().add(726new X500Principal("CN=John Doe, O=Bogus Corp."));727subj2princ.getPrincipals().add(728new X500Principal("CN=Tom Sawyer, ST=Missouri, C=US"));729if (subj1princ.getPrincipals().equals(730subj2princ.getPrincipals()) != false) {731throw new RuntimeException(732"equals([differing sizes]) incorrectly returned true");733}734735// Case 5: Content equality test [expect true]736Set<Principal> equalSet = new HashSet<>(Arrays.asList(princVals));737if (subj.getPrincipals().equals(equalSet) != true) {738throw new RuntimeException(739"equals([equivalent set]) incorrectly returned false");740}741742// Case 5: Content inequality test [expect false]743// Note: to not fall into the size inequality check the two744// sets need to have the same number of elements.745Set<Principal> inequalSet =746new HashSet<Principal>(Arrays.asList(tmplAddPrincs));747inequalSet.add(new JMXPrincipal("Samuel Clemens"));748749if (subj.getPrincipals().equals(inequalSet) != false) {750throw new RuntimeException(751"equals([equivalent set]) incorrectly returned false");752}753System.out.println("SecureSet.equals() tests passed");754}755756private static void testSecureSetHashCode() {757System.out.println("------ SecureSet.hashCode() -----");758759Subject subj = makeSubj(false, false, false);760761// Make sure two other Set types that we know are equal per762// SecureSet.equals() and verify their hashCodes are also the same763Set<Principal> equalHashSet = new HashSet<>(Arrays.asList(princVals));764765if (subj.getPrincipals().hashCode() != equalHashSet.hashCode()) {766throw new RuntimeException(767"SecureSet and HashSet hashCodes() differ");768}769System.out.println("SecureSet.hashCode() tests passed");770}771772private static void testToArray() {773System.out.println("------ toArray() -----");774775Subject subj = makeSubj(false, false, false);776777// Case 1: no-parameter toArray with equality comparison778// Expected result: true779List<Object> alSubj = Arrays.asList(subj.getPrincipals().toArray());780List<Principal> alPrincs = Arrays.asList(princVals);781782if (alSubj.size() != alPrincs.size() ||783alSubj.containsAll(alPrincs) != true) {784throw new RuntimeException(785"Unexpected inequality on returned toArray()");786}787788// Case 2: generic-type toArray where passed array is of sufficient789// size.790// Expected result: returned Array is reference-equal to input param791// and content equal to data used to construct the originating Subject.792Principal[] pBlock = new Principal[3];793Principal[] pBlockRef = subj.getPrincipals().toArray(pBlock);794alSubj = Arrays.asList((Object[])pBlockRef);795796if (pBlockRef != pBlock) {797throw new RuntimeException(798"Unexpected reference-inequality on returned toArray(T[])");799} else if (alSubj.size() != alPrincs.size() ||800alSubj.containsAll(alPrincs) != true) {801throw new RuntimeException(802"Unexpected content-inequality on returned toArray(T[])");803}804805// Case 3: generic-type toArray where passed array is of806// insufficient size.807// Expected result: returned Array is not reference-equal to808// input param but is content equal to data used to construct the809// originating Subject.810pBlock = new Principal[1];811pBlockRef = subj.getPrincipals().toArray(pBlock);812alSubj = Arrays.asList((Object[])pBlockRef);813814if (pBlockRef == pBlock) {815throw new RuntimeException(816"Unexpected reference-equality on returned toArray(T[])");817} else if (alSubj.size() != alPrincs.size() ||818alSubj.containsAll(alPrincs) != true) {819throw new RuntimeException(820"Unexpected content-inequality on returned toArray(T[])");821}822System.out.println("toArray() tests passed");823}824825public static void main(String[] args) throws Exception {826827testCTOR();828829testDeserialize();830831testAdd();832833testRemove();834835testContains();836837testAddAll();838839testRemoveAll();840841testContainsAll();842843testRetainAll();844845testIsEmpty();846847testSecureSetEquals();848849testSecureSetHashCode();850851testToArray();852}853}854855856