diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index ac39ba033..728ce0f30 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -50,7 +50,7 @@ jobs: run: | make test - build-odiglet: + build-and-test-odiglet: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 @@ -63,6 +63,13 @@ jobs: context: . push: false tags: odiglet:pr-${{ github.event.number }} + - name: Install build dependencies + run: | + sudo apt-get update && sudo apt-get install -y clang llvm libbpf-dev + - name: run tests + working-directory: ./odiglet + run: | + make test build-frontend: runs-on: ubuntu-latest steps: diff --git a/odiglet/Makefile b/odiglet/Makefile index f94f921a8..a899b07b2 100644 --- a/odiglet/Makefile +++ b/odiglet/Makefile @@ -10,4 +10,12 @@ generate: go mod download GO_AUTO_PATH=$$(go list -m -f '{{.Dir}}' "go.opentelemetry.io/auto") && \ cd $$GO_AUTO_PATH && \ - make generate \ No newline at end of file + make generate + +test: + go mod download + GO_AUTO_PATH=$$(go list -m -f '{{.Dir}}' "go.opentelemetry.io/auto") && \ + sudo chmod -R +w $$GO_AUTO_PATH && \ + cd $$GO_AUTO_PATH && \ + make generate + go test -v ./... \ No newline at end of file diff --git a/odiglet/pkg/kube/instrumentation_ebpf/pods.go b/odiglet/pkg/kube/instrumentation_ebpf/pods.go index 321cd27ee..4882f62f5 100644 --- a/odiglet/pkg/kube/instrumentation_ebpf/pods.go +++ b/odiglet/pkg/kube/instrumentation_ebpf/pods.go @@ -95,7 +95,7 @@ func (p *PodsReconciler) getPodWorkloadObject(ctx context.Context, pod *corev1.P for _, owner := range pod.OwnerReferences { if owner.Kind == "ReplicaSet" { // ReplicaSet name is in the format - - hyphenIndex := strings.Index(owner.Name, "-") + hyphenIndex := strings.LastIndex(owner.Name, "-") if hyphenIndex == -1 { // It is possible for a user to define a bare ReplicaSet without a deployment, currently not supporting this return nil, errors.New("replicaset name does not contain a hyphen") diff --git a/odiglet/pkg/kube/instrumentation_ebpf/pods_test.go b/odiglet/pkg/kube/instrumentation_ebpf/pods_test.go new file mode 100644 index 000000000..60a30c6d3 --- /dev/null +++ b/odiglet/pkg/kube/instrumentation_ebpf/pods_test.go @@ -0,0 +1,114 @@ +package instrumentation_ebpf + +import ( + "context" + "testing" + + "github.com/odigos-io/odigos/common" + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +func TestGetPodWorkloadObject(t *testing.T) { + pr := &PodsReconciler{} + cases := []struct{ + name string + pod *corev1.Pod + expectedWorkload common.PodWorkload + }{ + { + name: "pod in deployment", + pod: &corev1.Pod{ + ObjectMeta: metav1.ObjectMeta { + OwnerReferences: []metav1.OwnerReference{ + { + Kind: "ReplicaSet", + Name: "deployment-1234", + }, + }, + Namespace: "default", + }, + }, + expectedWorkload: common.PodWorkload{ + Kind: "Deployment", + Name: "deployment", + Namespace: "default", + }, + }, + { + name: "pod with hyphen in name of deployment", + pod: &corev1.Pod{ + ObjectMeta: metav1.ObjectMeta { + OwnerReferences: []metav1.OwnerReference{ + { + Kind: "ReplicaSet", + Name: "deployment-foo-5678", + }, + }, + Namespace: "default", + }, + }, + expectedWorkload: common.PodWorkload{ + Kind: "Deployment", + Name: "deployment-foo", + Namespace: "default", + }, + }, + { + name: "pod in DaemonSet", + pod: &corev1.Pod{ + ObjectMeta: metav1.ObjectMeta { + OwnerReferences: []metav1.OwnerReference{ + { + Kind: "DaemonSet", + Name: "someDaemonSet", + }, + }, + Namespace: "default", + }, + }, + expectedWorkload: common.PodWorkload{ + Kind: "DaemonSet", + Name: "someDaemonSet", + Namespace: "default", + }, + }, + { + name: "pod in StatefulSet", + pod: &corev1.Pod{ + ObjectMeta: metav1.ObjectMeta { + OwnerReferences: []metav1.OwnerReference{ + { + Kind: "StatefulSet", + Name: "someStatefulSet", + }, + }, + Namespace: "default", + }, + }, + expectedWorkload: common.PodWorkload{ + Kind: "StatefulSet", + Name: "someStatefulSet", + Namespace: "default", + }, + }, + } + + for _, c := range cases { + t.Run(c.name, func(t *testing.T) { + workload, err := pr.getPodWorkloadObject(context.Background(), c.pod) + if err != nil { + t.Errorf("unexpected error: %v", err) + } + if workload.Kind != c.expectedWorkload.Kind { + t.Errorf("expected kind %s, got %s", c.expectedWorkload.Kind, workload.Kind) + } + if workload.Name != c.expectedWorkload.Name { + t.Errorf("expected name %s, got %s", c.expectedWorkload.Name, workload.Name) + } + if workload.Namespace != c.expectedWorkload.Namespace { + t.Errorf("expected namespace %s, got %s", c.expectedWorkload.Namespace, workload.Namespace) + } + }) + } +} \ No newline at end of file diff --git a/odiglet/pkg/process/process_other.go b/odiglet/pkg/process/process_other.go new file mode 100644 index 000000000..30bc2b049 --- /dev/null +++ b/odiglet/pkg/process/process_other.go @@ -0,0 +1,17 @@ +//go:build !linux + +package process + +import procdiscovery "github.com/odigos-io/odigos/procdiscovery/pkg/process" + +// These functions are stubs for non-linux platforms to allow running tests on them. + +func isPodContainerPredicate(_ string, _ string) func(string) bool { + return func(procDirName string) bool { + return false + } +} + +func FindAllInContainer(podUID string, containerName string) ([]procdiscovery.Details, error) { + return nil, nil +} \ No newline at end of file