Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

8334562: Automate com/sun/security/auth/callback/TextCallbackHandler/Default.java test #19790

Closed
wants to merge 2 commits into from
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion test/jdk/ProblemList.txt
Original file line number Diff line number Diff line change
@@ -609,7 +609,6 @@ sun/security/smartcardio/TestMultiplePresent.java 8039280 generic-
sun/security/smartcardio/TestPresent.java 8039280 generic-all
sun/security/smartcardio/TestTransmit.java 8039280 generic-all
com/sun/crypto/provider/Cipher/DES/PerformanceTest.java 8039280 generic-all
com/sun/security/auth/callback/TextCallbackHandler/Default.java 8039280 generic-all
com/sun/security/auth/callback/TextCallbackHandler/Password.java 8039280 generic-all
com/sun/security/sasl/gsskerb/AuthOnly.java 8039280 generic-all
com/sun/security/sasl/gsskerb/ConfSecurityLayer.java 8039280 generic-all
1 change: 0 additions & 1 deletion test/jdk/TEST.groups
Original file line number Diff line number Diff line change
@@ -621,7 +621,6 @@ jdk_security_manual_no_input = \
com/sun/crypto/provider/Cipher/DES/PerformanceTest.java \
com/sun/crypto/provider/Cipher/AEAD/GCMIncrementByte4.java \
com/sun/crypto/provider/Cipher/AEAD/GCMIncrementDirect4.java \
com/sun/security/auth/callback/TextCallbackHandler/Default.java \
com/sun/security/auth/callback/TextCallbackHandler/Password.java \
com/sun/security/sasl/gsskerb/AuthOnly.java \
com/sun/security/sasl/gsskerb/ConfSecurityLayer.java \
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2001, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -23,31 +23,48 @@

/*
* @test
* @library /test/lib /java/security/testlibrary
* @bug 4470717
* @summary fix default handling and other misc
* @run main/manual Default
* @run main/othervm Default
*/

import com.sun.security.auth.callback.TextCallbackHandler;
import jdk.test.lib.Asserts;

import javax.security.auth.callback.*;
import java.io.*;

