syncable_cli/analyzer/hadolint/rules/
dl3012.rs1use crate::analyzer::hadolint::parser::instruction::Instruction;
6use crate::analyzer::hadolint::rules::{custom_rule, CustomRule, RuleState};
7use crate::analyzer::hadolint::shell::ParsedShell;
8use crate::analyzer::hadolint::types::Severity;
9
10pub fn rule() -> CustomRule<impl Fn(&mut RuleState, u32, &Instruction, Option<&ParsedShell>) + Send + Sync> {
11 custom_rule(
12 "DL3012",
13 Severity::Error,
14 "Multiple `HEALTHCHECK` instructions.",
15 |state, line, instr, _shell| {
16 match instr {
17 Instruction::From(_) => {
18 state.data.set_int("healthcheck_count", 0);
20 }
21 Instruction::Healthcheck(_) => {
22 let count = state.data.get_int("healthcheck_count");
23 if count > 0 {
24 state.add_failure(
25 "DL3012",
26 Severity::Error,
27 "Multiple `HEALTHCHECK` instructions.",
28 line,
29 );
30 }
31 state.data.set_int("healthcheck_count", count + 1);
32 }
33 _ => {}
34 }
35 },
36 )
37}
38
39#[cfg(test)]
40mod tests {
41 use super::*;
42 use crate::analyzer::hadolint::lint::{lint, LintResult};
43 use crate::analyzer::hadolint::config::HadolintConfig;
44
45 fn lint_dockerfile(content: &str) -> LintResult {
46 lint(content, &HadolintConfig::default())
47 }
48
49 #[test]
50 fn test_single_healthcheck() {
51 let result = lint_dockerfile(
52 "FROM ubuntu:20.04\nHEALTHCHECK CMD curl -f http://localhost/ || exit 1"
53 );
54 assert!(!result.failures.iter().any(|f| f.code.as_str() == "DL3012"));
55 }
56
57 #[test]
58 fn test_multiple_healthchecks() {
59 let result = lint_dockerfile(
60 "FROM ubuntu:20.04\nHEALTHCHECK CMD curl http://localhost/\nHEALTHCHECK CMD wget http://localhost/"
61 );
62 assert!(result.failures.iter().any(|f| f.code.as_str() == "DL3012"));
63 }
64
65 #[test]
66 fn test_healthcheck_different_stages() {
67 let result = lint_dockerfile(
68 "FROM ubuntu:20.04 AS builder\nHEALTHCHECK CMD curl http://localhost/\nFROM ubuntu:20.04\nHEALTHCHECK CMD wget http://localhost/"
69 );
70 assert!(!result.failures.iter().any(|f| f.code.as_str() == "DL3012"));
71 }
72
73 #[test]
74 fn test_no_healthcheck() {
75 let result = lint_dockerfile("FROM ubuntu:20.04\nRUN echo hello");
76 assert!(!result.failures.iter().any(|f| f.code.as_str() == "DL3012"));
77 }
78}