Skip to content

Commit 30dae1f

Browse files
authored
Fix bug with config file parsing (#2)
* Fix bug with config file parsing The Java config file parser implements a very basic key-value line parse. This change fixes the logic to better handle whitespace and key/value separation. * One more unit test validation * Add missing file
1 parent 96e277b commit 30dae1f

File tree

8 files changed

+89
-41
lines changed

8 files changed

+89
-41
lines changed

bmc-common/src/main/java/com/oracle/bmc/ConfigFileReader.java

Lines changed: 26 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/**
2-
* Copyright (c) 2016 Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2016-2017 Oracle and/or its affiliates. All rights reserved.
33
*/
44
package com.oracle.bmc;
55

@@ -30,6 +30,7 @@ public final class ConfigFileReader {
3030
* Default location of the config file.
3131
*/
3232
public static final String DEFAULT_FILE_PATH = "~/.oraclebmc/config";
33+
private static final String DEFAULT_PROFILE_NAME = "DEFAULT";
3334

3435
/**
3536
* Creates a new ConfigFile instance using the configuration at the default location,
@@ -146,7 +147,7 @@ public String get(String key) {
146147
&& (accumulator.configurationsByProfile.get(profile).containsKey(key))) {
147148
return accumulator.configurationsByProfile.get(profile).get(key);
148149
}
149-
return accumulator.configurationsByProfile.get("DEFAULT").get(key);
150+
return accumulator.configurationsByProfile.get(DEFAULT_PROFILE_NAME).get(key);
150151
}
151152
}
152153

@@ -159,7 +160,6 @@ private static final class ConfigAccumulator {
159160
private void accept(String line) {
160161
final String trimmedLine = line.trim();
161162

162-
// no blank lines
163163
if (trimmedLine.isEmpty()) {
164164
return;
165165
}
@@ -169,30 +169,39 @@ private void accept(String line) {
169169
return;
170170
}
171171

172-
if (trimmedLine.charAt(0) == '[') {
172+
if (trimmedLine.charAt(0) == '['
173+
&& trimmedLine.charAt(trimmedLine.length() - 1) == ']') {
173174
currentProfile = trimmedLine.substring(1, trimmedLine.length() - 1).trim();
174-
if (currentProfile.equals("DEFAULT")) {
175+
if (currentProfile.isEmpty()) {
176+
throw new IllegalStateException("Cannot have empty profile name: " + line);
177+
}
178+
if (currentProfile.equals(DEFAULT_PROFILE_NAME)) {
175179
foundDefaultProfile = true;
176180
}
177-
}
181+
if (!configurationsByProfile.containsKey(currentProfile)) {
182+
configurationsByProfile.put(currentProfile, new HashMap<String, String>());
183+
}
178184

179-
if (currentProfile == null) {
180-
throw new IllegalStateException(
181-
"Config parse error, attempted to read configuration without specifying a profile: "
182-
+ trimmedLine);
185+
return;
183186
}
184187

185-
final String[] keyValue = trimmedLine.split("=");
186-
if (keyValue.length != 2) {
187-
return;
188+
final int splitIndex = trimmedLine.indexOf('=');
189+
if (splitIndex == -1) {
190+
throw new IllegalStateException("Found line with no key-value pair: " + line);
188191
}
189192

190-
final String key = keyValue[0];
191-
final String value = keyValue[1];
193+
final String key = trimmedLine.substring(0, splitIndex).trim();
194+
final String value = trimmedLine.substring(splitIndex + 1).trim();
195+
if (key.isEmpty()) {
196+
throw new IllegalStateException("Found line with no key: " + line);
197+
}
192198

193-
if (!configurationsByProfile.containsKey(currentProfile)) {
194-
configurationsByProfile.put(currentProfile, new HashMap<String, String>());
199+
if (currentProfile == null) {
200+
throw new IllegalStateException(
201+
"Config parse error, attempted to read configuration without specifying a profile: "
202+
+ line);
195203
}
204+
196205
configurationsByProfile.get(currentProfile).put(key, value);
197206
}
198207
}

bmc-common/src/test/java/com/oracle/bmc/ConfigFileReaderTest.java

Lines changed: 36 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/**
2-
* Copyright (c) 2016 Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2016-2017 Oracle and/or its affiliates. All rights reserved.
33
*/
44
package com.oracle.bmc;
55

@@ -24,29 +24,52 @@ public void noDefaultProfile() throws IOException {
2424
ConfigFileReader.parse("src/test/resources/unit_test_no_default_config");
2525
}
2626

27+
@Test(expected = IllegalStateException.class)
28+
public void noLeadingProfile() throws IOException {
29+
ConfigFileReader.parse("src/test/resources/unit_test_no_leading_profile_config");
30+
}
31+
32+
@Test(expected = IllegalStateException.class)
33+
public void lineWithNoValue() throws IOException {
34+
ConfigFileReader.parse("src/test/resources/unit_test_no_value_config");
35+
}
36+
37+
@Test(expected = IllegalStateException.class)
38+
public void lineWithEmptyKey() throws IOException {
39+
ConfigFileReader.parse("src/test/resources/unit_test_empty_key_config");
40+
}
41+
2742
@Test(expected = IllegalArgumentException.class)
2843
public void noProfile() throws IOException {
2944
ConfigFileReader.parse("src/test/resources/unit_test_config", "foobar");
3045
}
3146

47+
@Test(expected = IllegalStateException.class)
48+
public void emptyProfileName() throws IOException {
49+
ConfigFileReader.parse("src/test/resources/unit_test_empty_profile_name_config");
50+
}
51+
3252
@Test
3353
public void defaultProfile() throws IOException {
3454
ConfigFile configFile = ConfigFileReader.parse("src/test/resources/unit_test_config");
35-
assertEquals("default_tenancy", configFile.get("tenancy"));
36-
assertEquals("default_user", configFile.get("user"));
37-
assertEquals("default_fingerprint", configFile.get("fingerprint"));
38-
assertEquals("default_key_file", configFile.get("key_file"));
39-
assertNull(configFile.get("pass_phrase"));
55+
assertEquals("value", configFile.get("key"));
56+
assertEquals("value2", configFile.get("key2"));
57+
assertEquals("value3", configFile.get("key3"));
58+
assertEquals("value4", configFile.get("key4"));
59+
assertEquals("=val=ue=", configFile.get("key5"));
60+
assertEquals("value6", configFile.get("[key6"));
4061
}
4162

4263
@Test
4364
public void overrideProfile() throws IOException {
44-
ConfigFile configFile =
45-
ConfigFileReader.parse("src/test/resources/unit_test_config", "OVERRIDE");
46-
assertEquals("default_tenancy", configFile.get("tenancy"));
47-
assertEquals("default_user", configFile.get("user"));
48-
assertEquals("default_fingerprint", configFile.get("fingerprint"));
49-
assertEquals("override_key_file", configFile.get("key_file"));
50-
assertEquals("override_pass_phrase", configFile.get("pass_phrase"));
65+
ConfigFile profile1 =
66+
ConfigFileReader.parse("src/test/resources/unit_test_config", "PROFILE1");
67+
assertEquals("new value", profile1.get("key"));
68+
assertEquals("value2", profile1.get("key2"));
69+
70+
ConfigFile profile2 =
71+
ConfigFileReader.parse("src/test/resources/unit_test_config", "PROFILE2");
72+
assertEquals("value=foobar", profile2.get("key"));
73+
assertEquals("nota#comment", profile2.get("key2"));
5174
}
5275
}

bmc-common/src/test/java/com/oracle/bmc/waiter/ExponentialBackoffDelayStrategyTest.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/**
2-
* Copyright (c) 2016 Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2016-2017 Oracle and/or its affiliates. All rights reserved.
33
*/
44
package com.oracle.bmc.waiter;
55

@@ -30,12 +30,12 @@ public void getDelays() {
3030
context.incrementAttempts();
3131
assertEquals(30000L, strategy.nextDelay(context));
3232
}
33-
33+
3434
@Test
3535
public void getDelays_overflow() {
3636
ExponentialBackoffDelayStrategy strategy = new ExponentialBackoffDelayStrategy(30000L);
3737
WaitContext context = new WaitContext(System.currentTimeMillis());
38-
for (int attempt=0; attempt < 100; attempt++) {
38+
for (int attempt = 0; attempt < 100; attempt++) {
3939
context.incrementAttempts();
4040
assertTrue(strategy.nextDelay(context) > 0);
4141
assertTrue(strategy.nextDelay(context) <= 30000L);
Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,18 @@
11
[DEFAULT]
2-
tenancy=default_tenancy
3-
user=default_user
4-
fingerprint=default_fingerprint
5-
key_file=default_key_file
6-
7-
[OVERRIDE]
8-
key_file=override_key_file
9-
pass_phrase=override_pass_phrase
2+
key=value
3+
4+
key2= value2
5+
# ignore line
6+
key3 =value3
7+
# ignore line
8+
key4 = value4
9+
key5 ==val=ue=
10+
[key6=value6
11+
12+
[ PROFILE1 ]
13+
key=new value
14+
15+
[PROFILE2 ]
16+
key = value=foobar
17+
key2=nota#comment
18+
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
[DEFAULT]
2+
=foobar
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
[ ]
2+
key=value
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
foo=bar
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
[DEFAULT]
2+
foobar

0 commit comments

Comments
 (0)