Skip to content

Commit 5561a05

Browse files
committed
Additional tests to verify different ways to resolve TNS name.
1 parent 11f2ae8 commit 5561a05

1 file changed

Lines changed: 79 additions & 8 deletions

File tree

‎src/test/java/org/utplsql/cli/WalletConnectionIT.java‎

Lines changed: 79 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,16 +8,21 @@
88
import org.utplsql.cli.datasource.TestedDataSourceProvider;
99

1010
import javax.sql.DataSource;
11+
import java.io.IOException;
1112
import java.nio.file.Files;
1213
import java.nio.file.Path;
14+
import java.nio.file.Paths;
1315
import java.sql.Connection;
1416
import java.sql.ResultSet;
1517
import java.sql.Statement;
18+
import java.util.Map;
19+
import java.util.concurrent.TimeUnit;
1620
import java.util.regex.Matcher;
1721
import java.util.regex.Pattern;
1822

1923
import static org.junit.jupiter.api.Assertions.assertEquals;
2024
import static org.junit.jupiter.api.Assertions.assertTrue;
25+
import static org.junit.jupiter.api.Assertions.fail;
2126
import static org.junit.jupiter.api.Assumptions.assumeTrue;
2227

2328
/**
@@ -26,15 +31,22 @@
2631
* <p>
2732
* The wallet, tnsnames.ora and ojdbc.properties are created on the fly from DB_URL / DB_USER / DB_PASS,
2833
* so no Oracle client tooling (mkstore/orapki) is needed.
34+
* <p>
35+
* TNS_ADMIN and ORACLE_HOME are read once per JVM and environment variables can't be changed at runtime,
36+
* so the scenarios depending on them run the CLI in a separate JVM with a controlled environment.
2937
*/
3038
class WalletConnectionIT {
3139

3240
private static final String TNS_ALIAS = "UTPLSQL_CLI_WALLET";
3341
private static final Pattern EZ_CONNECT = Pattern.compile("^//([^:/]+)(?::(\\d+))?/(.+)$");
42+
private static final long SUBPROCESS_TIMEOUT_MINUTES = 3;
3443

3544
@TempDir
36-
static Path tnsAdmin;
45+
static Path tempDir;
3746

47+
private static Path tnsAdmin;
48+
private static Path oracleHome;
49+
private static Path emptyOracleHome;
3850
private static String walletConnectString;
3951

4052
@BeforeAll
@@ -45,7 +57,7 @@ static void createWallet() throws Exception {
4557
String port = m.group(2) == null ? "1521" : m.group(2);
4658
String service = m.group(3);
4759

48-
Path walletDir = Files.createDirectories(tnsAdmin.resolve("wallet"));
60+
Path walletDir = Files.createDirectories(tempDir.resolve("wallet"));
4961
char[] walletPassword = "Wallet_Pwd_123".toCharArray();
5062

5163
OracleWallet wallet = new OracleWallet();
@@ -61,16 +73,26 @@ static void createWallet() throws Exception {
6173

6274
assertTrue(Files.exists(walletDir.resolve("cwallet.sso")), "auto-login wallet was not created");
6375

64-
Files.writeString(tnsAdmin.resolve("tnsnames.ora"),
65-
TNS_ALIAS + " = (DESCRIPTION = (ADDRESS = (PROTOCOL = TCP)(HOST = " + host + ")(PORT = " + port + "))"
66-
+ "(CONNECT_DATA = (SERVICE_NAME = " + service + ")))\n");
67-
Files.writeString(tnsAdmin.resolve("ojdbc.properties"),
68-
"oracle.net.wallet_location=(SOURCE=(METHOD=FILE)(METHOD_DATA=(DIRECTORY="
69-
+ forwardSlashes(walletDir) + ")))\n");
76+
String tnsnamesOra = TNS_ALIAS + " = (DESCRIPTION = (ADDRESS = (PROTOCOL = TCP)(HOST = " + host + ")(PORT = " + port + "))"
77+
+ "(CONNECT_DATA = (SERVICE_NAME = " + service + ")))\n";
78+
String ojdbcProperties = "oracle.net.wallet_location=(SOURCE=(METHOD=FILE)(METHOD_DATA=(DIRECTORY="
79+
+ forwardSlashes(walletDir) + ")))\n";
80+
81+
tnsAdmin = writeNetworkConfig(tempDir.resolve("tns_admin"), tnsnamesOra, ojdbcProperties);
82+
oracleHome = tempDir.resolve("oracle_home");
83+
writeNetworkConfig(oracleHome.resolve("network").resolve("admin"), tnsnamesOra, ojdbcProperties);
84+
emptyOracleHome = Files.createDirectories(tempDir.resolve("empty_oracle_home"));
7085

7186
walletConnectString = "/@" + TNS_ALIAS + "?TNS_ADMIN=" + forwardSlashes(tnsAdmin);
7287
}
7388

89+
private static Path writeNetworkConfig(Path dir, String tnsnamesOra, String ojdbcProperties) throws IOException {
90+
Files.createDirectories(dir);
91+
Files.writeString(dir.resolve("tnsnames.ora"), tnsnamesOra);
92+
Files.writeString(dir.resolve("ojdbc.properties"), ojdbcProperties);
93+
return dir;
94+
}
95+
7496
private static String forwardSlashes(Path path) {
7597
return path.toAbsolutePath().toString().replace('\\', '/');
7698
}
@@ -98,4 +120,53 @@ void runCommandWithWallet() {
98120

99121
assertEquals(0, result);
100122
}
123+
124+
@Test
125+
void runCommandWithTnsAdminEnvironmentVariable() throws Exception {
126+
assertCliConnectsWithWallet(Map.of("TNS_ADMIN", tnsAdmin.toString()));
127+
}
128+
129+
@Test
130+
void runCommandWithOracleHomeFallback() throws Exception {
131+
assertCliConnectsWithWallet(Map.of("ORACLE_HOME", oracleHome.toString()));
132+
}
133+
134+
@Test
135+
void tnsAdminEnvironmentVariableTakesPrecedenceOverOracleHome() throws Exception {
136+
// Fails if ORACLE_HOME/network/admin (without tnsnames.ora) is used instead of TNS_ADMIN
137+
assertCliConnectsWithWallet(Map.of(
138+
"TNS_ADMIN", tnsAdmin.toString(),
139+
"ORACLE_HOME", emptyOracleHome.toString()));
140+
}
141+
142+
/**
143+
* Runs {@code utplsql run /@<TNS alias>} in a separate JVM with TNS_ADMIN and ORACLE_HOME
144+
* replaced by the given environment
145+
*/
146+
private void assertCliConnectsWithWallet(Map<String, String> environment) throws Exception {
147+
Path java = Paths.get(System.getProperty("java.home"), "bin", "java");
148+
ProcessBuilder processBuilder = new ProcessBuilder(
149+
java.toString(), "-cp", System.getProperty("java.class.path"),
150+
Cli.class.getName(), "run", "/@" + TNS_ALIAS,
151+
"-f=ut_documentation_reporter", "-s", "--failure-exit-code=0");
152+
153+
processBuilder.environment().remove("TNS_ADMIN");
154+
processBuilder.environment().remove("ORACLE_HOME");
155+
processBuilder.environment().putAll(environment);
156+
157+
Path output = Files.createTempFile(tempDir, "cli-output", ".log");
158+
processBuilder.redirectErrorStream(true);
159+
processBuilder.redirectOutput(output.toFile());
160+
161+
Process process = processBuilder.start();
162+
if (!process.waitFor(SUBPROCESS_TIMEOUT_MINUTES, TimeUnit.MINUTES)) {
163+
process.destroyForcibly();
164+
fail("CLI did not finish within " + SUBPROCESS_TIMEOUT_MINUTES + " minutes. Output:\n" + Files.readString(output));
165+
}
166+
167+
String cliOutput = Files.readString(output);
168+
assertEquals(0, process.exitValue(), () -> "CLI failed with environment " + environment + ". Output:\n" + cliOutput);
169+
assertTrue(cliOutput.contains("Use connection string jdbc:oracle:thin:/@" + TNS_ALIAS),
170+
() -> "Expected wallet connection with environment " + environment + ". Output:\n" + cliOutput);
171+
}
101172
}

0 commit comments

Comments
 (0)