content: /*
   * Copyright The OpenTelemetry Authors
   * SPDX-License-Identifier: Apache-2.0
   */
  
  package io.opentelemetry.instrumentation.resources;
  
  import static io.opentelemetry.instrumentation.resources.CgroupV1ContainerIdExtractor.V1_CGROUP_PATH;
  import static org.assertj.core.api.Assertions.assertThat;
  import static org.junit.jupiter.params.provider.Arguments.arguments;
  import static org.mockito.ArgumentMatchers.any;
  import static org.mockito.Mockito.never;
  import static org.mockito.Mockito.verify;
  import static org.mockito.Mockito.when;
  
  import java.io.IOException;
  import java.util.Optional;
  import java.util.stream.Stream;
  import org.junit.jupiter.api.Test;
  import org.junit.jupiter.api.extension.ExtendWith;
  import org.junit.jupiter.params.ParameterizedTest;
  import org.junit.jupiter.params.provider.Arguments;
  import org.junit.jupiter.params.provider.MethodSource;
  import org.junit.jupiter.params.provider.ValueSource;
  import org.mockito.Mock;
  import org.mockito.junit.jupiter.MockitoExtension;
  
  @ExtendWith(MockitoExtension.class)
  class CgroupV1ContainerIdExtractorTest {
  
    @Mock ContainerResource.Filesystem filesystem;
  
    @Test
    void fileNotReadable() throws IOException {
      when(filesystem.isReadable(V1_CGROUP_PATH)).thenReturn(false);
      CgroupV1ContainerIdExtractor extractor = new CgroupV1ContainerIdExtractor(filesystem);
      Optional<String> result = extractor.extractContainerId();
      assertThat(result).isEmpty();
      verify(filesystem, never()).lines(any());
    }
  
    @ParameterizedTest
    @ValueSource(
        strings = {
          // invalid containerId (non-hex)
          "13:name=systemd:/podruntime/docker/kubepods/ac679f8a8319c8cf7d38e1adf263bc08d23zzzz",
          // unrecognized format (last "-" is after last ".")
          "13:name=systemd:/podruntime/docker/kubepods/ac679f8.a8319c8cf7d38e1adf263bc08-d23zzzz"
        })
    void invalidContainerIds(String line) throws IOException {
      when(filesystem.isReadable(V1_CGROUP_PATH)).thenReturn(true);
      when(filesystem.lines(V1_CGROUP_PATH)).thenReturn(Stream.of(line));
  
      CgroupV1ContainerIdExtractor extractor = new CgroupV1ContainerIdExtractor(filesystem);
      Optional<String> result = extractor.extractContainerId();
      assertThat(result).isEmpty();
    }
  
    @ParameterizedTest
    @MethodSource("validLines")
    void validCgroupLines(String line, String expectedContainerId) throws IOException {
      when(filesystem.isReadable(V1_CGROUP_PATH)).thenReturn(true);
      when(filesystem.lines(V1_CGROUP_PATH)).thenReturn(Stream.of(line));
  
      CgroupV1ContainerIdExtractor extractor = new CgroupV1ContainerIdExtractor(filesystem);
      Optional<String> result = extractor.extractContainerId();
      assertThat(result.orElse("fail")).isEqualTo(expectedContainerId);
    }
  
    // See https://github.com/open-telemetry/opentelemetry-java-instrumentation/issues/7437
    @Test
    void hostStyleCgroupFile() throws IOException {
      String line = "1:name=systemd:/user.slice/user-0.slice/session-31207.scope";
      when(filesystem.isReadable(V1_CGROUP_PATH)).thenReturn(true);
      when(filesystem.lines(V1_CGROUP_PATH)).thenReturn(Stream.of(line));
  
      CgroupV1ContainerIdExtractor extractor = new CgroupV1ContainerIdExtractor(filesystem);
      Optional<String> result = extractor.extractContainerId();
      assertThat(result).isEmpty();
    }
  
    static Stream<Arguments> validLines() {
      return Stream.of(
          // with suffix
          arguments(
              "13:name=systemd:/podruntime/docker/kubepods/ac679f8a8319c8cf7d38e1adf263bc08d231f2ff81abda3915f6e8ba4d64156a.aaaa",
              "ac679f8a8319c8cf7d38e1adf263bc08d231f2ff81abda3915f6e8ba4d64156a"),
          // with prefix and suffix
          arguments(
              "13:name=systemd:/podruntime/docker/kubepods/crio-dc679f8a8319c8cf7d38e1adf263bc08d234f0749ea715fb6ca3bb259db69956.stuff",
              "dc679f8a8319c8cf7d38e1adf263bc08d234f0749ea715fb6ca3bb259db69956"),
          // just container id
          arguments(
              "13:name=systemd:/pod/d86d75589bf6cc254f3e2cc29debdf85dde404998aa128997a819ff991827356",
              "d86d75589bf6cc254f3e2cc29debdf85dde404998aa128997a819ff991827356"),
          // with prefix
          arguments(
              "//\n"
                  + "1:name=systemd:/podruntime/docker/kubepods/docker-dc579f8a8319c8cf7d38e1adf263bc08d230600179b07acfd7eaf9646778dc31"
                  + "2:name=systemd:/podruntime/docker/kubepods/docker-dc579f8a8319c8cf7d38e1adf263bc08d230600179b07acfd7eaf9646778dc31"
                  + "3:name=systemd:/podruntime/docker/kubepods/docker-dc579f8a8319c8cf7d38e1adf263bc08d230600179b07acfd7eaf9646778dc31",
              "dc579f8a8319c8cf7d38e1adf263bc08d230600179b07acfd7eaf9646778dc31"),
          // with two dashes in prefix
          arguments(
              "11:perf_event:/kubepods.slice/kubepods-burstable.slice/kubepods-burstable-pod4415fd05_2c0f_4533_909b_f2180dca8d7c.slice/cri-containerd-713a77a26fe2a38ebebd5709604a048c3d380db1eb16aa43aca0b2499e54733c.scope",
              "713a77a26fe2a38ebebd5709604a048c3d380db1eb16aa43aca0b2499e54733c"),
          // with colon, env: k8s v1.24.0, the cgroupDriver by systemd(default), and container is
          // cri-containerd v1.6.8
          arguments(
              "11:devices:/system.slice/containerd.service/kubepods-pod87a18a64_b74a_454a_b10b_a4a36059d0a3.slice:cri-containerd:05c48c82caff3be3d7f1e896981dd410e81487538936914f32b624d168de9db0",
              "05c48c82caff3be3d7f1e896981dd410e81487538936914f32b624d168de9db0"));
    }
  }
  