1+ package edu .hm .hafner .analysis .parser ;
2+
3+ import org .junit .jupiter .api .Test ;
4+
5+ import edu .hm .hafner .analysis .Issue ;
6+ import edu .hm .hafner .analysis .IssueParser ;
7+ import edu .hm .hafner .analysis .Report ;
8+ import edu .hm .hafner .analysis .Severity ;
9+ import edu .hm .hafner .analysis .assertions .SoftAssertions ;
10+ import edu .hm .hafner .analysis .registry .AbstractParserTest ;
11+ import edu .hm .hafner .analysis .registry .ParserRegistry ;
12+ import edu .hm .hafner .analysis .Report .IssueType ;
13+
14+ import static edu .hm .hafner .analysis .assertions .Assertions .*;
15+
16+ /**
17+ * Tests the class {@link OpenScapParser}.
18+ *
19+ * @author Akash Manna
20+ */
21+ class OpenScapParserTest extends AbstractParserTest {
22+ OpenScapParserTest () {
23+ super ("openscap-report.json" );
24+ }
25+
26+ @ Override
27+ protected IssueParser createParser () {
28+ return new OpenScapParser ();
29+ }
30+
31+ @ Override
32+ protected void assertThatIssuesArePresent (final Report report , final SoftAssertions softly ) {
33+ softly .assertThat (report ).hasSize (3 ).hasDuplicatesSize (0 );
34+
35+ softly .assertThat (report .get (0 ))
36+ .hasFileName ("config/login.defs" )
37+ .hasSeverity (Severity .WARNING_HIGH )
38+ .hasType ("xccdf_org.ssgproject.content_rule_accounts_umask_etc_login_defs" )
39+ .hasMessage ("Set Default umask for Users - umask setting is not restrictive enough" )
40+ .hasCategory ("fail" );
41+
42+ softly .assertThat (report .get (0 ).getDescription ())
43+ .contains ("The umask controls the default permissions of newly created files" )
44+ .contains ("Evidence: umask setting is not restrictive enough" );
45+
46+ softly .assertThat (report .get (1 ))
47+ .hasFileName ("config/selinux" )
48+ .hasSeverity (Severity .WARNING_NORMAL )
49+ .hasType ("xccdf_org.ssgproject.content_rule_selinux_policy" )
50+ .hasMessage ("Ensure SELinux Policy is Configured - SELinux is not enabled" )
51+ .hasCategory ("fail" );
52+
53+ softly .assertThat (report .get (1 ).getDescription ())
54+ .contains ("SELinux provides mandatory access control policies" )
55+ .contains ("Evidence: SELinux is not enabled" );
56+
57+ softly .assertThat (report .get (2 ))
58+ .hasFileName ("config/sshd_config" )
59+ .hasSeverity (Severity .ERROR )
60+ .hasType ("xccdf_org.ssgproject.content_rule_ssh_password_authentication" )
61+ .hasMessage ("Disable SSH Password Authentication - PasswordAuthentication is enabled in SSH configuration" )
62+ .hasCategory ("fail" );
63+
64+ softly .assertThat (report .get (2 ).getDescription ())
65+ .contains ("SSH password authentication should be disabled" )
66+ .contains ("Evidence: PasswordAuthentication is enabled in SSH configuration" );
67+ }
68+
69+ @ Test
70+ void shouldParseEdgeCases () {
71+ var report = parse ("openscap-report-edge-cases.json" );
72+
73+ assertThat (report ).hasSize (2 ).hasDuplicatesSize (0 );
74+
75+ assertThat (report .get (0 ))
76+ .hasFileName ("config/firewall" )
77+ .hasSeverity (Severity .WARNING_HIGH )
78+ .hasType ("xccdf_org.ssgproject.content_rule_firewall_enabled" )
79+ .hasMessage ("Firewall Service Enabled" )
80+ .hasCategory ("fail" );
81+
82+ assertThat (report .get (0 ).getDescription ())
83+ .contains ("The firewall service should be enabled to protect the system" );
84+
85+ assertThat (report .get (1 ))
86+ .hasFileName ("config/audit" )
87+ .hasSeverity (Severity .WARNING_NORMAL )
88+ .hasType ("xccdf_org.ssgproject.content_rule_audit_enabled" )
89+ .hasMessage ("Audit Daemon Enabled" )
90+ .hasCategory ("error" );
91+
92+ assertThat (report .get (1 ).getDescription ())
93+ .contains ("The audit daemon should be enabled to log system activities" );
94+ }
95+
96+ @ Test
97+ void shouldNotReportPassResults () {
98+ var report = parse ("openscap-report.json" );
99+ assertThat (report .get ())
100+ .map (Issue ::getCategory )
101+ .doesNotContain ("pass" , "notapplicable" );
102+ }
103+
104+ @ Test
105+ void shouldHandleNullRuleObject () {
106+ var report = parse ("openscap-report-null-handling.json" );
107+
108+ assertThat (report ).hasSize (3 ).hasDuplicatesSize (0 );
109+
110+ assertThat (report .get (0 ))
111+ .hasFileName ("config/test.conf" )
112+ .hasSeverity (Severity .WARNING_HIGH )
113+ .hasType ("-" )
114+ .hasMessage ("Unknown - Test without rule object" )
115+ .hasCategory ("fail" );
116+
117+ assertThat (report .get (1 ))
118+ .hasFileName ("config/test2.conf" )
119+ .hasSeverity (Severity .ERROR )
120+ .hasType ("test-rule-1" )
121+ .hasMessage ("Test Rule With Description" )
122+ .hasCategory ("fail" );
123+
124+ assertThat (report .get (1 ).getDescription ())
125+ .contains ("Detailed description of the issue" );
126+
127+ assertThat (report .get (2 ))
128+ .hasFileName ("config/test3.conf" )
129+ .hasSeverity (Severity .WARNING_LOW )
130+ .hasType ("test-rule-2" )
131+ .hasMessage ("Test Rule Without Description" )
132+ .hasCategory ("error" );
133+ }
134+
135+ @ Test
136+ void shouldCombineEvidenceAndDescription () {
137+ var report = parse ("openscap-report-null-handling.json" );
138+ assertThat (report .get (0 )).hasDescription ("Test without rule object" );
139+ assertThat (report .get (1 )).hasDescription ("Detailed description of the issue" );
140+ }
141+
142+ @ Test
143+ void shouldMapSeverityCorrectly () {
144+ var report = parse ("openscap-report-null-handling.json" );
145+
146+ assertThat (report .get (0 )).hasSeverity (Severity .WARNING_HIGH );
147+ assertThat (report .get (1 )).hasSeverity (Severity .ERROR );
148+ assertThat (report .get (2 )).hasSeverity (Severity .WARNING_LOW );
149+ }
150+
151+ @ Test
152+ void shouldFilterFailAndErrorResults () {
153+ var report = parse ("openscap-report-null-handling.json" );
154+ assertOnlyFailureCategories (report );
155+ }
156+
157+ @ Test
158+ void shouldUseDefaultFileNameWhenMissing () {
159+ var report = parse ("openscap-report-null-handling.json" );
160+ assertThat (report .get ())
161+ .map (Issue ::getFileName )
162+ .allSatisfy (fileName -> assertThat (fileName ).isNotNull ().isNotEmpty ());
163+ }
164+
165+ @ Test
166+ void shouldParseMainReport () {
167+ assertOnlyFailureCategories (parse ("openscap-report.json" ));
168+ }
169+
170+ @ Test
171+ void shouldParseEdgeCaseReport () {
172+ assertOnlyFailureCategories (parse ("openscap-report-edge-cases.json" ));
173+ }
174+
175+ @ Test
176+ void shouldProvideDescriptorMetadata () {
177+ var descriptor = new ParserRegistry ().get ("openscap" );
178+
179+ assertThat (descriptor .getPattern ()).isEqualTo ("**/openscap-report.json" );
180+ assertThat (descriptor .getHelp ()).contains ("oscap scan --results-arf results.xml --report report.html" );
181+ assertThat (descriptor .getUrl ()).isEqualTo ("https://github.com/OpenSCAP/openscap" );
182+ assertThat (descriptor .getIconUrl ()).isEqualTo ("https://github.com/OpenSCAP/openscap/blob/main/docs/manual/images/vertical-logo.png" );
183+ assertThat (descriptor .getType ()).isEqualTo (IssueType .WARNING );
184+ assertThat (descriptor .hasHelp ()).isTrue ();
185+ assertThat (descriptor .hasUrl ()).isTrue ();
186+ }
187+
188+ private void assertOnlyFailureCategories (final Report report ) {
189+ assertThat (report .get ())
190+ .map (Issue ::getCategory )
191+ .allSatisfy (category -> assertThat (category ).isIn ("fail" , "error" ));
192+ }
193+ }
0 commit comments