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