public class Default {
public static void main(String args[]) throws Exception {
TextCallbackHandler h = new TextCallbackHandler();
NameCallback nc = new NameCallback("Name: ", "charlie");
ConfirmationCallback cc = new ConfirmationCallback
("Correct?",
ConfirmationCallback.INFORMATION,
ConfirmationCallback.YES_NO_OPTION,
ConfirmationCallback.NO);

Callback[] callbacks = { nc, cc };
h.handle(callbacks);

if (cc.getSelectedIndex() == ConfirmationCallback.YES) {
System.out.println("yes");
} else {
System.out.println("no");
public static void main(String args[]) throws Exception {
InputStream in = System.in;
PrintStream err = System.err;
ByteArrayOutputStream baos = new ByteArrayOutputStream();
final String defaultName = "charlie";
final String simulatedInput = "-1\n-1\n";
HumanInputStream humanInputStream = new HumanInputStream(simulatedInput);

try (PrintStream prints = new PrintStream(baos)) {
System.setIn(humanInputStream);
System.setErr(prints);
NameCallback nameCallback = new NameCallback("Name: ", defaultName);
ConfirmationCallback confirmationCallback = new ConfirmationCallback(
"Correct?",
ConfirmationCallback.INFORMATION,
ConfirmationCallback.YES_NO_OPTION,
ConfirmationCallback.NO);
new TextCallbackHandler().handle(new Callback[]{nameCallback, confirmationCallback});

Asserts.assertEquals(nameCallback.getDefaultName(), defaultName);
Asserts.assertEquals(confirmationCallback.getSelectedIndex(), ConfirmationCallback.NO);

} finally {
System.setIn(in);
System.setErr(err);
}
}

// check that the default name and confirmation were visible in the output
Asserts.assertTrue(baos.toString().contains(String.format("Name: [%s]", defaultName)));
Asserts.assertTrue(baos.toString().contains("1. No [default]"));
}
}
192 changes: 192 additions & 0 deletions test/jdk/java/security/testlibrary/HumanInputStream.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,192 @@
/*
* Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;

/**
* HumanInputStream tries to act like a human sitting in front of a computer
* terminal typing on the keyboard while a program is running.
* <p>
* The program may call InputStream.read() and BufferedReader.readLine() in
* various places. a call to B.readLine() will try to buffer as much input as
* possible. Thus, a trivial InputStream will find it impossible to feed
* anything to I.read() after a B.readLine() call.
* <p>
* This is why HumanInputStream was created, which will only send a single line
* to B.readLine(), no more, no less, and the next I.read() can have a chance
* to read the exact character right after "\n".
*
*/

public class HumanInputStream extends InputStream {
byte[] src;
int pos;
int length;
boolean inLine;
int stopIt;

public HumanInputStream(String input) {
src = input.getBytes();
pos = 0;
length = src.length;
stopIt = 0;
inLine = false;
}

// the trick: when called through read(byte[], int, int),
// return -1 twice after "\n"

@Override public int read() throws IOException {
int re;
if(pos < length) {
re = src[pos];
if(inLine) {
if(stopIt > 0) {
stopIt--;
re = -1;
} else {
if(re == '\n') {
stopIt = 2;
}
pos++;
}
} else {
pos++;
}
} else {
re = -1; //throws new IOException("NO MORE TO READ");
}
return re;
}
@Override public int read(byte[] buffer, int offset, int len) {
inLine = true;
try {
return super.read(buffer, offset, len);
} catch(Exception e) {
throw new RuntimeException("HumanInputStream error");
} finally {
inLine = false;
}
}
@Override public int available() {
if (pos < length) return 1;
return 0;
}

// test part
static void assertTrue(boolean bool) {
if (!bool)
throw new RuntimeException();
}

public static void test() throws Exception {
class Tester {
HumanInputStream is;
BufferedReader reader;
Tester(String s) {
is = new HumanInputStream(s);
reader = new BufferedReader(new InputStreamReader(is));
}

// three kinds of test method
// 1. read byte by byte from InputStream
void testStreamReadOnce(int expection) throws Exception {
assertTrue(is.read() == expection);
}
void testStreamReadMany(String expectation) throws Exception {
char[] keys = expectation.toCharArray();
for (char key : keys) {
assertTrue(is.read() == key);
}
}
// 2. read a line with a newly created Reader
void testReaderReadline(String expectation) throws Exception {
String s = new BufferedReader(new InputStreamReader(is)).readLine();
if(s == null) assertTrue(expectation == null);
else assertTrue(s.equals(expectation));
}
// 3. read a line with the old Reader
void testReaderReadline2(String expectation) throws Exception {
String s = reader.readLine();
if(s == null) assertTrue(expectation == null);
else assertTrue(s.equals(expectation));
}
}

Tester test;

test = new Tester("111\n222\n\n444\n\n");
test.testReaderReadline("111");
test.testReaderReadline("222");
test.testReaderReadline("");
test.testReaderReadline("444");
test.testReaderReadline("");
test.testReaderReadline(null);

test = new Tester("111\n222\n\n444\n\n");
test.testReaderReadline2("111");
test.testReaderReadline2("222");
test.testReaderReadline2("");
test.testReaderReadline2("444");
test.testReaderReadline2("");
test.testReaderReadline2(null);

test = new Tester("111\n222\n\n444\n\n");
test.testReaderReadline2("111");
test.testReaderReadline("222");
test.testReaderReadline2("");
test.testReaderReadline2("444");
test.testReaderReadline("");
test.testReaderReadline2(null);

test = new Tester("1\n2");
test.testStreamReadMany("1\n2");
test.testStreamReadOnce(-1);

test = new Tester("12\n234");
test.testStreamReadOnce('1');
test.testReaderReadline("2");
test.testStreamReadOnce('2');
test.testReaderReadline2("34");
test.testReaderReadline2(null);

test = new Tester("changeit\n");
test.testStreamReadMany("changeit\n");
test.testReaderReadline(null);

test = new Tester("changeit\nName\nCountry\nYes\n");
test.testStreamReadMany("changeit\n");
test.testReaderReadline("Name");
test.testReaderReadline("Country");
test.testReaderReadline("Yes");
test.testReaderReadline(null);

test = new Tester("Me\nHere\n");
test.testReaderReadline2("Me");
test.testReaderReadline2("Here");
}
}
173 changes: 3 additions & 170 deletions test/jdk/sun/security/tools/keytool/KeyToolTest.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2005, 2020, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2005, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -23,6 +23,7 @@

/*
* @test
* @library /java/security/testlibrary
* @bug 6251120 8231950 8242151
* @summary Testing keytool
*
@@ -1865,172 +1866,4 @@ class TestException extends Exception {
public TestException(String e) {
super(e);
}
}

/**
* HumanInputStream tries to act like a human sitting in front of a computer
* terminal typing on the keyboard while the keytool program is running.
*
* keytool has called InputStream.read() and BufferedReader.readLine() in
* various places. a call to B.readLine() will try to buffer as much input as
* possible. Thus, a trivial InputStream will find it impossible to feed
* anything to I.read() after a B.readLine() call.
*
* This is why i create HumanInputStream, which will only send a single line
* to B.readLine(), no more, no less, and the next I.read() can have a chance
* to read the exact character right after "\n".
*
* I don't know why HumanInputStream works.
*/
class HumanInputStream extends InputStream {
byte[] src;
int pos;
int length;
boolean inLine;
int stopIt;

public HumanInputStream(String input) {
src = input.getBytes();
pos = 0;
length = src.length;
stopIt = 0;
inLine = false;
}

// the trick: when called through read(byte[], int, int),
// return -1 twice after "\n"

@Override public int read() throws IOException {
int re;
if(pos < length) {
re = src[pos];
if(inLine) {
if(stopIt > 0) {
stopIt--;
re = -1;
} else {
if(re == '\n') {
stopIt = 2;
}
pos++;
}
} else {
pos++;
}
} else {
re = -1;//throw new IOException("NO MORE TO READ");
}
//if (re < 32) System.err.printf("[%02d]", re);
//else System.err.printf("[%c]", (char)re);
return re;
}
@Override public int read(byte[] buffer, int offset, int len) {
inLine = true;
try {
int re = super.read(buffer, offset, len);
return re;
} catch(Exception e) {
throw new RuntimeException("HumanInputStream error");
} finally {
inLine = false;
}
}
@Override public int available() {
if(pos < length) return 1;
return 0;
}

// test part
static void assertTrue(boolean bool) {
if(!bool)
throw new RuntimeException();
}

public static void test() throws Exception {

class Tester {
HumanInputStream is;
BufferedReader reader;
Tester(String s) {
is = new HumanInputStream(s);
reader = new BufferedReader(new InputStreamReader(is));
}

// three kinds of test method
// 1. read byte by byte from InputStream
void testStreamReadOnce(int expection) throws Exception {
assertTrue(is.read() == expection);
}
void testStreamReadMany(String expection) throws Exception {
char[] keys = expection.toCharArray();
for(int i=0; i<keys.length; i++) {
assertTrue(is.read() == keys[i]);
}
}
// 2. read a line with a newly created Reader
void testReaderReadline(String expection) throws Exception {
String s = new BufferedReader(new InputStreamReader(is)).readLine();
if(s == null) assertTrue(expection == null);
else assertTrue(s.equals(expection));
}
// 3. read a line with the old Reader
void testReaderReadline2(String expection) throws Exception {
String s = reader.readLine();
if(s == null) assertTrue(expection == null);
else assertTrue(s.equals(expection));
}
}

Tester test;

test = new Tester("111\n222\n\n444\n\n");
test.testReaderReadline("111");
test.testReaderReadline("222");
test.testReaderReadline("");
test.testReaderReadline("444");
test.testReaderReadline("");
test.testReaderReadline(null);

test = new Tester("111\n222\n\n444\n\n");
test.testReaderReadline2("111");
test.testReaderReadline2("222");
test.testReaderReadline2("");
test.testReaderReadline2("444");
test.testReaderReadline2("");
test.testReaderReadline2(null);

test = new Tester("111\n222\n\n444\n\n");
test.testReaderReadline2("111");
test.testReaderReadline("222");
test.testReaderReadline2("");
test.testReaderReadline2("444");
test.testReaderReadline("");
test.testReaderReadline2(null);

test = new Tester("1\n2");
test.testStreamReadMany("1\n2");
test.testStreamReadOnce(-1);

test = new Tester("12\n234");
test.testStreamReadOnce('1');
test.testReaderReadline("2");
test.testStreamReadOnce('2');
test.testReaderReadline2("34");
test.testReaderReadline2(null);

test = new Tester("changeit\n");
test.testStreamReadMany("changeit\n");
test.testReaderReadline(null);

test = new Tester("changeit\nName\nCountry\nYes\n");
test.testStreamReadMany("changeit\n");
test.testReaderReadline("Name");
test.testReaderReadline("Country");
test.testReaderReadline("Yes");
test.testReaderReadline(null);

test = new Tester("Me\nHere\n");
test.testReaderReadline2("Me");
test.testReaderReadline2("Here");
}
}
}