1+ // / Copyright 2023 Google LLC
2+ // /
3+ // / Licensed under the Apache License, Version 2.0 (the "License");
4+ // / you may not use this file except in compliance with the License.
5+ // / You may obtain a copy of the License at
6+ // /
7+ // / https://www.apache.org/licenses/LICENSE-2.0
8+ // /
9+ // / Unless required by applicable law or agreed to in writing, software
10+ // / distributed under the License is distributed on an "AS IS" BASIS,
11+ // / WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+ // / See the License for the specific language governing permissions and
13+ // / limitations under the License.
14+
15+ #import < Foundation/Foundation.h>
16+ #import < XCTest/XCTest.h>
17+
18+ #include " Source/santad/ProcessTree/annotations/ancestry.h"
19+ #include " Source/santad/ProcessTree/process.h"
20+ #include " Source/santad/ProcessTree/process_tree.pb.h"
21+ #include " Source/santad/ProcessTree/process_tree_test_helpers.h"
22+
23+ using namespace santa ::santad::process_tree;
24+ namespace ptpb = ::santa::pb::v1::process_tree;
25+
26+ @interface AncestryAnnotatorTest : XCTestCase
27+ @property std::shared_ptr<ProcessTreeTestPeer> tree;
28+ @property std::shared_ptr<const Process> initProc;
29+ @end
30+
31+ @implementation AncestryAnnotatorTest
32+
33+ - (void )setUp {
34+ std::vector<std::unique_ptr<Annotator>> annotators;
35+ annotators.emplace_back (std::make_unique<AncestryAnnotator>());
36+ self.tree = std::make_shared<ProcessTreeTestPeer>(std::move (annotators));
37+ self.initProc = self.tree ->InsertInit ();
38+ }
39+
40+ - (void )testSingleFork_childHasAncestryAnnotation {
41+ uint64_t event_id = 123 ;
42+ // PID 1.1: fork() -> PID 2.2
43+ const struct Pid child_pid = {.pid = 2 , .pidversion = 2 };
44+ self.tree ->HandleFork (event_id++, *self.initProc , child_pid);
45+
46+ auto child = *self.tree ->Get (child_pid);
47+ auto annotation_opt = self.tree ->GetAnnotation <AncestryAnnotator>(*child);
48+ XCTAssertTrue (annotation_opt.has_value ());
49+ auto proto_opt = (*annotation_opt)->Proto ();
50+
51+ XCTAssertTrue (proto_opt.has_value ());
52+ XCTAssertEqual (proto_opt->ancestry ().ancestor_size (), 1 );
53+ XCTAssertEqual (proto_opt->ancestry ().ancestor ().Get (0 ).pid (), 1 );
54+ XCTAssertEqual (proto_opt->ancestry ().ancestor ().Get (0 ).secondary_id (), 0 );
55+ }
56+
57+ - (void )testDoubleFork_grandchildHasAncestryAnnotation {
58+ uint64_t event_id = 123 ;
59+ // PID 1.1: fork() -> PID 2.2 fork() -> PID 3.3
60+ const struct Pid child_pid = {.pid = 2 , .pidversion = 2 };
61+ const struct Pid grandchild_pid = {.pid = 3 , .pidversion = 3 };
62+
63+ self.tree ->HandleFork (event_id++, *self.initProc , child_pid);
64+ auto child = *self.tree ->Get (child_pid);
65+ self.tree ->HandleFork (event_id++, *child, grandchild_pid);
66+
67+ auto grandchild = *self.tree ->Get (grandchild_pid);
68+ auto annotation_opt = self.tree ->GetAnnotation <AncestryAnnotator>(*grandchild);
69+ XCTAssertTrue (annotation_opt.has_value ());
70+ auto grandchild_proto_opt = (*annotation_opt)->Proto ();
71+ XCTAssertTrue (grandchild_proto_opt.has_value ());
72+ auto grandchild_proto = *grandchild_proto_opt;
73+ XCTAssertEqual (grandchild_proto.ancestry ().ancestor_size (), 2 );
74+ XCTAssertEqual (grandchild_proto.ancestry ().ancestor ().Get (0 ).pid (), 1 );
75+ XCTAssertEqual (grandchild_proto.ancestry ().ancestor ().Get (0 ).secondary_id (), 0 );
76+ XCTAssertEqual (grandchild_proto.ancestry ().ancestor ().Get (1 ).pid (), 2 );
77+ XCTAssertEqual (grandchild_proto.ancestry ().ancestor ().Get (1 ).secondary_id (), 123 );
78+ }
79+
80+ // - (void)testExec_noEffectOnAncestryAnnotation() {
81+ // uint64_t event_id = 1;
82+
83+ // // PID 1.1: fork() -> PID 2.2
84+ // const struct Pid child_pid = {.pid = 2, .pidversion = 2};
85+ // self.tree->HandleFork(event_id++, *self.initProc, child_pid);
86+ // auto child = *self.tree->Get(child_pid);
87+ // auto annotation_opt = self.tree->GetAnnotation<AncestryAnnotator>(*child);
88+ // XCTAssertTrue(annotation_opt.has_value());
89+ // auto proto_opt = (*annotation_opt)->Proto();
90+
91+ // // PID 2.2: exec("/usr/bin/login") -> PID 2.3
92+ // const struct Pid login_exec_pid = {.pid = 2, .pidversion = 3};
93+ // const struct Program login_prog = {.executable = "/usr/bin/login", .arguments = {}};
94+ // auto login = *self.tree->Get(login_pid);
95+ // self.tree->HandleExec(event_id++, *login, login_exec_pid, login_prog, cred);
96+ // }
97+
98+ @end
0 commit comments