Repository: open-telemetry/opentelemetry-java
File: sdk-extensions/incubator/src/test/java/io/opentelemetry/sdk/extension/incubator/fileconfig/ConfigurationReaderTest.java (Java)

Code before:

  @SuppressWarnings("unchecked")
  private static java.util.stream.Stream<Arguments> envVarSubstitutionArgs() {
    return java.util.stream.Stream.of(
        // Simple cases
        Arguments.of("key1: ${env:VAR_1}", "key1: value1\n", mapOf(entry("key1", "value1"))),
        Arguments.of(
            "key1: ${env:VAR_1}\nkey2: value2\n",
            "key1: value1\nkey2: value2\n",
            mapOf(entry("key1", "value1"), entry("key2", "value2"))),
        Arguments.of(
            "key1: ${env:VAR_1} value1\nkey2: value2\n",
            "key1: value1 value1\nkey2: value2\n",
            mapOf(entry("key1", "value1 value1"), entry("key2", "value2"))),
        // Multiple environment variables referenced
        Arguments.of(
            "key1: ${env:VAR_1}${env:VAR_2}\nkey2: value2\n",
            "key1: value1value2\nkey2: value2\n",
            mapOf(entry("key1", "value1value2"), entry("key2", "value2"))),
        Arguments.of(
            "key1: ${env:VAR_1} ${env:VAR_2}\nkey2: value2\n",
            "key1: value1 value2\nkey2: value2\n",
            mapOf(entry("key1", "value1 value2"), entry("key2", "value2"))),
        // VAR_3 is not defined in environment
        Arguments.of(
            "key1: ${env:VAR_3}\nkey2: value2\n",
            "key1: \nkey2: value2\n",
            mapOf(entry("key1", null), entry("key2", "value2"))),
        Arguments.of(
            "key1: ${env:VAR_1} ${env:VAR_3}\nkey2: value2\n",
            "key1: value1 \nkey2: value2\n",
            mapOf(entry("key1", "value1"), entry("key2", "value2"))),
        // Environment variable keys must match pattern: [a-zA-Z_]+[a-zA-Z0-9_]*
        Arguments.of(
            "key1: ${env:VAR&}\nkey2: value2\n",
            "key1: ${env:VAR&}\nkey2: value2\n",
            mapOf(entry("key1", "${env:VAR&}"), entry("key2", "value2"))));
  }

  private static <K, V> Map.Entry<K, V> entry(K key, @Nullable V value) {
    return new AbstractMap.SimpleEntry<>(key, value);
  }

  @SuppressWarnings("unchecked")
  private static Map<String, Object> mapOf(Map.Entry<String, ?>... entries) {
    Map<String, Object> result = new HashMap<>();
    for (Map.Entry<String, ?> entry : entries) {
      result.put(entry.getKey(), entry.getValue());
    }
    return result;
  }

Review comment (suggestion):
These multi-line yamls that have been collapsed into a single one-line string with `\n` in the middle are a bit hard to read. I think a string concat would read slightly better here.

Code after:
        // Simple cases
        Arguments.of("key1: ${env:STR_1}\n", mapOf(entry("key1", "value1"))),
        Arguments.of("key1: ${env:BOOL}\n", mapOf(entry("key1", true))),
        Arguments.of("key1: ${env:INT}\n", mapOf(entry("key1", 1))),
        Arguments.of("key1: ${env:FLOAT}\n", mapOf(entry("key1", 1.1))),
        Arguments.of(
            "key1: ${env:STR_1}\n" + "key2: value2\n",
            mapOf(entry("key1", "value1"), entry("key2", "value2"))),
        Arguments.of(
            "key1: ${env:STR_1} value1\n" + "key2: value2\n",
            mapOf(entry("key1", "value1 value1"), entry("key2", "value2"))),
        // Multiple environment variables referenced
        Arguments.of("key1: ${env:STR_1}${env:STR_2}\n", mapOf(entry("key1", "value1value2"))),
        Arguments.of("key1: ${env:STR_1} ${env:STR_2}\n", mapOf(entry("key1", "value1 value2"))),
        // Undefined environment variable
        Arguments.of("key1: ${env:STR_3}\n", mapOf(entry("key1", null))),
        Arguments.of("key1: ${env:STR_1} ${env:STR_3}\n", mapOf(entry("key1", "value1"))),
        // Environment variable keys must match pattern: [a-zA-Z_]+[a-zA-Z0-9_]*
        Arguments.of("key1: ${env:VAR&}\n", mapOf(entry("key1", "${env:VAR&}"))),
        // Environment variable substitution only takes place in scalar values of maps
        Arguments.of("${env:STR_1}: value1\n", mapOf(entry("${env:STR_1}", "value1"))),
        Arguments.of(
            "key1:\n  ${env:STR_1}: value1\n",
            mapOf(entry("key1", mapOf(entry("${env:STR_1}", "value1"))))),
        Arguments.of(
            "key1:\n - ${env:STR_1}\n",
            mapOf(entry("key1", Collections.singletonList("${env:STR_1}")))));
  }

  private static <K, V> Map.Entry<K, V> entry(K key, @Nullable V value) {
    return new AbstractMap.SimpleEntry<>(key, value);
  }

  @SuppressWarnings("unchecked")
  private static Map<String, Object> mapOf(Map.Entry<String, ?>... entries) {
    Map<String, Object> result = new HashMap<>();
    for (Map.Entry<String, ?> entry : entries) {
      result.put(entry.getKey(), entry.getValue());
    }
    return result;
  }

  @Test
  void read_WithEnvironmentVariables() {
    String yaml =
        "file_format: \"0.1\"\n"
            + "tracer_provider:\n"
            + "  processors:\n"
            + "    - batch:\n"
            + "        exporter:\n"
            + "          otlp:\n"