diff --git a/src/main/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/semanticdata/optionvalues/AiGenerated.kt b/src/main/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/semanticdata/optionvalues/AiGenerated.kt index 0d17110..077d32d 100644 --- a/src/main/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/semanticdata/optionvalues/AiGenerated.kt +++ b/src/main/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/semanticdata/optionvalues/AiGenerated.kt @@ -99,6 +99,7 @@ fun getAllAIGeneratedValidators(): Map { Validator("config_parse_iaid", "AF_INET") to ConfigParseIaidOptionValue() as OptionValueInformation, Validator("config_parse_in_addr_non_null", "AF_INET") to ConfigParseInAddrNonNullOptionValue() as OptionValueInformation, Validator("config_parse_ip_masquerade", "0") to ConfigParseIpMasqueradeOptionValue() as OptionValueInformation, + Validator("config_parse_ip_protocol", "true") to ConfigParseIpProtocolOptionValue() as OptionValueInformation, Validator("config_parse_ip_reverse_path_filter", "0") to ConfigParseIpReversePathFilterOptionValue() as OptionValueInformation, Validator("config_parse_ipoib_mode", "0") to ConfigParseIpoibModeOptionValue() as OptionValueInformation, Validator("config_parse_ipv4_force_igmp_version", "0") to ConfigParseIpv4ForceIgmpVersionOptionValue() as OptionValueInformation, @@ -163,11 +164,13 @@ fun getAllAIGeneratedValidators(): Map { Validator("config_parse_rx_tx_queues", "0") to ConfigParseRxTxQueuesOptionValue() as OptionValueInformation, Validator("config_parse_service_restart_mode", "0") to ConfigParseServiceRestartModeOptionValue() as OptionValueInformation, Validator("config_parse_socket_defer_trigger", "0") to ConfigParseSocketDeferTriggerOptionValue() as OptionValueInformation, + Validator("config_parse_sr_iov_link_state", "0") to ConfigParseSrIovLinkStateOptionValue() as OptionValueInformation, Validator("config_parse_sr_iov_num_vfs", "0") to ConfigParseSrIovNumVfsOptionValue() as OptionValueInformation, Validator("config_parse_sr_iov_vlan_proto", "0") to ConfigParseSrIovVlanProtoOptionValue() as OptionValueInformation, Validator("config_parse_swap_priority", "0") to ConfigParseSwapPriorityOptionValue() as OptionValueInformation, Validator("config_parse_tcp_window", "0") to ConfigParseTcpWindowOptionValue() as OptionValueInformation, Validator("config_parse_timezone_mode", "0") to ConfigParseTimezoneModeOptionValue() as OptionValueInformation, + Validator("config_parse_trigger_unit", "0") to ConfigParseTriggerUnitOptionValue() as OptionValueInformation, Validator("config_parse_tunnel_mode", "0") to ConfigParseTunnelModeOptionValue() as OptionValueInformation, Validator("config_parse_txqueuelen", "0") to ConfigParseTxqueuelenOptionValue() as OptionValueInformation, Validator("config_parse_unit_condition_string", "CONDITION_AC_POWER") to ConfigParseUnitConditionStringOptionValue() as OptionValueInformation, @@ -186,6 +189,38 @@ fun getAllAIGeneratedValidators(): Map { Validator("config_parse_wlan_iftype", "0") to ConfigParseWlanIftypeOptionValue() as OptionValueInformation, Validator("config_parse_ad_actor_system", "0") to ConfigParseAdActorSystemOptionValue() as OptionValueInformation, Validator("config_parse_address_section", "ADDRESS_SCOPE") to ConfigParseAddressSectionAddressScopeOptionValue() as OptionValueInformation, + Validator("config_parse_string", "CONFIG_PARSE_STRING_SAFE") to ConfigParseStringOptionValue() as OptionValueInformation, + Validator("config_parse_bind_user_shell", "0") to ConfigParseBindUserShellOptionValue() as OptionValueInformation, + Validator("config_parse_cake_priority_queueing_preset", "QDISC_KIND_CAKE") to ConfigParseCakePriorityQueueingPresetOptionValue() as OptionValueInformation, + Validator("config_parse_hostname", "0") to ConfigParseHostnameOptionValue() as OptionValueInformation, + Validator("config_parse_device_allow", "0") to ConfigParseDeviceAllowOptionValue() as OptionValueInformation, + Validator("config_parse_ifname", "0") to ConfigParseIfnameOptionValue() as OptionValueInformation, + Validator("config_parse_dns", "0") to ConfigParseDnsOptionValue() as OptionValueInformation, + Validator("config_parse_dns_name", "0") to ConfigParseDnsNameOptionValue() as OptionValueInformation, + Validator("config_parse_wol", "0") to ConfigParseWolOptionValue() as OptionValueInformation, + Validator("config_parse_dnssec_mode", "0") to ConfigParseDnssecModeOptionValue() as OptionValueInformation, + Validator("config_parse_protect_hostname", "0") to ConfigParseProtectHostnameOptionValue() as OptionValueInformation, + Validator("config_parse_ip_tos", "0") to ConfigParseIpTosOptionValue() as OptionValueInformation, + Validator("config_parse_required_family_for_online", "0") to ConfigParseRequiredFamilyForOnlineOptionValue() as OptionValueInformation, + Validator("config_parse_fq_bool", "QDISC_KIND_FQ") to ConfigParseFairQueueingBoolOptionValue() as OptionValueInformation, + Validator("config_parse_fq_size", "QDISC_KIND_FQ") to ConfigParseFairQueueingSizeOptionValue() as OptionValueInformation, + Validator("config_parse_fq_u32", "QDISC_KIND_FQ") to ConfigParseFairQueueingU32OptionValue() as OptionValueInformation, + Validator("config_parse_si_uint64", "0") to ConfigParseSiUint64OptionValue() as OptionValueInformation, + Validator("config_parse_fdb_vlan_id", "0") to ConfigParseFdbVlanIdOptionValue() as OptionValueInformation, + Validator("config_parse_dhcp_socket_priority", "0") to ConfigParseDhcpSocketPriorityOptionValue() as OptionValueInformation, + Validator("config_parse_cake_rtt", "QDISC_KIND_CAKE") to ConfigParseCakeRttOptionValue() as OptionValueInformation, + Validator("config_parse_coalesce_sec", "0") to ConfigParseCoalesceSecOptionValue() as OptionValueInformation, + Validator("config_parse_codel_usec", "QDISC_KIND_CODEL") to ConfigParseControlledDelayUsecOptionValue() as OptionValueInformation, + Validator("config_parse_tbf_latency", "QDISC_KIND_TBF") to ConfigParseTokenBucketFilterLatencyOptionValue() as OptionValueInformation, + Validator("config_parse_service_timeout", "0") to ConfigParseServiceTimeoutOptionValue() as OptionValueInformation, + Validator("config_parse_service_timeout_abort", "0") to ConfigParseServiceTimeoutAbortOptionValue() as OptionValueInformation, + Validator("config_parse_job_running_timeout_sec", "0") to ConfigParseJobRunningTimeoutSecOptionValue() as OptionValueInformation, + Validator("config_parse_exec_secure_bits", "0") to ConfigParseExecSecureBitsOptionValue() as OptionValueInformation, + Validator("config_parse_namespace_flags", "0") to ConfigParseNamespaceFlagsOptionValue() as OptionValueInformation, + Validator("config_parse_can_bitrate", "0") to ConfigParseCanBitrateOptionValue() as OptionValueInformation, + Validator("config_parse_can_time_quanta", "0") to ConfigParseCanTimeQuantaOptionValue() as OptionValueInformation, + Validator("config_parse_fdname", "0") to ConfigParseFdnameOptionValue() as OptionValueInformation, + Validator("config_parse_udev_property_name", "0") to ConfigParseUdevPropertyNameOptionValue() as OptionValueInformation, ) diff --git a/src/main/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/semanticdata/optionvalues/ai/ConfigParseBindUserShellOptionValue.kt b/src/main/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/semanticdata/optionvalues/ai/ConfigParseBindUserShellOptionValue.kt new file mode 100644 index 0000000..4bfafa1 --- /dev/null +++ b/src/main/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/semanticdata/optionvalues/ai/ConfigParseBindUserShellOptionValue.kt @@ -0,0 +1,23 @@ +package net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.ai + +import net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.grammar.* +import net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.SimpleGrammarOptionValues + +/** + * Validator for Files.BindUserShell (.nspawn). + * C Function: config_parse_bind_user_shell(0) + * + * The C path calls parse_user_shell which accepts either: + * - an absolute, normalized path (path_is_absolute && path_is_normalized), or + * - a boolean (parse_boolean) + */ +class ConfigParseBindUserShellOptionValue : SimpleGrammarOptionValues( + "config_parse_bind_user_shell", + SequenceCombinator( + AlternativeCombinator( + BOOLEAN, + RegexTerminal("/[^\\s]+", "/[^\\s]+") + ), + EOF() + ) +) diff --git a/src/main/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/semanticdata/optionvalues/ai/ConfigParseCakePriorityQueueingPresetOptionValue.kt b/src/main/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/semanticdata/optionvalues/ai/ConfigParseCakePriorityQueueingPresetOptionValue.kt new file mode 100644 index 0000000..f21ecf1 --- /dev/null +++ b/src/main/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/semanticdata/optionvalues/ai/ConfigParseCakePriorityQueueingPresetOptionValue.kt @@ -0,0 +1,19 @@ +package net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.ai + +import net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.grammar.* +import net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.SimpleGrammarOptionValues + +/** + * Validator for CAKE.PriorityQueueingPreset (.network). + * C Function: config_parse_cake_priority_queueing_preset(QDISC_KIND_CAKE) + * + * Accepts the 5 entries in cake_priority_queueing_preset_table: + * besteffort, precedence, diffserv3, diffserv4, diffserv8. + */ +class ConfigParseCakePriorityQueueingPresetOptionValue : SimpleGrammarOptionValues( + "config_parse_cake_priority_queueing_preset", + SequenceCombinator( + FlexibleLiteralChoiceTerminal("besteffort", "precedence", "diffserv3", "diffserv4", "diffserv8"), + EOF() + ) +) diff --git a/src/main/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/semanticdata/optionvalues/ai/ConfigParseCakeRttOptionValue.kt b/src/main/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/semanticdata/optionvalues/ai/ConfigParseCakeRttOptionValue.kt new file mode 100644 index 0000000..8459883 --- /dev/null +++ b/src/main/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/semanticdata/optionvalues/ai/ConfigParseCakeRttOptionValue.kt @@ -0,0 +1,16 @@ +package net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.ai + +import net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.grammar.* +import net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.SimpleGrammarOptionValues + +/** + * Validator for CAKE.RTTSec (.network). + * C Function: config_parse_cake_rtt(QDISC_KIND_CAKE) + * + * Calls parse_sec, which accepts "infinity", a fractional or integer number + * with any of systemd's time-unit suffixes, and compound forms like "1h 30s". + */ +class ConfigParseCakeRttOptionValue : SimpleGrammarOptionValues( + "config_parse_cake_rtt", + SequenceCombinator(TIME_VALUE, EOF()) +) diff --git a/src/main/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/semanticdata/optionvalues/ai/ConfigParseCanBitrateOptionValue.kt b/src/main/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/semanticdata/optionvalues/ai/ConfigParseCanBitrateOptionValue.kt new file mode 100644 index 0000000..f4b845f --- /dev/null +++ b/src/main/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/semanticdata/optionvalues/ai/ConfigParseCanBitrateOptionValue.kt @@ -0,0 +1,23 @@ +package net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.ai + +import net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.grammar.* +import net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.SimpleGrammarOptionValues + +/** + * Validator for CAN.BitRate and CAN.DataBitRate. + * C Function: config_parse_can_bitrate(0) in src/network/networkd-can.c. + * + * Internally calls parse_size(rvalue, 1000, &sz). parse_size accepts a decimal + * number (with optional fractional part) optionally suffixed with B/K/M/G/T/P/E. + * The result must fit in a uint32_t; the range check is not enforced here. + */ +class ConfigParseCanBitrateOptionValue : SimpleGrammarOptionValues( + "config_parse_can_bitrate", + SequenceCombinator( + RegexTerminal( + "[0-9]+(?:\\.[0-9]+)?\\s*[BKMGTPE]?", + "[0-9]+(?:\\.[0-9]+)?\\s*[BKMGTPE]?" + ), + EOF() + ) +) diff --git a/src/main/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/semanticdata/optionvalues/ai/ConfigParseCanTimeQuantaOptionValue.kt b/src/main/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/semanticdata/optionvalues/ai/ConfigParseCanTimeQuantaOptionValue.kt new file mode 100644 index 0000000..b914cfc --- /dev/null +++ b/src/main/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/semanticdata/optionvalues/ai/ConfigParseCanTimeQuantaOptionValue.kt @@ -0,0 +1,17 @@ +package net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.ai + +import net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.grammar.* +import net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.SimpleGrammarOptionValues + +/** + * Validator for CAN.TimeQuantaNSec, CAN.DataTimeQuantaNSec. + * C Function: config_parse_can_time_quanta(0) + * + * Per parse_nsec, accepts "infinity", a fractional or integer number with any of + * systemd's time-unit suffixes (default unit: nanoseconds), and compound forms + * like "1ms 500us". + */ +class ConfigParseCanTimeQuantaOptionValue : SimpleGrammarOptionValues( + "config_parse_can_time_quanta", + SequenceCombinator(TIME_VALUE, EOF()) +) diff --git a/src/main/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/semanticdata/optionvalues/ai/ConfigParseCoalesceSecOptionValue.kt b/src/main/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/semanticdata/optionvalues/ai/ConfigParseCoalesceSecOptionValue.kt new file mode 100644 index 0000000..0a8452b --- /dev/null +++ b/src/main/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/semanticdata/optionvalues/ai/ConfigParseCoalesceSecOptionValue.kt @@ -0,0 +1,18 @@ +package net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.ai + +import net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.grammar.* +import net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.SimpleGrammarOptionValues + +/** + * Validator for Link.{RxCoalesceSec, RxCoalesceIrqSec, TxCoalesceSec, TxCoalesceIrqSec, + * StatisticsBlockCoalesceSec, RxCoalesceLowSec, TxCoalesceLowSec, + * RxCoalesceHighSec, TxCoalesceHighSec, CoalescePacketRateSampleIntervalSec}. + * C Function: config_parse_coalesce_sec(0) + * + * Calls parse_sec, which accepts "infinity", a fractional or integer number with any + * of systemd's time-unit suffixes, and compound forms like "1h 30s". + */ +class ConfigParseCoalesceSecOptionValue : SimpleGrammarOptionValues( + "config_parse_coalesce_sec", + SequenceCombinator(TIME_VALUE, EOF()) +) diff --git a/src/main/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/semanticdata/optionvalues/ai/ConfigParseControlledDelayUsecOptionValue.kt b/src/main/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/semanticdata/optionvalues/ai/ConfigParseControlledDelayUsecOptionValue.kt new file mode 100644 index 0000000..91ddf84 --- /dev/null +++ b/src/main/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/semanticdata/optionvalues/ai/ConfigParseControlledDelayUsecOptionValue.kt @@ -0,0 +1,16 @@ +package net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.ai + +import net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.grammar.* +import net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.SimpleGrammarOptionValues + +/** + * Validator for ControlledDelay.TargetSec, ControlledDelay.IntervalSec, ControlledDelay.CEThresholdSec + * C Function: config_parse_codel_usec(QDISC_KIND_CODEL) + * + * Calls parse_sec, which accepts "infinity", a fractional or integer number with any + * of systemd's time-unit suffixes, and compound forms like "1h 30s". + */ +class ConfigParseControlledDelayUsecOptionValue : SimpleGrammarOptionValues( + "config_parse_codel_usec", + SequenceCombinator(TIME_VALUE, EOF()) +) diff --git a/src/main/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/semanticdata/optionvalues/ai/ConfigParseDeviceAllowOptionValue.kt b/src/main/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/semanticdata/optionvalues/ai/ConfigParseDeviceAllowOptionValue.kt new file mode 100644 index 0000000..e117c01 --- /dev/null +++ b/src/main/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/semanticdata/optionvalues/ai/ConfigParseDeviceAllowOptionValue.kt @@ -0,0 +1,29 @@ +package net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.ai + +import net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.grammar.* +import net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.SimpleGrammarOptionValues + +/** + * Validator for {Service,Socket,Mount,Swap,Slice,Scope}.DeviceAllow. + * C Function: config_parse_device_allow(0) + * + * Per valid_device_allow_pattern + cgroup_device_permissions_from_string: + * - device specifier is either a /dev/... path or a block-/char- prefixed device class + * - optional whitespace + permissions, where permissions is a single token of [rwm]+ + */ +class ConfigParseDeviceAllowOptionValue : SimpleGrammarOptionValues( + "config_parse_device_allow", + SequenceCombinator( + AlternativeCombinator( + RegexTerminal("(block-|char-)\\S+", "(block-|char-)\\S+"), + RegexTerminal("/dev/\\S+", "/dev/\\S+") + ), + ZeroOrOne( + SequenceCombinator( + WhitespaceTerminal(), + RegexTerminal("[rwm]+", "[rwm]+") + ) + ), + EOF() + ) +) diff --git a/src/main/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/semanticdata/optionvalues/ai/ConfigParseDhcpSocketPriorityOptionValue.kt b/src/main/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/semanticdata/optionvalues/ai/ConfigParseDhcpSocketPriorityOptionValue.kt new file mode 100644 index 0000000..b89a472 --- /dev/null +++ b/src/main/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/semanticdata/optionvalues/ai/ConfigParseDhcpSocketPriorityOptionValue.kt @@ -0,0 +1,21 @@ +package net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.ai + +import net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.grammar.* +import net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.SimpleGrammarOptionValues + +/** + * Validator for DHCPv4.SocketPriority + * C Function: config_parse_dhcp_socket_priority(0) + * Used by Options: DHCPv4.SocketPriority + * + * The C implementation uses safe_atoi() with no range restriction beyond what fits in a + * signed 32-bit int. SO_PRIORITY values 0..6 are typical, but the parser itself accepts + * any signed int. Empty values are allowed (clears the setting) and so are skipped here. + */ +class ConfigParseDhcpSocketPriorityOptionValue : SimpleGrammarOptionValues( + "config_parse_dhcp_socket_priority", + SequenceCombinator( + IntegerTerminal(Int.MIN_VALUE.toLong(), Int.MAX_VALUE.toLong() + 1L), + EOF() + ) +) diff --git a/src/main/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/semanticdata/optionvalues/ai/ConfigParseDnsNameOptionValue.kt b/src/main/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/semanticdata/optionvalues/ai/ConfigParseDnsNameOptionValue.kt new file mode 100644 index 0000000..41a1ea2 --- /dev/null +++ b/src/main/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/semanticdata/optionvalues/ai/ConfigParseDnsNameOptionValue.kt @@ -0,0 +1,30 @@ +package net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.ai + +import net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.SimpleGrammarOptionValues +import net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.grammar.EOF +import net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.grammar.RegexTerminal +import net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.grammar.SequenceCombinator + +/** + * Validator for config_parse_dns_name(0). + * + * Used by .network DHCPServer.Domain, DHCPServer.BootServerName, DHCPServer.LocalLeaseDomain. + * + * Mirrors dns_name_is_valid (no DNS_LABEL_LDH flag): each label is a non-empty + * sequence of any characters except '.' (label separator) and '\' (escape + * introducer); labels are joined by single dots; an optional trailing dot + * denotes a fully-qualified name. Empty labels (e.g. ".." or a leading ".") + * are rejected. This is intentionally far more permissive than hostname + * validation — leading/trailing hyphens, underscores, spaces, and most + * printable punctuation are all accepted by the C validator. + */ +class ConfigParseDnsNameOptionValue : SimpleGrammarOptionValues( + "config_parse_dns_name", + SequenceCombinator( + RegexTerminal( + "[^.\\\\\\p{Cntrl}]+(?:\\.[^.\\\\\\p{Cntrl}]+)*\\.?", + "[^.\\\\\\p{Cntrl}]+(?:\\.[^.\\\\\\p{Cntrl}]+)*\\.?" + ), + EOF() + ) +) diff --git a/src/main/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/semanticdata/optionvalues/ai/ConfigParseDnsOptionValue.kt b/src/main/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/semanticdata/optionvalues/ai/ConfigParseDnsOptionValue.kt new file mode 100644 index 0000000..9b6d732 --- /dev/null +++ b/src/main/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/semanticdata/optionvalues/ai/ConfigParseDnsOptionValue.kt @@ -0,0 +1,59 @@ +package net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.ai + +import net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.SimpleGrammarOptionValues +import net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.grammar.AlternativeCombinator +import net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.grammar.EOF +import net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.grammar.IPV4_ADDR +import net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.grammar.IPV6_ADDR +import net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.grammar.IntegerTerminal +import net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.grammar.LiteralChoiceTerminal +import net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.grammar.RegexTerminal +import net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.grammar.SequenceCombinator +import net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.grammar.WhitespaceTerminal +import net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.grammar.ZeroOrMore +import net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.grammar.ZeroOrOne + +private val DNS_PORT = IntegerTerminal(0, 65536) +private val DNS_IFACE = RegexTerminal("[A-Za-z0-9_][A-Za-z0-9_.-]*", "[A-Za-z0-9_][A-Za-z0-9_.-]*") +private val DNS_IFACE_SUFFIX = SequenceCombinator(LiteralChoiceTerminal("%"), DNS_IFACE) + +private val DNS_IPV4_ENTRY = SequenceCombinator( + IPV4_ADDR, + ZeroOrOne(SequenceCombinator(LiteralChoiceTerminal(":"), DNS_PORT)), + ZeroOrOne(DNS_IFACE_SUFFIX) +) +private val DNS_IPV6_BRACKETED_ENTRY = SequenceCombinator( + LiteralChoiceTerminal("["), + IPV6_ADDR, + LiteralChoiceTerminal("]"), + ZeroOrOne(SequenceCombinator(LiteralChoiceTerminal(":"), DNS_PORT)), + ZeroOrOne(DNS_IFACE_SUFFIX) +) +private val DNS_IPV6_BARE_ENTRY = SequenceCombinator( + IPV6_ADDR, + ZeroOrOne(DNS_IFACE_SUFFIX) +) +private val DNS_ENTRY = AlternativeCombinator( + DNS_IPV6_BRACKETED_ENTRY, + DNS_IPV4_ENTRY, + DNS_IPV6_BARE_ENTRY +) + +/** + * Validator for Network.DNS (.network). + * + * C Function: config_parse_dns(0) + * + * Accepts a whitespace-separated list of DNS server addresses. Each entry is an IPv4 + * or IPv6 address. IPv4 addresses may optionally include a port suffix (":port") and + * an interface suffix ("%iface"). IPv6 addresses can be bare, or bracketed with a port + * ("[ipv6]:port") and may also have an interface suffix. + */ +class ConfigParseDnsOptionValue : SimpleGrammarOptionValues( + "config_parse_dns", + SequenceCombinator( + DNS_ENTRY, + ZeroOrMore(SequenceCombinator(WhitespaceTerminal(), DNS_ENTRY)), + EOF() + ) +) diff --git a/src/main/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/semanticdata/optionvalues/ai/ConfigParseDnssecModeOptionValue.kt b/src/main/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/semanticdata/optionvalues/ai/ConfigParseDnssecModeOptionValue.kt new file mode 100644 index 0000000..bdf2011 --- /dev/null +++ b/src/main/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/semanticdata/optionvalues/ai/ConfigParseDnssecModeOptionValue.kt @@ -0,0 +1,27 @@ +package net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.ai + +import net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.SimpleGrammarOptionValues +import net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.grammar.AlternativeCombinator +import net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.grammar.BOOLEAN +import net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.grammar.EOF +import net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.grammar.FlexibleLiteralChoiceTerminal +import net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.grammar.SequenceCombinator + +/** + * Validator for Network.DNSSEC (.network) and Resolve.DNSSEC (.conf via resolved.conf). + * + * C Function: config_parse_dnssec_mode(0) + * + * Backed by DEFINE_STRING_TABLE_LOOKUP_WITH_BOOLEAN(dnssec_mode, ...), so accepts + * any boolean value as well as the explicit table entries: "no", "allow-downgrade", "yes". + */ +class ConfigParseDnssecModeOptionValue : SimpleGrammarOptionValues( + "config_parse_dnssec_mode", + SequenceCombinator( + AlternativeCombinator( + FlexibleLiteralChoiceTerminal("allow-downgrade"), + BOOLEAN + ), + EOF() + ) +) diff --git a/src/main/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/semanticdata/optionvalues/ai/ConfigParseExecSecureBitsOptionValue.kt b/src/main/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/semanticdata/optionvalues/ai/ConfigParseExecSecureBitsOptionValue.kt new file mode 100644 index 0000000..67353ac --- /dev/null +++ b/src/main/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/semanticdata/optionvalues/ai/ConfigParseExecSecureBitsOptionValue.kt @@ -0,0 +1,35 @@ +package net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.ai + +import net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.SimpleGrammarOptionValues +import net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.grammar.EOF +import net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.grammar.FlexibleLiteralChoiceTerminal +import net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.grammar.SequenceCombinator +import net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.grammar.WhitespaceTerminal +import net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.grammar.ZeroOrMore + +private val SECURE_BIT = FlexibleLiteralChoiceTerminal( + "keep-caps", + "keep-caps-locked", + "no-setuid-fixup", + "no-setuid-fixup-locked", + "noroot", + "noroot-locked" +) + +/** + * Validator for Service.SecureBits, Socket.SecureBits, Mount.SecureBits, Swap.SecureBits. + * + * C Function: config_parse_exec_secure_bits(0) + * + * Accepts a whitespace-separated list of secure bits flags. Valid values are: + * keep-caps, keep-caps-locked, no-setuid-fixup, no-setuid-fixup-locked, + * noroot, noroot-locked. + */ +class ConfigParseExecSecureBitsOptionValue : SimpleGrammarOptionValues( + "config_parse_exec_secure_bits", + SequenceCombinator( + SECURE_BIT, + ZeroOrMore(SequenceCombinator(WhitespaceTerminal(), SECURE_BIT)), + EOF() + ) +) diff --git a/src/main/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/semanticdata/optionvalues/ai/ConfigParseFairQueueingBoolOptionValue.kt b/src/main/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/semanticdata/optionvalues/ai/ConfigParseFairQueueingBoolOptionValue.kt new file mode 100644 index 0000000..70b20ba --- /dev/null +++ b/src/main/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/semanticdata/optionvalues/ai/ConfigParseFairQueueingBoolOptionValue.kt @@ -0,0 +1,21 @@ +package net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.ai + +import net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.grammar.* +import net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.SimpleGrammarOptionValues + +/** + * Validator for FairQueueing.Pacing (.network) + * C function: config_parse_fq_bool + * + * The C implementation calls parse_tristate(rvalue, &fq->pacing). Since the + * "third" argument is NULL, an empty string sets the value to -1 (auto) and + * any other value is parsed via parse_boolean (yes/y/true/t/on/1 or no/n/false/f/off/0). + * Empty values are handled by the framework, so we only validate boolean. + */ +class ConfigParseFairQueueingBoolOptionValue : SimpleGrammarOptionValues( + "config_parse_fq_bool", + SequenceCombinator( + BOOLEAN, + EOF() + ) +) diff --git a/src/main/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/semanticdata/optionvalues/ai/ConfigParseFairQueueingSizeOptionValue.kt b/src/main/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/semanticdata/optionvalues/ai/ConfigParseFairQueueingSizeOptionValue.kt new file mode 100644 index 0000000..f176bcd --- /dev/null +++ b/src/main/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/semanticdata/optionvalues/ai/ConfigParseFairQueueingSizeOptionValue.kt @@ -0,0 +1,20 @@ +package net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.ai + +import net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.SimpleGrammarOptionValues +import net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.grammar.* + +/** + * Validator for FairQueueing.QuantumBytes, FairQueueing.InitialQuantumBytes (and the deprecated + * Quantum / InitialQuantum aliases). + * + * C function: config_parse_fq_size (QDISC_KIND_FQ) in src/network/tc/fq.c. Internally calls + * parse_size(rvalue, 1024, &sz), so the value is a decimal byte count optionally suffixed with + * an IEC unit (B, K, M, G, T, P, E). Hexadecimal and octal forms are not accepted. + */ +class ConfigParseFairQueueingSizeOptionValue : SimpleGrammarOptionValues( + "config_parse_fq_size", + SequenceCombinator( + OptionalWhitespacePrefix(BYTES), + EOF() + ) +) diff --git a/src/main/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/semanticdata/optionvalues/ai/ConfigParseFairQueueingU32OptionValue.kt b/src/main/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/semanticdata/optionvalues/ai/ConfigParseFairQueueingU32OptionValue.kt new file mode 100644 index 0000000..1d91db5 --- /dev/null +++ b/src/main/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/semanticdata/optionvalues/ai/ConfigParseFairQueueingU32OptionValue.kt @@ -0,0 +1,17 @@ +package net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.ai + +import net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.SimpleGrammarOptionValues +import net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.grammar.EOF +import net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.grammar.IntegerTerminal +import net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.grammar.SequenceCombinator + +/** + * Validator for FairQueueing keys parsed by config_parse_fq_u32 (QDISC_KIND_FQ). + * C Function: config_parse_fq_u32 - parses a uint32_t via safe_atou32. + * Used by Options: FairQueueing.PacketLimit, FairQueueing.FlowLimit, + * FairQueueing.Buckets, FairQueueing.OrphanMask. + */ +class ConfigParseFairQueueingU32OptionValue : SimpleGrammarOptionValues( + "config_parse_fq_u32", + SequenceCombinator(IntegerTerminal(0L, 4_294_967_296L), EOF()) +) diff --git a/src/main/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/semanticdata/optionvalues/ai/ConfigParseFdbVlanIdOptionValue.kt b/src/main/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/semanticdata/optionvalues/ai/ConfigParseFdbVlanIdOptionValue.kt new file mode 100644 index 0000000..6b525e9 --- /dev/null +++ b/src/main/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/semanticdata/optionvalues/ai/ConfigParseFdbVlanIdOptionValue.kt @@ -0,0 +1,22 @@ +package net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.ai + +import net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.SimpleGrammarOptionValues +import net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.grammar.EOF +import net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.grammar.IntegerTerminal +import net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.grammar.SequenceCombinator + +/** + * Validator for BridgeFDB.VLANId + * C Function: config_parse_fdb_vlan_id(0) + * Used by Options: BridgeFDB.VLANId + * + * Delegates to config_parse_vlanid which accepts a uint16 in the inclusive range + * 0..VLANID_MAX (4094). + */ +class ConfigParseFdbVlanIdOptionValue : SimpleGrammarOptionValues( + "config_parse_fdb_vlan_id", + SequenceCombinator( + IntegerTerminal(0, 4095), // Range 0-4094 inclusive (max is exclusive) + EOF() + ) +) diff --git a/src/main/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/semanticdata/optionvalues/ai/ConfigParseFdnameOptionValue.kt b/src/main/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/semanticdata/optionvalues/ai/ConfigParseFdnameOptionValue.kt new file mode 100644 index 0000000..5174560 --- /dev/null +++ b/src/main/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/semanticdata/optionvalues/ai/ConfigParseFdnameOptionValue.kt @@ -0,0 +1,22 @@ +package net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.ai + +import net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.grammar.* +import net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.SimpleGrammarOptionValues + +/** + * Validator for config_parse_fdname(0). + * Used by Options: Socket.FileDescriptorName. + * + * Mirrors fdname_is_valid: + * - Printable ASCII only: bytes >= 0x20 (space) and < 0x7F (DEL). + * - The ':' character (0x3A) is reserved as a separator in $LISTEN_FDNAMES and is forbidden. + * - Maximum length is 255 characters (FDNAME_MAX). The empty string is handled by the + * caller (it clears the value) and is not validated here. + */ +class ConfigParseFdnameOptionValue : SimpleGrammarOptionValues( + "config_parse_fdname", + SequenceCombinator( + RegexTerminal("[ -9;-~]{1,255}", "[ -9;-~]{1,255}"), + EOF() + ) +) diff --git a/src/main/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/semanticdata/optionvalues/ai/ConfigParseHostnameOptionValue.kt b/src/main/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/semanticdata/optionvalues/ai/ConfigParseHostnameOptionValue.kt new file mode 100644 index 0000000..58a7e7a --- /dev/null +++ b/src/main/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/semanticdata/optionvalues/ai/ConfigParseHostnameOptionValue.kt @@ -0,0 +1,25 @@ +package net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.ai + +import net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.grammar.* +import net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.SimpleGrammarOptionValues + +/** + * Validator for config_parse_hostname(0). + * Used by Options: Exec.Hostname (.nspawn), DHCPv4.Hostname, DHCPv6.Hostname, DHCP.Hostname (.network). + * + * Mirrors hostname_is_valid(s, 0): + * - LDH chars only (letters, digits, hyphen) + * - dots between labels, no leading or consecutive dots + * - no leading or trailing hyphen on a label + * - no trailing dot (VALID_HOSTNAME_TRAILING_DOT not set) + */ +class ConfigParseHostnameOptionValue : SimpleGrammarOptionValues( + "config_parse_hostname", + SequenceCombinator( + RegexTerminal( + "[a-zA-Z0-9](?:[a-zA-Z0-9-]*[a-zA-Z0-9])?(?:\\.[a-zA-Z0-9](?:[a-zA-Z0-9-]*[a-zA-Z0-9])?)*", + "[a-zA-Z0-9](?:[a-zA-Z0-9-]*[a-zA-Z0-9])?(?:\\.[a-zA-Z0-9](?:[a-zA-Z0-9-]*[a-zA-Z0-9])?)*" + ), + EOF() + ) +) diff --git a/src/main/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/semanticdata/optionvalues/ai/ConfigParseIfnameOptionValue.kt b/src/main/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/semanticdata/optionvalues/ai/ConfigParseIfnameOptionValue.kt new file mode 100644 index 0000000..4953504 --- /dev/null +++ b/src/main/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/semanticdata/optionvalues/ai/ConfigParseIfnameOptionValue.kt @@ -0,0 +1,27 @@ +package net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.ai + +import net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.grammar.* +import net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.SimpleGrammarOptionValues + +/** + * Validator for keys parsed by config_parse_ifname (e.g. Network.Bridge, Network.Bond, + * Network.VRF, Network.BatmanAdvanced in .network; NetDev.Name, Peer.Name, VXCAN.Peer in + * .netdev; Link.Name in .link; Network.Bridge in .nspawn). + * + * Delegates to ifname_valid, which requires a Linux interface name: + * - 1..15 characters + * - no whitespace, no '/', no ':', no '%' (rejected by ifname_valid_char) + * - cannot be "." or ".." + * - cannot be the reserved names "all" or "default" + * - cannot be a purely-numeric string (interpreted as ifindex) + */ +class ConfigParseIfnameOptionValue : SimpleGrammarOptionValues( + "config_parse_ifname", + SequenceCombinator( + RegexTerminal( + "(?!(?:all|default|\\.{1,2}|0[xX][0-9a-fA-F]+|[0-9]+)\\Z)[^\\s:/%]{1,15}", + "(?!(?:all|default|\\.{1,2}|0[xX][0-9a-fA-F]+|[0-9]+)\\Z)[^\\s:/%]{1,15}" + ), + EOF() + ) +) diff --git a/src/main/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/semanticdata/optionvalues/ai/ConfigParseIpProtocolOptionValue.kt b/src/main/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/semanticdata/optionvalues/ai/ConfigParseIpProtocolOptionValue.kt new file mode 100644 index 0000000..27521ff --- /dev/null +++ b/src/main/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/semanticdata/optionvalues/ai/ConfigParseIpProtocolOptionValue.kt @@ -0,0 +1,25 @@ +package net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.ai + +import net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.Validator +import net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.grammar.* +import net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.SimpleGrammarOptionValues + +/** + * Validator for FooOverUDP.Protocol + * C Function: config_parse_ip_protocol(true) + * Used by Options: FooOverUDP.Protocol + * + * Accepts an IP protocol name from /etc/protocols (e.g. tcp, udp, icmp) or an integer 0..255. + * The list of protocol names below is intentionally conservative; rare names will produce a + * (false-positive) warning, which is acceptable. + */ +class ConfigParseIpProtocolOptionValue : SimpleGrammarOptionValues( + "config_parse_ip_protocol", + SequenceCombinator( + AlternativeCombinator( + FlexibleLiteralChoiceTerminal("tcp", "udp", "icmp", "icmpv6", "sctp", "udplite", "dccp"), + IntegerTerminal(0, 256) + ), + EOF() + ) +) diff --git a/src/main/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/semanticdata/optionvalues/ai/ConfigParseIpTosOptionValue.kt b/src/main/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/semanticdata/optionvalues/ai/ConfigParseIpTosOptionValue.kt new file mode 100644 index 0000000..dc657b0 --- /dev/null +++ b/src/main/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/semanticdata/optionvalues/ai/ConfigParseIpTosOptionValue.kt @@ -0,0 +1,23 @@ +package net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.ai + +import net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.grammar.* +import net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.SimpleGrammarOptionValues + +/** + * Validator for Socket.IPTOS + * C Function: config_parse_ip_tos(0) + * + * Accepts a symbolic name (low-delay, throughput, reliability, low-cost) or a + * raw integer in the range 0..255 (ip_tos_from_string falls back to safe_atou + * with max 0xff). + */ +class ConfigParseIpTosOptionValue : SimpleGrammarOptionValues( + "config_parse_ip_tos", + SequenceCombinator( + AlternativeCombinator( + FlexibleLiteralChoiceTerminal("low-delay", "throughput", "reliability", "low-cost"), + IntegerTerminal(0, 256) + ), + EOF() + ) +) diff --git a/src/main/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/semanticdata/optionvalues/ai/ConfigParseJobRunningTimeoutSecOptionValue.kt b/src/main/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/semanticdata/optionvalues/ai/ConfigParseJobRunningTimeoutSecOptionValue.kt new file mode 100644 index 0000000..f41d1df --- /dev/null +++ b/src/main/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/semanticdata/optionvalues/ai/ConfigParseJobRunningTimeoutSecOptionValue.kt @@ -0,0 +1,17 @@ +package net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.ai + +import net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.grammar.* +import net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.SimpleGrammarOptionValues + +/** + * Validator for Unit.JobRunningTimeoutSec + * C Function: config_parse_job_running_timeout_sec + * + * Parses a time value via parse_sec_fix_0 -> parse_sec, which accepts "infinity", + * a fractional or integer number with any of systemd's time-unit suffixes, and + * compound forms like "1h 30s". + */ +class ConfigParseJobRunningTimeoutSecOptionValue : SimpleGrammarOptionValues( + "config_parse_job_running_timeout_sec", + SequenceCombinator(TIME_VALUE, EOF()) +) diff --git a/src/main/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/semanticdata/optionvalues/ai/ConfigParseNamespaceFlagsOptionValue.kt b/src/main/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/semanticdata/optionvalues/ai/ConfigParseNamespaceFlagsOptionValue.kt new file mode 100644 index 0000000..f0fc9cc --- /dev/null +++ b/src/main/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/semanticdata/optionvalues/ai/ConfigParseNamespaceFlagsOptionValue.kt @@ -0,0 +1,51 @@ +package net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.ai + +import net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.SimpleGrammarOptionValues +import net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.grammar.AlternativeCombinator +import net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.grammar.BOOLEAN +import net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.grammar.EOF +import net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.grammar.FlexibleLiteralChoiceTerminal +import net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.grammar.LiteralChoiceTerminal +import net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.grammar.SequenceCombinator +import net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.grammar.WhitespaceTerminal +import net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.grammar.ZeroOrMore +import net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.grammar.ZeroOrOne + +private val NAMESPACE_TYPE = FlexibleLiteralChoiceTerminal( + "cgroup", + "ipc", + "net", + "mnt", + "pid", + "user", + "uts", + "time" +) + +private val NAMESPACE_LIST = SequenceCombinator( + ZeroOrOne(LiteralChoiceTerminal("~")), + NAMESPACE_TYPE, + ZeroOrMore(SequenceCombinator(WhitespaceTerminal(), NAMESPACE_TYPE)) +) + +/** + * Validator for Service.RestrictNamespaces, Service.DelegateNamespaces, Socket.RestrictNamespaces, + * Socket.DelegateNamespaces, Mount.RestrictNamespaces, Mount.DelegateNamespaces, Swap.RestrictNamespaces, + * Swap.DelegateNamespaces. + * + * C Function: config_parse_namespace_flags(0) + * + * Accepts either a boolean (yes/no/on/off/...) or a whitespace-separated list of namespace types, + * optionally preceded by '~' to invert the meaning. Valid namespace types are: cgroup, ipc, net, + * mnt, pid, user, uts, time. + */ +class ConfigParseNamespaceFlagsOptionValue : SimpleGrammarOptionValues( + "config_parse_namespace_flags", + SequenceCombinator( + AlternativeCombinator( + NAMESPACE_LIST, + BOOLEAN + ), + EOF() + ) +) diff --git a/src/main/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/semanticdata/optionvalues/ai/ConfigParseProtectHostnameOptionValue.kt b/src/main/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/semanticdata/optionvalues/ai/ConfigParseProtectHostnameOptionValue.kt new file mode 100644 index 0000000..9534edf --- /dev/null +++ b/src/main/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/semanticdata/optionvalues/ai/ConfigParseProtectHostnameOptionValue.kt @@ -0,0 +1,56 @@ +package net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.ai + +import net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.SimpleGrammarOptionValues +import net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.grammar.* + +/** + * Validator for Service.ProtectHostname (also Socket/Mount/Swap.ProtectHostname). + * C Function: config_parse_protect_hostname(0) + * + * Accepts either: + * - a boolean (yes/no/y/n/true/false/t/f/1/0/on/off) or "private" + * - ":" where is a "true" boolean (yes/y/true/t/1/on) + * or "private", and matches hostname_is_valid (LDH chars; labels + * joined by '.' with no leading/trailing hyphens). + * + * The C code rejects "no:" (and other false synonyms with a hostname). + */ +class ConfigParseProtectHostnameOptionValue : SimpleGrammarOptionValues( + "config_parse_protect_hostname", + SequenceCombinator( + AlternativeCombinator( + // Form: : + SequenceCombinator( + BOOLEAN_TRUE_OR_PRIVATE, + COLON_LITERAL, + HOSTNAME + ), + // Form: standalone keyword (any boolean or "private") + BOOLEAN_OR_PRIVATE + ), + EOF() + ) +) { + companion object { + private val COLON_LITERAL = LiteralChoiceTerminal(":") + + // Boolean true synonyms plus "private" (used when a hostname is supplied). + private val BOOLEAN_TRUE_OR_PRIVATE = FlexibleLiteralChoiceTerminal( + "yes", "y", "true", "t", "on", "1", "private" + ) + + // Any boolean (true or false synonyms) plus "private". + private val BOOLEAN_OR_PRIVATE = FlexibleLiteralChoiceTerminal( + "1", "yes", "y", "true", "t", "on", + "0", "no", "n", "false", "f", "off", + "private" + ) + + // Hostname: one or more LDH labels separated by '.'. Each label starts and + // ends with [A-Za-z0-9] and may contain hyphens internally. + private val HOSTNAME = RegexTerminal( + "[A-Za-z0-9]([A-Za-z0-9-]*[A-Za-z0-9])?(\\.[A-Za-z0-9]([A-Za-z0-9-]*[A-Za-z0-9])?)*", + "[A-Za-z0-9]([A-Za-z0-9-]*[A-Za-z0-9])?(\\.[A-Za-z0-9]([A-Za-z0-9-]*[A-Za-z0-9])?)*" + ) + } +} diff --git a/src/main/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/semanticdata/optionvalues/ai/ConfigParseRequiredFamilyForOnlineOptionValue.kt b/src/main/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/semanticdata/optionvalues/ai/ConfigParseRequiredFamilyForOnlineOptionValue.kt new file mode 100644 index 0000000..80494dc --- /dev/null +++ b/src/main/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/semanticdata/optionvalues/ai/ConfigParseRequiredFamilyForOnlineOptionValue.kt @@ -0,0 +1,15 @@ +package net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.ai + +import net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.grammar.* +import net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.SimpleGrammarOptionValues + +/** + * Validator for Link.RequiredFamilyForOnline (.network) + */ +class ConfigParseRequiredFamilyForOnlineOptionValue : SimpleGrammarOptionValues( + "config_parse_required_family_for_online", + SequenceCombinator( + FlexibleLiteralChoiceTerminal("ipv4", "ipv6", "both", "any"), + EOF() + ) +) diff --git a/src/main/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/semanticdata/optionvalues/ai/ConfigParseServiceTimeoutAbortOptionValue.kt b/src/main/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/semanticdata/optionvalues/ai/ConfigParseServiceTimeoutAbortOptionValue.kt new file mode 100644 index 0000000..907a59c --- /dev/null +++ b/src/main/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/semanticdata/optionvalues/ai/ConfigParseServiceTimeoutAbortOptionValue.kt @@ -0,0 +1,17 @@ +package net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.ai + +import net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.SimpleGrammarOptionValues +import net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.grammar.* + +/** + * Validator for Service.TimeoutAbortSec. + * C Function: config_parse_service_timeout_abort(0) + * + * Delegates to config_parse_timeout_abort, which calls parse_sec — accepts + * "infinity", a fractional or integer number with any of systemd's time-unit + * suffixes, and compound forms like "1h 30s". + */ +class ConfigParseServiceTimeoutAbortOptionValue : SimpleGrammarOptionValues( + "config_parse_service_timeout_abort", + SequenceCombinator(TIME_VALUE, EOF()) +) diff --git a/src/main/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/semanticdata/optionvalues/ai/ConfigParseServiceTimeoutOptionValue.kt b/src/main/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/semanticdata/optionvalues/ai/ConfigParseServiceTimeoutOptionValue.kt new file mode 100644 index 0000000..b961d7b --- /dev/null +++ b/src/main/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/semanticdata/optionvalues/ai/ConfigParseServiceTimeoutOptionValue.kt @@ -0,0 +1,17 @@ +package net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.ai + +import net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.grammar.* +import net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.SimpleGrammarOptionValues + +/** + * Validator for Service.TimeoutSec, Service.TimeoutStartSec. + * C Function: config_parse_service_timeout(0) + * + * Calls parse_sec_fix_0 -> parse_sec, which accepts "infinity", a fractional or + * integer number with any of systemd's time-unit suffixes, and compound forms + * like "1min 30s". + */ +class ConfigParseServiceTimeoutOptionValue : SimpleGrammarOptionValues( + "config_parse_service_timeout", + SequenceCombinator(TIME_VALUE, EOF()) +) diff --git a/src/main/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/semanticdata/optionvalues/ai/ConfigParseSiUint64OptionValue.kt b/src/main/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/semanticdata/optionvalues/ai/ConfigParseSiUint64OptionValue.kt new file mode 100644 index 0000000..a13cb6b --- /dev/null +++ b/src/main/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/semanticdata/optionvalues/ai/ConfigParseSiUint64OptionValue.kt @@ -0,0 +1,23 @@ +package net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.ai + +import net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.SimpleGrammarOptionValues +import net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.grammar.* + +/** + * Validator for Link.BitsPerSecond. + * + * C function: config_parse_si_uint64 in src/shared/conf-parser.c. Internally calls + * parse_size(rvalue, 1000, &sz), so the value is an unsigned decimal optionally followed by + * a case-sensitive SI suffix (K, M, G, T, P, E or B) — base 1000, not 1024. Negative values + * and lowercase suffixes (e.g. "1k") are rejected. Decimal fractions (e.g. "1.5G") are + * accepted by parse_size. + */ +class ConfigParseSiUint64OptionValue : SimpleGrammarOptionValues( + "config_parse_si_uint64", + SequenceCombinator( + OptionalWhitespacePrefix( + RegexTerminal("[0-9]+(\\.[0-9]+)?[a-zA-Z]?\\s*", "[0-9]+(\\.[0-9]+)?[KMGTPEB]?\\s*") + ), + EOF() + ) +) diff --git a/src/main/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/semanticdata/optionvalues/ai/ConfigParseSrIovLinkStateOptionValue.kt b/src/main/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/semanticdata/optionvalues/ai/ConfigParseSrIovLinkStateOptionValue.kt new file mode 100644 index 0000000..7251d65 --- /dev/null +++ b/src/main/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/semanticdata/optionvalues/ai/ConfigParseSrIovLinkStateOptionValue.kt @@ -0,0 +1,27 @@ +package net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.ai + +import net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.SimpleGrammarOptionValues +import net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.grammar.AlternativeCombinator +import net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.grammar.BOOLEAN +import net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.grammar.EOF +import net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.grammar.FlexibleLiteralChoiceTerminal +import net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.grammar.SequenceCombinator + +/** + * Validator for SR-IOV.LinkState in .network and .link files. + * + * C Function: config_parse_sr_iov_link_state(0) + * + * Accepts the literal "auto", or any boolean value (which is parsed via parse_boolean + * and mapped to SR_IOV_LINK_STATE_ENABLE / SR_IOV_LINK_STATE_DISABLE). + */ +class ConfigParseSrIovLinkStateOptionValue : SimpleGrammarOptionValues( + "config_parse_sr_iov_link_state", + SequenceCombinator( + AlternativeCombinator( + BOOLEAN, + FlexibleLiteralChoiceTerminal("auto") + ), + EOF() + ) +) diff --git a/src/main/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/semanticdata/optionvalues/ai/ConfigParseStringOptionValue.kt b/src/main/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/semanticdata/optionvalues/ai/ConfigParseStringOptionValue.kt new file mode 100644 index 0000000..def5919 --- /dev/null +++ b/src/main/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/semanticdata/optionvalues/ai/ConfigParseStringOptionValue.kt @@ -0,0 +1,24 @@ +package net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.ai + +import net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.grammar.* +import net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.SimpleGrammarOptionValues + +/** + * Validator for config_parse_string with CONFIG_PARSE_STRING_SAFE. + * Used by Options: Tun.User, Tun.Group, Tap.User, Tap.Group, Exec.User (nspawn), + * DHCPv4.VendorClassIdentifier, *.NetLabel, Manager.RuntimeWatchdogPreGovernor, ... + * + * The C path is config_parse_string -> string_is_safe(rvalue, STRING_ALLOW_GLOBS): + * - rejects control characters (0..31, 127) + * - rejects backslash + * - rejects quotes (" and ') + * - allows globs (*, ?, [) + * - empty resets and is always valid (handled outside the grammar) + */ +class ConfigParseStringOptionValue : SimpleGrammarOptionValues( + "config_parse_string", + SequenceCombinator( + RegexTerminal("[^\\x00-\\x1F\\x7F\"'\\\\]+", "[^\\x00-\\x1F\\x7F\"'\\\\]+"), + EOF() + ) +) diff --git a/src/main/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/semanticdata/optionvalues/ai/ConfigParseTokenBucketFilterLatencyOptionValue.kt b/src/main/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/semanticdata/optionvalues/ai/ConfigParseTokenBucketFilterLatencyOptionValue.kt new file mode 100644 index 0000000..b43f936 --- /dev/null +++ b/src/main/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/semanticdata/optionvalues/ai/ConfigParseTokenBucketFilterLatencyOptionValue.kt @@ -0,0 +1,16 @@ +package net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.ai + +import net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.grammar.* +import net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.SimpleGrammarOptionValues + +/** + * Validator for TokenBucketFilter.LatencySec + * C Function: config_parse_tbf_latency (QDISC_KIND_TBF) + * + * Calls parse_sec, which accepts "infinity", a fractional or integer number with any + * of systemd's time-unit suffixes, and compound forms like "1h 30s". + */ +class ConfigParseTokenBucketFilterLatencyOptionValue : SimpleGrammarOptionValues( + "config_parse_tbf_latency", + SequenceCombinator(TIME_VALUE, EOF()) +) diff --git a/src/main/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/semanticdata/optionvalues/ai/ConfigParseTriggerUnitOptionValue.kt b/src/main/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/semanticdata/optionvalues/ai/ConfigParseTriggerUnitOptionValue.kt new file mode 100644 index 0000000..8ba6e20 --- /dev/null +++ b/src/main/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/semanticdata/optionvalues/ai/ConfigParseTriggerUnitOptionValue.kt @@ -0,0 +1,26 @@ +package net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.ai + +import net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.grammar.* +import net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.SimpleGrammarOptionValues + +/** + * Validator for [Path] Unit= and [Timer] Unit=. + * C function: config_parse_trigger_unit (src/core/load-fragment.c) + * + * The C path resolves specifiers in rvalue, then requires the result to be a + * valid systemd unit name (unit_name_to_type must succeed). A unit name is + * . where the body characters are letters, digits, '-', '_', '@', + * ':', and '.', and is one of the recognised unit type extensions. + * + * Used by .path (Path.Unit) and .timer (Timer.Unit) units. + */ +class ConfigParseTriggerUnitOptionValue : SimpleGrammarOptionValues( + "config_parse_trigger_unit", + SequenceCombinator( + RegexTerminal( + "[A-Za-z0-9_:.@-]+\\.(service|socket|target|device|mount|automount|timer|swap|path|slice|scope)", + "[A-Za-z0-9_:.@-]+\\.(service|socket|target|device|mount|automount|timer|swap|path|slice|scope)" + ), + EOF() + ) +) diff --git a/src/main/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/semanticdata/optionvalues/ai/ConfigParseUdevPropertyNameOptionValue.kt b/src/main/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/semanticdata/optionvalues/ai/ConfigParseUdevPropertyNameOptionValue.kt new file mode 100644 index 0000000..c1dea29 --- /dev/null +++ b/src/main/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/semanticdata/optionvalues/ai/ConfigParseUdevPropertyNameOptionValue.kt @@ -0,0 +1,28 @@ +package net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.ai + +import net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.SimpleGrammarOptionValues +import net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.grammar.* + +/** + * Validator for Link.ImportProperty and Link.UnsetProperty + * C Function: config_parse_udev_property_name(0) + * + * A whitespace-separated list of udev property names. A udev property name is + * validated by udev_property_name_is_valid which delegates to env_name_is_valid: + * - non-empty + * - first character must not be a digit + * - all characters must be ASCII letters, digits, or underscore + */ +class ConfigParseUdevPropertyNameOptionValue : SimpleGrammarOptionValues( + "config_parse_udev_property_name", + SequenceCombinator( + RegexTerminal("[A-Za-z_][A-Za-z0-9_]*", "[A-Za-z_][A-Za-z0-9_]*"), + ZeroOrMore( + SequenceCombinator( + WhitespaceTerminal(), + RegexTerminal("[A-Za-z_][A-Za-z0-9_]*", "[A-Za-z_][A-Za-z0-9_]*") + ) + ), + EOF() + ) +) diff --git a/src/main/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/semanticdata/optionvalues/ai/ConfigParseWolOptionValue.kt b/src/main/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/semanticdata/optionvalues/ai/ConfigParseWolOptionValue.kt new file mode 100644 index 0000000..b5b9e43 --- /dev/null +++ b/src/main/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/semanticdata/optionvalues/ai/ConfigParseWolOptionValue.kt @@ -0,0 +1,32 @@ +package net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.ai + +import net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.grammar.* +import net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.SimpleGrammarOptionValues + +/** + * Validator for Link.WakeOnLan (.link). + * C Function: config_parse_wol(0) + * + * Source: src/shared/ethtool-util.c — config_parse_wol() and the wol_option_map[] table. + * Accepts either the standalone literal "off", or one or more whitespace-separated + * Wake-on-LAN flags from the set: phy, unicast, multicast, broadcast, arp, magic, secureon. + * (Empty value resets the field — handled separately by the inspection framework.) + */ +class ConfigParseWolOptionValue : SimpleGrammarOptionValues( + "config_parse_wol", + SequenceCombinator( + AlternativeCombinator( + LiteralChoiceTerminal("off"), + SequenceCombinator( + LiteralChoiceTerminal("phy", "unicast", "multicast", "broadcast", "arp", "magic", "secureon"), + ZeroOrMore( + SequenceCombinator( + WhitespaceTerminal(), + LiteralChoiceTerminal("phy", "unicast", "multicast", "broadcast", "arp", "magic", "secureon") + ) + ) + ) + ), + EOF() + ) +) diff --git a/src/main/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/semanticdata/optionvalues/grammar/Combinators.kt b/src/main/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/semanticdata/optionvalues/grammar/Combinators.kt index 5bf6141..825f0c2 100644 --- a/src/main/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/semanticdata/optionvalues/grammar/Combinators.kt +++ b/src/main/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/semanticdata/optionvalues/grammar/Combinators.kt @@ -5,6 +5,17 @@ val BYTES = RegexTerminal("[0-9]+[a-zA-Z]*\\s*", "[0-9]+[KMGT]?\\s*") val DEVICE = RegexTerminal("\\S+\\s*", "/[^\\u0000. ]+\\s*") val IOPS = RegexTerminal("[0-9]+[a-zA-Z]*\\s*", "[0-9]+[KMGT]?\\s*") +// Time-suffix list mirrors systemd's extract_multiplier (parse_sec, parse_nsec). +// Longer alternatives MUST come first so that `min` is tried before `m`, etc. +private const val TIME_SUFFIX = "(?:seconds|minutes|months|second|minute|month|years|weeks|hours|usec|msec|nsec|year|week|hour|days|min|sec|day|hr|µs|μs|ns|us|ms|s|m|h|d|w|y|M)" +private const val TIME_NUMBER = "[0-9]+(?:\\.[0-9]+)?" +private const val TIME_ELEMENT = "$TIME_NUMBER\\s*$TIME_SUFFIX?" +private const val TIME_COMPOUND = "$TIME_ELEMENT(?:\\s+$TIME_ELEMENT)*" +val TIME_VALUE = AlternativeCombinator( + FlexibleLiteralChoiceTerminal("infinity"), + RegexTerminal(TIME_COMPOUND, TIME_COMPOUND) +) + var IPV4_OCTET = IntegerTerminal(0, 256) val DOT = LiteralChoiceTerminal(".") var IPV4_ADDR = SequenceCombinator(IPV4_OCTET, DOT, IPV4_OCTET, DOT, IPV4_OCTET, DOT, IPV4_OCTET) diff --git a/src/test/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/inspections/ai/ConfigParseBindUserShellOptionValueTest.kt b/src/test/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/inspections/ai/ConfigParseBindUserShellOptionValueTest.kt new file mode 100644 index 0000000..e9b147f --- /dev/null +++ b/src/test/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/inspections/ai/ConfigParseBindUserShellOptionValueTest.kt @@ -0,0 +1,61 @@ +package net.sjrx.intellij.plugins.systemdunitfiles.inspections.ai + +import net.sjrx.intellij.plugins.systemdunitfiles.AbstractUnitFileTest +import net.sjrx.intellij.plugins.systemdunitfiles.inspections.InvalidValueInspection +import org.junit.Test + +class ConfigParseBindUserShellOptionValueTest : AbstractUnitFileTest() { + + @Test + fun testValidBooleans() { + // language="unit file (systemd)" + val file = """ + [Files] + BindUserShell=yes + BindUserShell=no + BindUserShell=true + BindUserShell=false + BindUserShell=on + BindUserShell=off + BindUserShell=1 + BindUserShell=0 + """.trimIndent() + + setupFileInEditor("file.nspawn", file) + enableInspection(InvalidValueInspection::class.java) + val highlights = myFixture.doHighlighting() + assertSize(0, highlights) + } + + @Test + fun testValidAbsolutePaths() { + // language="unit file (systemd)" + val file = """ + [Files] + BindUserShell=/bin/sh + BindUserShell=/usr/bin/zsh + BindUserShell=/bin/bash + """.trimIndent() + + setupFileInEditor("file.nspawn", file) + enableInspection(InvalidValueInspection::class.java) + val highlights = myFixture.doHighlighting() + assertSize(0, highlights) + } + + @Test + fun testInvalidValues() { + // language="unit file (systemd)" + val file = """ + [Files] + BindUserShell=invalid + BindUserShell=relative/path + BindUserShell=bin/sh + """.trimIndent() + + setupFileInEditor("file.nspawn", file) + enableInspection(InvalidValueInspection::class.java) + val highlights = myFixture.doHighlighting() + assertSize(3, highlights) + } +} diff --git a/src/test/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/inspections/ai/ConfigParseCakePriorityQueueingPresetOptionValueTest.kt b/src/test/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/inspections/ai/ConfigParseCakePriorityQueueingPresetOptionValueTest.kt new file mode 100644 index 0000000..a68dbe3 --- /dev/null +++ b/src/test/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/inspections/ai/ConfigParseCakePriorityQueueingPresetOptionValueTest.kt @@ -0,0 +1,42 @@ +package net.sjrx.intellij.plugins.systemdunitfiles.inspections.ai + +import net.sjrx.intellij.plugins.systemdunitfiles.AbstractUnitFileTest +import net.sjrx.intellij.plugins.systemdunitfiles.inspections.InvalidValueInspection +import org.junit.Test + +class ConfigParseCakePriorityQueueingPresetOptionValueTest : AbstractUnitFileTest() { + + @Test + fun testValidValues() { + // language="unit file (systemd)" + val file = """ + [CAKE] + PriorityQueueingPreset=besteffort + PriorityQueueingPreset=precedence + PriorityQueueingPreset=diffserv3 + PriorityQueueingPreset=diffserv4 + PriorityQueueingPreset=diffserv8 + """.trimIndent() + + setupFileInEditor("file.network", file) + enableInspection(InvalidValueInspection::class.java) + val highlights = myFixture.doHighlighting() + assertSize(0, highlights) + } + + @Test + fun testInvalidValues() { + // language="unit file (systemd)" + val file = """ + [CAKE] + PriorityQueueingPreset=diffserv5 + PriorityQueueingPreset=invalid + PriorityQueueingPreset=diffserv + """.trimIndent() + + setupFileInEditor("file.network", file) + enableInspection(InvalidValueInspection::class.java) + val highlights = myFixture.doHighlighting() + assertSize(3, highlights) + } +} diff --git a/src/test/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/inspections/ai/ConfigParseCakeRttOptionValueTest.kt b/src/test/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/inspections/ai/ConfigParseCakeRttOptionValueTest.kt new file mode 100644 index 0000000..22e9c76 --- /dev/null +++ b/src/test/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/inspections/ai/ConfigParseCakeRttOptionValueTest.kt @@ -0,0 +1,42 @@ +package net.sjrx.intellij.plugins.systemdunitfiles.inspections.ai + +import net.sjrx.intellij.plugins.systemdunitfiles.AbstractUnitFileTest +import net.sjrx.intellij.plugins.systemdunitfiles.inspections.InvalidValueInspection +import org.junit.Test + +class ConfigParseCakeRttOptionValueTest : AbstractUnitFileTest() { + + @Test + fun testValidValues() { + // language="unit file (systemd)" + val file = """ + [CAKE] + RTTSec=100ms + RTTSec=1s + RTTSec=100us + RTTSec=5m + RTTSec=200 + RTTSec=10.5s + RTTSec=infinity + RTTSec=2hour + """.trimIndent() + + setupFileInEditor("file.network", file) + enableInspection(InvalidValueInspection::class.java) + assertSize(0, myFixture.doHighlighting()) + } + + @Test + fun testInvalidValues() { + // language="unit file (systemd)" + val file = """ + [CAKE] + RTTSec=abc + RTTSec=-1 + """.trimIndent() + + setupFileInEditor("file.network", file) + enableInspection(InvalidValueInspection::class.java) + assertSize(2, myFixture.doHighlighting()) + } +} diff --git a/src/test/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/inspections/ai/ConfigParseCanBitrateOptionValueTest.kt b/src/test/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/inspections/ai/ConfigParseCanBitrateOptionValueTest.kt new file mode 100644 index 0000000..e8ba2b2 --- /dev/null +++ b/src/test/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/inspections/ai/ConfigParseCanBitrateOptionValueTest.kt @@ -0,0 +1,43 @@ +package net.sjrx.intellij.plugins.systemdunitfiles.inspections.ai + +import net.sjrx.intellij.plugins.systemdunitfiles.AbstractUnitFileTest +import net.sjrx.intellij.plugins.systemdunitfiles.inspections.InvalidValueInspection +import org.junit.Test + +class ConfigParseCanBitrateOptionValueTest : AbstractUnitFileTest() { + + @Test + fun testValidValues() { + // language="unit file (systemd)" + val file = """ + [CAN] + BitRate=100 + BitRate=1000000 + BitRate=500K + BitRate=1M + DataBitRate=2M + DataBitRate=125000 + BitRate=1.5M + DataBitRate=1G + BitRate=42B + """.trimIndent() + + setupFileInEditor("file.network", file) + enableInspection(InvalidValueInspection::class.java) + assertSize(0, myFixture.doHighlighting()) + } + + @Test + fun testInvalidValues() { + // language="unit file (systemd)" + val file = """ + [CAN] + BitRate=abc + DataBitRate=foo + """.trimIndent() + + setupFileInEditor("file.network", file) + enableInspection(InvalidValueInspection::class.java) + assertSize(2, myFixture.doHighlighting()) + } +} diff --git a/src/test/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/inspections/ai/ConfigParseCanTimeQuantaOptionValueTest.kt b/src/test/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/inspections/ai/ConfigParseCanTimeQuantaOptionValueTest.kt new file mode 100644 index 0000000..54141ae --- /dev/null +++ b/src/test/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/inspections/ai/ConfigParseCanTimeQuantaOptionValueTest.kt @@ -0,0 +1,41 @@ +package net.sjrx.intellij.plugins.systemdunitfiles.inspections.ai + +import net.sjrx.intellij.plugins.systemdunitfiles.AbstractUnitFileTest +import net.sjrx.intellij.plugins.systemdunitfiles.inspections.InvalidValueInspection +import org.junit.Test + +class ConfigParseCanTimeQuantaOptionValueTest : AbstractUnitFileTest() { + + @Test + fun testValidValues() { + // language="unit file (systemd)" + val file = """ + [CAN] + TimeQuantaNSec=100 + TimeQuantaNSec=500ns + TimeQuantaNSec=1us + TimeQuantaNSec=1ms + DataTimeQuantaNSec=infinity + DataTimeQuantaNSec=1ms 500us + DataTimeQuantaNSec=10.5ms + """.trimIndent() + + setupFileInEditor("file.network", file) + enableInspection(InvalidValueInspection::class.java) + assertSize(0, myFixture.doHighlighting()) + } + + @Test + fun testInvalidValues() { + // language="unit file (systemd)" + val file = """ + [CAN] + TimeQuantaNSec=invalid + TimeQuantaNSec=-10ns + """.trimIndent() + + setupFileInEditor("file.network", file) + enableInspection(InvalidValueInspection::class.java) + assertSize(2, myFixture.doHighlighting()) + } +} diff --git a/src/test/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/inspections/ai/ConfigParseCoalesceSecOptionValueTest.kt b/src/test/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/inspections/ai/ConfigParseCoalesceSecOptionValueTest.kt new file mode 100644 index 0000000..cdcec36 --- /dev/null +++ b/src/test/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/inspections/ai/ConfigParseCoalesceSecOptionValueTest.kt @@ -0,0 +1,49 @@ +package net.sjrx.intellij.plugins.systemdunitfiles.inspections.ai + +import net.sjrx.intellij.plugins.systemdunitfiles.AbstractUnitFileTest +import net.sjrx.intellij.plugins.systemdunitfiles.inspections.InvalidValueInspection +import org.junit.Test + +class ConfigParseCoalesceSecOptionValueTest : AbstractUnitFileTest() { + + @Test + fun testValidValues() { + // language="unit file (systemd)" + val file = """ + [Link] + RxCoalesceSec=0 + RxCoalesceIrqSec=1 + TxCoalesceSec=60 + TxCoalesceIrqSec=500ms + StatisticsBlockCoalesceSec=2s + RxCoalesceLowSec=10us + TxCoalesceLowSec=100µs + RxCoalesceHighSec=1m + TxCoalesceHighSec=1h + CoalescePacketRateSampleIntervalSec=1 + RxCoalesceSec=1.5s + TxCoalesceSec=1min 30sec + RxCoalesceSec=infinity + TxCoalesceSec=2hour + """.trimIndent() + + setupFileInEditor("file.link", file) + enableInspection(InvalidValueInspection::class.java) + assertSize(0, myFixture.doHighlighting()) + } + + @Test + fun testInvalidValues() { + // language="unit file (systemd)" + val file = """ + [Link] + RxCoalesceSec=-1 + TxCoalesceSec=abc + TxCoalesceIrqSec=5z + """.trimIndent() + + setupFileInEditor("file.link", file) + enableInspection(InvalidValueInspection::class.java) + assertSize(3, myFixture.doHighlighting()) + } +} diff --git a/src/test/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/inspections/ai/ConfigParseControlledDelayUsecOptionValueTest.kt b/src/test/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/inspections/ai/ConfigParseControlledDelayUsecOptionValueTest.kt new file mode 100644 index 0000000..ee0af9e --- /dev/null +++ b/src/test/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/inspections/ai/ConfigParseControlledDelayUsecOptionValueTest.kt @@ -0,0 +1,43 @@ +package net.sjrx.intellij.plugins.systemdunitfiles.inspections.ai + +import net.sjrx.intellij.plugins.systemdunitfiles.AbstractUnitFileTest +import net.sjrx.intellij.plugins.systemdunitfiles.inspections.InvalidValueInspection +import org.junit.Test + +class ConfigParseControlledDelayUsecOptionValueTest : AbstractUnitFileTest() { + + @Test + fun testValidValues() { + // language="unit file (systemd)" + val file = """ + [ControlledDelay] + TargetSec=10s + IntervalSec=100ms + CEThresholdSec=5 + TargetSec=1m + IntervalSec=2h + CEThresholdSec=500us + TargetSec=10.5s + IntervalSec=infinity + CEThresholdSec=1min 30s + """.trimIndent() + + setupFileInEditor("file.network", file) + enableInspection(InvalidValueInspection::class.java) + assertSize(0, myFixture.doHighlighting()) + } + + @Test + fun testInvalidValues() { + // language="unit file (systemd)" + val file = """ + [ControlledDelay] + TargetSec=invalid + IntervalSec=-10s + """.trimIndent() + + setupFileInEditor("file.network", file) + enableInspection(InvalidValueInspection::class.java) + assertSize(2, myFixture.doHighlighting()) + } +} diff --git a/src/test/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/inspections/ai/ConfigParseDeviceAllowOptionValueTest.kt b/src/test/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/inspections/ai/ConfigParseDeviceAllowOptionValueTest.kt new file mode 100644 index 0000000..d757f55 --- /dev/null +++ b/src/test/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/inspections/ai/ConfigParseDeviceAllowOptionValueTest.kt @@ -0,0 +1,46 @@ +package net.sjrx.intellij.plugins.systemdunitfiles.inspections.ai + +import net.sjrx.intellij.plugins.systemdunitfiles.AbstractUnitFileTest +import net.sjrx.intellij.plugins.systemdunitfiles.inspections.InvalidValueInspection +import org.junit.Test + +class ConfigParseDeviceAllowOptionValueTest : AbstractUnitFileTest() { + + @Test + fun testValidValues() { + // language="unit file (systemd)" + val file = """ + [Service] + DeviceAllow=/dev/sda1 + DeviceAllow=/dev/sda1 r + DeviceAllow=/dev/sda1 rw + DeviceAllow=/dev/sda1 rwm + DeviceAllow=/dev/dri/card0 rw + DeviceAllow=block-loop + DeviceAllow=block-loop rw + DeviceAllow=char-rtc r + """.trimIndent() + + setupFileInEditor("file.service", file) + enableInspection(InvalidValueInspection::class.java) + val highlights = myFixture.doHighlighting() + assertSize(0, highlights) + } + + @Test + fun testInvalidValues() { + // language="unit file (systemd)" + val file = """ + [Service] + DeviceAllow=relative-path + DeviceAllow=/dev/sda1 x + DeviceAllow=/dev/sda1 rwx + DeviceAllow=block-loop xyz + """.trimIndent() + + setupFileInEditor("file.service", file) + enableInspection(InvalidValueInspection::class.java) + val highlights = myFixture.doHighlighting() + assertSize(4, highlights) + } +} diff --git a/src/test/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/inspections/ai/ConfigParseDhcpSocketPriorityOptionValueTest.kt b/src/test/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/inspections/ai/ConfigParseDhcpSocketPriorityOptionValueTest.kt new file mode 100644 index 0000000..35dc952 --- /dev/null +++ b/src/test/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/inspections/ai/ConfigParseDhcpSocketPriorityOptionValueTest.kt @@ -0,0 +1,52 @@ +package net.sjrx.intellij.plugins.systemdunitfiles.inspections.ai + +import net.sjrx.intellij.plugins.systemdunitfiles.AbstractUnitFileTest +import net.sjrx.intellij.plugins.systemdunitfiles.inspections.InvalidValueInspection +import org.junit.Test + +class ConfigParseDhcpSocketPriorityOptionValueTest : AbstractUnitFileTest() { + + @Test + fun testValidValues() { + // Fixture Setup + // language="unit file (systemd)" + val file = """ + [DHCPv4] + SocketPriority=0 + SocketPriority=6 + SocketPriority=-1 + SocketPriority=2147483647 + SocketPriority=-2147483648 + """.trimIndent() + + // Execute SUT + setupFileInEditor("file.network", file) + enableInspection(InvalidValueInspection::class.java) + val highlights = myFixture.doHighlighting() + + // Verification + assertSize(0, highlights) + } + + @Test + fun testInvalidValues() { + // Fixture Setup + // language="unit file (systemd)" + val file = """ + [DHCPv4] + SocketPriority=forever + SocketPriority=infinity + SocketPriority=abc + SocketPriority=1.5 + SocketPriority=2147483648 + """.trimIndent() + + // Execute SUT + setupFileInEditor("file.network", file) + enableInspection(InvalidValueInspection::class.java) + val highlights = myFixture.doHighlighting() + + // Verification + assertSize(5, highlights) + } +} diff --git a/src/test/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/inspections/ai/ConfigParseDnsNameOptionValueTest.kt b/src/test/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/inspections/ai/ConfigParseDnsNameOptionValueTest.kt new file mode 100644 index 0000000..617f541 --- /dev/null +++ b/src/test/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/inspections/ai/ConfigParseDnsNameOptionValueTest.kt @@ -0,0 +1,49 @@ +package net.sjrx.intellij.plugins.systemdunitfiles.inspections.ai + +import net.sjrx.intellij.plugins.systemdunitfiles.AbstractUnitFileTest +import net.sjrx.intellij.plugins.systemdunitfiles.inspections.InvalidValueInspection +import org.junit.Test + +class ConfigParseDnsNameOptionValueTest : AbstractUnitFileTest() { + + @Test + fun testValidDnsNames() { + // language="unit file (systemd)" + val file = """ + [DHCPServer] + BootServerName=valid-hostname.example.com + BootServerName=valid.hostname + BootServerName=single + BootServerName=name_with_underscore + BootServerName=mixed_chars-123.example.com + BootServerName=trailing.dot. + BootServerName=-leading.hyphen + BootServerName=trailing-.com + BootServerName=has!bang + Domain=example.org + LocalLeaseDomain=lan.local + """.trimIndent() + + setupFileInEditor("file.network", file) + enableInspection(InvalidValueInspection::class.java) + val highlights = myFixture.doHighlighting() + + assertSize(0, highlights) + } + + @Test + fun testInvalidDnsNames() { + // language="unit file (systemd)" + val file = """ + [DHCPServer] + BootServerName=double..dot + Domain=.leading.dot + """.trimIndent() + + setupFileInEditor("file.network", file) + enableInspection(InvalidValueInspection::class.java) + val highlights = myFixture.doHighlighting() + + assertSize(2, highlights) + } +} diff --git a/src/test/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/inspections/ai/ConfigParseDnsOptionValueTest.kt b/src/test/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/inspections/ai/ConfigParseDnsOptionValueTest.kt new file mode 100644 index 0000000..ef80672 --- /dev/null +++ b/src/test/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/inspections/ai/ConfigParseDnsOptionValueTest.kt @@ -0,0 +1,159 @@ +package net.sjrx.intellij.plugins.systemdunitfiles.inspections.ai + +import net.sjrx.intellij.plugins.systemdunitfiles.AbstractUnitFileTest +import net.sjrx.intellij.plugins.systemdunitfiles.inspections.InvalidValueInspection +import org.junit.Test + +class ConfigParseDnsOptionValueTest : AbstractUnitFileTest() { + + @Test + fun testValidSingleIpv4() { + // language="unit file (systemd)" + val file = """ + [Network] + DNS=192.168.1.1 + """.trimIndent() + + setupFileInEditor("file.network", file) + enableInspection(InvalidValueInspection::class.java) + val highlights = myFixture.doHighlighting() + + assertSize(0, highlights) + } + + @Test + fun testValidMultipleIpv4() { + // language="unit file (systemd)" + val file = """ + [Network] + DNS=192.168.1.1 8.8.8.8 1.1.1.1 + """.trimIndent() + + setupFileInEditor("file.network", file) + enableInspection(InvalidValueInspection::class.java) + val highlights = myFixture.doHighlighting() + + assertSize(0, highlights) + } + + @Test + fun testValidIpv6() { + // language="unit file (systemd)" + val file = """ + [Network] + DNS=2001:4860:4860::8888 + DNS=::1 + """.trimIndent() + + setupFileInEditor("file.network", file) + enableInspection(InvalidValueInspection::class.java) + val highlights = myFixture.doHighlighting() + + assertSize(0, highlights) + } + + @Test + fun testValidMixedIpv4AndIpv6() { + // language="unit file (systemd)" + val file = """ + [Network] + DNS=192.168.1.1 2001:4860:4860::8888 8.8.4.4 + """.trimIndent() + + setupFileInEditor("file.network", file) + enableInspection(InvalidValueInspection::class.java) + val highlights = myFixture.doHighlighting() + + assertSize(0, highlights) + } + + @Test + fun testValidIpv4WithPort() { + // language="unit file (systemd)" + val file = """ + [Network] + DNS=192.168.1.1:53 + """.trimIndent() + + setupFileInEditor("file.network", file) + enableInspection(InvalidValueInspection::class.java) + val highlights = myFixture.doHighlighting() + + assertSize(0, highlights) + } + + @Test + fun testValidIpv4WithInterface() { + // language="unit file (systemd)" + val file = """ + [Network] + DNS=192.168.1.1%eth0 + """.trimIndent() + + setupFileInEditor("file.network", file) + enableInspection(InvalidValueInspection::class.java) + val highlights = myFixture.doHighlighting() + + assertSize(0, highlights) + } + + @Test + fun testValidIpv6BracketedWithPort() { + // language="unit file (systemd)" + val file = """ + [Network] + DNS=[2001:4860:4860::8888]:53 + """.trimIndent() + + setupFileInEditor("file.network", file) + enableInspection(InvalidValueInspection::class.java) + val highlights = myFixture.doHighlighting() + + assertSize(0, highlights) + } + + @Test + fun testInvalidIpv4OctetTooLarge() { + // language="unit file (systemd)" + val file = """ + [Network] + DNS=192.168.1.256 + """.trimIndent() + + setupFileInEditor("file.network", file) + enableInspection(InvalidValueInspection::class.java) + val highlights = myFixture.doHighlighting() + + assertSize(1, highlights) + } + + @Test + fun testInvalidHostname() { + // language="unit file (systemd)" + val file = """ + [Network] + DNS=dns.example.com + """.trimIndent() + + setupFileInEditor("file.network", file) + enableInspection(InvalidValueInspection::class.java) + val highlights = myFixture.doHighlighting() + + assertSize(1, highlights) + } + + @Test + fun testInvalidGarbage() { + // language="unit file (systemd)" + val file = """ + [Network] + DNS=not-an-ip + """.trimIndent() + + setupFileInEditor("file.network", file) + enableInspection(InvalidValueInspection::class.java) + val highlights = myFixture.doHighlighting() + + assertSize(1, highlights) + } +} diff --git a/src/test/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/inspections/ai/ConfigParseDnssecModeOptionValueTest.kt b/src/test/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/inspections/ai/ConfigParseDnssecModeOptionValueTest.kt new file mode 100644 index 0000000..c9943a6 --- /dev/null +++ b/src/test/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/inspections/ai/ConfigParseDnssecModeOptionValueTest.kt @@ -0,0 +1,62 @@ +package net.sjrx.intellij.plugins.systemdunitfiles.inspections.ai + +import net.sjrx.intellij.plugins.systemdunitfiles.AbstractUnitFileTest +import net.sjrx.intellij.plugins.systemdunitfiles.inspections.InvalidValueInspection +import org.junit.Test + +class ConfigParseDnssecModeOptionValueTest : AbstractUnitFileTest() { + + @Test + fun testValidTableValues() { + // language="unit file (systemd)" + val file = """ + [Network] + DNSSEC=yes + DNSSEC=no + DNSSEC=allow-downgrade + """.trimIndent() + + setupFileInEditor("file.network", file) + enableInspection(InvalidValueInspection::class.java) + val highlights = myFixture.doHighlighting() + + assertSize(0, highlights) + } + + @Test + fun testValidBooleanValues() { + // language="unit file (systemd)" + val file = """ + [Network] + DNSSEC=true + DNSSEC=false + DNSSEC=on + DNSSEC=off + DNSSEC=1 + DNSSEC=0 + """.trimIndent() + + setupFileInEditor("file.network", file) + enableInspection(InvalidValueInspection::class.java) + val highlights = myFixture.doHighlighting() + + assertSize(0, highlights) + } + + @Test + fun testInvalidValues() { + // language="unit file (systemd)" + val file = """ + [Network] + DNSSEC=invalid + DNSSEC=allow + DNSSEC=downgrade + """.trimIndent() + + setupFileInEditor("file.network", file) + enableInspection(InvalidValueInspection::class.java) + val highlights = myFixture.doHighlighting() + + assertSize(3, highlights) + } +} diff --git a/src/test/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/inspections/ai/ConfigParseExecSecureBitsOptionValueTest.kt b/src/test/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/inspections/ai/ConfigParseExecSecureBitsOptionValueTest.kt new file mode 100644 index 0000000..fecf3ff --- /dev/null +++ b/src/test/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/inspections/ai/ConfigParseExecSecureBitsOptionValueTest.kt @@ -0,0 +1,52 @@ +package net.sjrx.intellij.plugins.systemdunitfiles.inspections.ai + +import net.sjrx.intellij.plugins.systemdunitfiles.AbstractUnitFileTest +import net.sjrx.intellij.plugins.systemdunitfiles.inspections.InvalidValueInspection +import org.junit.Test + +class ConfigParseExecSecureBitsOptionValueTest : AbstractUnitFileTest() { + + @Test + fun testValidValues() { + // Fixture Setup + // language="unit file (systemd)" + val file = """ + [Service] + SecureBits=keep-caps + SecureBits=keep-caps-locked + SecureBits=no-setuid-fixup + SecureBits=no-setuid-fixup-locked + SecureBits=noroot + SecureBits=noroot-locked + SecureBits=keep-caps keep-caps-locked no-setuid-fixup no-setuid-fixup-locked noroot noroot-locked + SecureBits=keep-caps noroot + """.trimIndent() + + // Execute SUT + setupFileInEditor("file.service", file) + enableInspection(InvalidValueInspection::class.java) + val highlights = myFixture.doHighlighting() + + // Verification + assertSize(0, highlights) + } + + @Test + fun testInvalidValues() { + // Fixture Setup + // language="unit file (systemd)" + val file = """ + [Service] + SecureBits=invalid_value + SecureBits=keep-caps invalid_value + """.trimIndent() + + // Execute SUT + setupFileInEditor("file.service", file) + enableInspection(InvalidValueInspection::class.java) + val highlights = myFixture.doHighlighting() + + // Verification + assertSize(2, highlights) + } +} diff --git a/src/test/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/inspections/ai/ConfigParseFairQueueingBoolOptionValueTest.kt b/src/test/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/inspections/ai/ConfigParseFairQueueingBoolOptionValueTest.kt new file mode 100644 index 0000000..fc800eb --- /dev/null +++ b/src/test/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/inspections/ai/ConfigParseFairQueueingBoolOptionValueTest.kt @@ -0,0 +1,58 @@ +package net.sjrx.intellij.plugins.systemdunitfiles.inspections.ai + +import net.sjrx.intellij.plugins.systemdunitfiles.AbstractUnitFileTest +import net.sjrx.intellij.plugins.systemdunitfiles.inspections.InvalidValueInspection +import org.junit.Test + +class ConfigParseFairQueueingBoolOptionValueTest : AbstractUnitFileTest() { + + @Test + fun testValidValues() { + // Fixture Setup + // language="unit file (systemd)" + val file = """ + [FairQueueing] + Pacing=yes + Pacing=no + Pacing=true + Pacing=false + Pacing=on + Pacing=off + Pacing=y + Pacing=n + Pacing=t + Pacing=f + Pacing=1 + Pacing=0 + """.trimIndent() + + // Execute SUT + setupFileInEditor("file.network", file) + enableInspection(InvalidValueInspection::class.java) + val highlights = myFixture.doHighlighting() + + // Verification + assertSize(0, highlights) + } + + @Test + fun testInvalidValues() { + // Fixture Setup + // language="unit file (systemd)" + val file = """ + [FairQueueing] + Pacing=invalid + Pacing=2 + Pacing=yesno + Pacing=auto + """.trimIndent() + + // Execute SUT + setupFileInEditor("file.network", file) + enableInspection(InvalidValueInspection::class.java) + val highlights = myFixture.doHighlighting() + + // Verification + assertSize(4, highlights) + } +} diff --git a/src/test/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/inspections/ai/ConfigParseFairQueueingSizeOptionValueTest.kt b/src/test/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/inspections/ai/ConfigParseFairQueueingSizeOptionValueTest.kt new file mode 100644 index 0000000..dab1423 --- /dev/null +++ b/src/test/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/inspections/ai/ConfigParseFairQueueingSizeOptionValueTest.kt @@ -0,0 +1,55 @@ +package net.sjrx.intellij.plugins.systemdunitfiles.inspections.ai + +import net.sjrx.intellij.plugins.systemdunitfiles.AbstractUnitFileTest +import net.sjrx.intellij.plugins.systemdunitfiles.inspections.InvalidValueInspection +import org.junit.Test + +class ConfigParseFairQueueingSizeOptionValueTest : AbstractUnitFileTest() { + + @Test + fun testValidValues() { + // Fixture Setup + // language="unit file (systemd)" + val file = """ + [FairQueueing] + QuantumBytes=1024 + InitialQuantumBytes=4096 + QuantumBytes=1K + InitialQuantumBytes=64K + QuantumBytes=1M + InitialQuantumBytes=2G + QuantumBytes=1T + InitialQuantumBytes=0 + """.trimIndent() + + // Execute SUT + setupFileInEditor("file.network", file) + enableInspection(InvalidValueInspection::class.java) + val highlights = myFixture.doHighlighting() + + // Verification + assertSize(0, highlights) + } + + @Test + fun testInvalidValues() { + // Fixture Setup + // language="unit file (systemd)" + val file = """ + [FairQueueing] + QuantumBytes=abc + InitialQuantumBytes=1024L + QuantumBytes=10.5M + InitialQuantumBytes=0x1000 + QuantumBytes=K + """.trimIndent() + + // Execute SUT + setupFileInEditor("file.network", file) + enableInspection(InvalidValueInspection::class.java) + val highlights = myFixture.doHighlighting() + + // Verification + assertSize(5, highlights) + } +} diff --git a/src/test/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/inspections/ai/ConfigParseFairQueueingU32OptionValueTest.kt b/src/test/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/inspections/ai/ConfigParseFairQueueingU32OptionValueTest.kt new file mode 100644 index 0000000..0970672 --- /dev/null +++ b/src/test/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/inspections/ai/ConfigParseFairQueueingU32OptionValueTest.kt @@ -0,0 +1,50 @@ +package net.sjrx.intellij.plugins.systemdunitfiles.inspections.ai + +import net.sjrx.intellij.plugins.systemdunitfiles.AbstractUnitFileTest +import net.sjrx.intellij.plugins.systemdunitfiles.inspections.InvalidValueInspection +import org.junit.Test + +class ConfigParseFairQueueingU32OptionValueTest : AbstractUnitFileTest() { + + @Test + fun testValidValues() { + // Fixture Setup + // language="unit file (systemd)" + val file = """ + [FairQueueing] + PacketLimit=0 + FlowLimit=100 + Buckets=1024 + OrphanMask=4294967295 + """.trimIndent() + + // Execute SUT + setupFileInEditor("file.network", file) + enableInspection(InvalidValueInspection::class.java) + val highlights = myFixture.doHighlighting() + + // Verification + assertSize(0, highlights) + } + + @Test + fun testInvalidValues() { + // Fixture Setup + // language="unit file (systemd)" + val file = """ + [FairQueueing] + PacketLimit=-1 + FlowLimit=4294967296 + Buckets=abc + OrphanMask=3.14 + """.trimIndent() + + // Execute SUT + setupFileInEditor("file.network", file) + enableInspection(InvalidValueInspection::class.java) + val highlights = myFixture.doHighlighting() + + // Verification + assertSize(4, highlights) + } +} diff --git a/src/test/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/inspections/ai/ConfigParseFdbVlanIdOptionValueTest.kt b/src/test/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/inspections/ai/ConfigParseFdbVlanIdOptionValueTest.kt new file mode 100644 index 0000000..58d4349 --- /dev/null +++ b/src/test/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/inspections/ai/ConfigParseFdbVlanIdOptionValueTest.kt @@ -0,0 +1,89 @@ +package net.sjrx.intellij.plugins.systemdunitfiles.inspections.ai + +import net.sjrx.intellij.plugins.systemdunitfiles.AbstractUnitFileTest +import net.sjrx.intellij.plugins.systemdunitfiles.inspections.InvalidValueInspection +import org.junit.Test + +class ConfigParseFdbVlanIdOptionValueTest : AbstractUnitFileTest() { + + @Test + fun testValidValues() { + // Fixture Setup + // language="unit file (systemd)" + val file = """ + [BridgeFDB] + VLANId=0 + VLANId=1 + VLANId=42 + VLANId=1000 + VLANId=4094 + """.trimIndent() + + // Execute SUT + setupFileInEditor("file.network", file) + enableInspection(InvalidValueInspection::class.java) + val highlights = myFixture.doHighlighting() + + // Verification + assertSize(0, highlights) + } + + @Test + fun testInvalidValues() { + // Fixture Setup + // language="unit file (systemd)" + val file = """ + [BridgeFDB] + VLANId=-1 + VLANId=4095 + VLANId=4096 + VLANId=abc + VLANId=1.5 + """.trimIndent() + + // Execute SUT + setupFileInEditor("file.network", file) + enableInspection(InvalidValueInspection::class.java) + val highlights = myFixture.doHighlighting() + + // Verification + assertSize(5, highlights) + } + + @Test + fun testBoundaryValues() { + // Fixture Setup + // language="unit file (systemd)" + val file = """ + [BridgeFDB] + VLANId=0 + VLANId=4094 + """.trimIndent() + + // Execute SUT + setupFileInEditor("file.network", file) + enableInspection(InvalidValueInspection::class.java) + val highlights = myFixture.doHighlighting() + + // Verification + assertSize(0, highlights) + } + + @Test + fun testInvalidBoundary() { + // Fixture Setup + // language="unit file (systemd)" + val file = """ + [BridgeFDB] + VLANId=4095 + """.trimIndent() + + // Execute SUT + setupFileInEditor("file.network", file) + enableInspection(InvalidValueInspection::class.java) + val highlights = myFixture.doHighlighting() + + // Verification + assertSize(1, highlights) + } +} diff --git a/src/test/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/inspections/ai/ConfigParseFdnameOptionValueTest.kt b/src/test/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/inspections/ai/ConfigParseFdnameOptionValueTest.kt new file mode 100644 index 0000000..d7878ce --- /dev/null +++ b/src/test/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/inspections/ai/ConfigParseFdnameOptionValueTest.kt @@ -0,0 +1,48 @@ +package net.sjrx.intellij.plugins.systemdunitfiles.inspections.ai + +import net.sjrx.intellij.plugins.systemdunitfiles.AbstractUnitFileTest +import net.sjrx.intellij.plugins.systemdunitfiles.inspections.InvalidValueInspection +import org.junit.Test + +class ConfigParseFdnameOptionValueTest : AbstractUnitFileTest() { + + @Test + fun testValidValues() { + // Fixture Setup + // language="unit file (systemd)" + val file = """ + [Socket] + FileDescriptorName=valid_name_1 + FileDescriptorName=valid-name-2 + FileDescriptorName=AnotherFd + FileDescriptorName=fd.with.dots + """.trimIndent() + + // Execute SUT + setupFileInEditor("file.socket", file) + enableInspection(InvalidValueInspection::class.java) + val highlights = myFixture.doHighlighting() + + // Verification + assertSize(0, highlights) + } + + @Test + fun testInvalidValues() { + // Fixture Setup - both lines contain a ':' which fdname_is_valid rejects + // language="unit file (systemd)" + val file = """ + [Socket] + FileDescriptorName=invalid:name_1 + FileDescriptorName=invalid:name_2 + """.trimIndent() + + // Execute SUT + setupFileInEditor("file.socket", file) + enableInspection(InvalidValueInspection::class.java) + val highlights = myFixture.doHighlighting() + + // Verification + assertSize(2, highlights) + } +} diff --git a/src/test/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/inspections/ai/ConfigParseHostnameOptionValueTest.kt b/src/test/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/inspections/ai/ConfigParseHostnameOptionValueTest.kt new file mode 100644 index 0000000..6e8cf20 --- /dev/null +++ b/src/test/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/inspections/ai/ConfigParseHostnameOptionValueTest.kt @@ -0,0 +1,47 @@ +package net.sjrx.intellij.plugins.systemdunitfiles.inspections.ai + +import net.sjrx.intellij.plugins.systemdunitfiles.AbstractUnitFileTest +import net.sjrx.intellij.plugins.systemdunitfiles.inspections.InvalidValueInspection +import org.junit.Test + +class ConfigParseHostnameOptionValueTest : AbstractUnitFileTest() { + + @Test + fun testValidHostnames() { + // language="unit file (systemd)" + val file = """ + [DHCPv4] + Hostname=myhost + Hostname=my-host + Hostname=host.example.com + Hostname=host123 + Hostname=123host + Hostname=h + Hostname=a-b-c + """.trimIndent() + + setupFileInEditor("file.network", file) + enableInspection(InvalidValueInspection::class.java) + val highlights = myFixture.doHighlighting() + assertSize(0, highlights) + } + + @Test + fun testInvalidHostnames() { + // language="unit file (systemd)" + val file = """ + [DHCPv4] + Hostname=-host + Hostname=host- + Hostname=host..com + Hostname=host_name + Hostname=host! + Hostname=host name + """.trimIndent() + + setupFileInEditor("file.network", file) + enableInspection(InvalidValueInspection::class.java) + val highlights = myFixture.doHighlighting() + assertSize(6, highlights) + } +} diff --git a/src/test/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/inspections/ai/ConfigParseIfnameOptionValueTest.kt b/src/test/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/inspections/ai/ConfigParseIfnameOptionValueTest.kt new file mode 100644 index 0000000..df56bc6 --- /dev/null +++ b/src/test/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/inspections/ai/ConfigParseIfnameOptionValueTest.kt @@ -0,0 +1,46 @@ +package net.sjrx.intellij.plugins.systemdunitfiles.inspections.ai + +import net.sjrx.intellij.plugins.systemdunitfiles.AbstractUnitFileTest +import net.sjrx.intellij.plugins.systemdunitfiles.inspections.InvalidValueInspection +import org.junit.Test + +class ConfigParseIfnameOptionValueTest : AbstractUnitFileTest() { + + @Test + fun testValidInterfaceNames() { + // language="unit file (systemd)" + val file = """ + [Network] + Bridge=br0 + Bridge=eth0 + Bridge=my-iface + Bridge=iface_1 + Bridge=abcdefghijklmno + Bridge=12eth + """.trimIndent() + + setupFileInEditor("file.network", file) + enableInspection(InvalidValueInspection::class.java) + assertSize(0, myFixture.doHighlighting()) + } + + @Test + fun testInvalidInterfaceNames() { + // language="unit file (systemd)" + val file = """ + [Network] + Bridge=bad/name + Bridge=thisnameiswaytoolong + Bridge=eth0:1 + Bridge=eth%d + Bridge=all + Bridge=default + Bridge=1234 + Bridge=0x10 + """.trimIndent() + + setupFileInEditor("file.network", file) + enableInspection(InvalidValueInspection::class.java) + assertSize(8, myFixture.doHighlighting()) + } +} diff --git a/src/test/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/inspections/ai/ConfigParseIpProtocolOptionValueTest.kt b/src/test/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/inspections/ai/ConfigParseIpProtocolOptionValueTest.kt new file mode 100644 index 0000000..f441017 --- /dev/null +++ b/src/test/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/inspections/ai/ConfigParseIpProtocolOptionValueTest.kt @@ -0,0 +1,53 @@ +package net.sjrx.intellij.plugins.systemdunitfiles.inspections.ai + +import net.sjrx.intellij.plugins.systemdunitfiles.AbstractUnitFileTest +import net.sjrx.intellij.plugins.systemdunitfiles.inspections.InvalidValueInspection +import org.junit.Test + +class ConfigParseIpProtocolOptionValueTest : AbstractUnitFileTest() { + + @Test + fun testValidValues() { + // Fixture Setup + // language="unit file (systemd)" + val file = """ + [FooOverUDP] + Protocol=tcp + Protocol=udp + Protocol=icmp + Protocol=icmpv6 + Protocol=sctp + Protocol=0 + Protocol=47 + Protocol=255 + """.trimIndent() + + // Execute SUT + setupFileInEditor("file.netdev", file) + enableInspection(InvalidValueInspection::class.java) + val highlights = myFixture.doHighlighting() + + // Verification + assertSize(0, highlights) + } + + @Test + fun testInvalidValues() { + // Fixture Setup + // language="unit file (systemd)" + val file = """ + [FooOverUDP] + Protocol=256 + Protocol=-1 + Protocol=not-a-protocol + """.trimIndent() + + // Execute SUT + setupFileInEditor("file.netdev", file) + enableInspection(InvalidValueInspection::class.java) + val highlights = myFixture.doHighlighting() + + // Verification + assertSize(3, highlights) + } +} diff --git a/src/test/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/inspections/ai/ConfigParseIpTosOptionValueTest.kt b/src/test/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/inspections/ai/ConfigParseIpTosOptionValueTest.kt new file mode 100644 index 0000000..00bc330 --- /dev/null +++ b/src/test/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/inspections/ai/ConfigParseIpTosOptionValueTest.kt @@ -0,0 +1,138 @@ +package net.sjrx.intellij.plugins.systemdunitfiles.inspections.ai + +import net.sjrx.intellij.plugins.systemdunitfiles.AbstractUnitFileTest +import net.sjrx.intellij.plugins.systemdunitfiles.inspections.InvalidValueInspection +import org.junit.Test + +class ConfigParseIpTosOptionValueTest : AbstractUnitFileTest() { + + @Test + fun testValidNamedValues() { + // language="unit file (systemd)" + val file = """ + [Socket] + IPTOS=low-delay + """.trimIndent() + + setupFileInEditor("file.socket", file) + enableInspection(InvalidValueInspection::class.java) + assertSize(0, myFixture.doHighlighting()) + } + + @Test + fun testValidNamedValueThroughput() { + // language="unit file (systemd)" + val file = """ + [Socket] + IPTOS=throughput + """.trimIndent() + + setupFileInEditor("file.socket", file) + enableInspection(InvalidValueInspection::class.java) + assertSize(0, myFixture.doHighlighting()) + } + + @Test + fun testValidNamedValueReliability() { + // language="unit file (systemd)" + val file = """ + [Socket] + IPTOS=reliability + """.trimIndent() + + setupFileInEditor("file.socket", file) + enableInspection(InvalidValueInspection::class.java) + assertSize(0, myFixture.doHighlighting()) + } + + @Test + fun testValidNamedValueLowCost() { + // language="unit file (systemd)" + val file = """ + [Socket] + IPTOS=low-cost + """.trimIndent() + + setupFileInEditor("file.socket", file) + enableInspection(InvalidValueInspection::class.java) + assertSize(0, myFixture.doHighlighting()) + } + + @Test + fun testValidIntegerLowerBound() { + // language="unit file (systemd)" + val file = """ + [Socket] + IPTOS=0 + """.trimIndent() + + setupFileInEditor("file.socket", file) + enableInspection(InvalidValueInspection::class.java) + assertSize(0, myFixture.doHighlighting()) + } + + @Test + fun testValidIntegerUpperBound() { + // language="unit file (systemd)" + val file = """ + [Socket] + IPTOS=255 + """.trimIndent() + + setupFileInEditor("file.socket", file) + enableInspection(InvalidValueInspection::class.java) + assertSize(0, myFixture.doHighlighting()) + } + + @Test + fun testValidIntegerMidRange() { + // language="unit file (systemd)" + val file = """ + [Socket] + IPTOS=42 + """.trimIndent() + + setupFileInEditor("file.socket", file) + enableInspection(InvalidValueInspection::class.java) + assertSize(0, myFixture.doHighlighting()) + } + + @Test + fun testInvalidWord() { + // language="unit file (systemd)" + val file = """ + [Socket] + IPTOS=invalid_value + """.trimIndent() + + setupFileInEditor("file.socket", file) + enableInspection(InvalidValueInspection::class.java) + assertSize(1, myFixture.doHighlighting()) + } + + @Test + fun testInvalidIntegerOutOfRange() { + // language="unit file (systemd)" + val file = """ + [Socket] + IPTOS=300 + """.trimIndent() + + setupFileInEditor("file.socket", file) + enableInspection(InvalidValueInspection::class.java) + assertSize(1, myFixture.doHighlighting()) + } + + @Test + fun testInvalidIntegerNegative() { + // language="unit file (systemd)" + val file = """ + [Socket] + IPTOS=-1 + """.trimIndent() + + setupFileInEditor("file.socket", file) + enableInspection(InvalidValueInspection::class.java) + assertSize(1, myFixture.doHighlighting()) + } +} diff --git a/src/test/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/inspections/ai/ConfigParseJobRunningTimeoutSecOptionValueTest.kt b/src/test/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/inspections/ai/ConfigParseJobRunningTimeoutSecOptionValueTest.kt new file mode 100644 index 0000000..2630909 --- /dev/null +++ b/src/test/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/inspections/ai/ConfigParseJobRunningTimeoutSecOptionValueTest.kt @@ -0,0 +1,46 @@ +package net.sjrx.intellij.plugins.systemdunitfiles.inspections.ai + +import net.sjrx.intellij.plugins.systemdunitfiles.AbstractUnitFileTest +import net.sjrx.intellij.plugins.systemdunitfiles.inspections.InvalidValueInspection +import org.junit.Test + +class ConfigParseJobRunningTimeoutSecOptionValueTest : AbstractUnitFileTest() { + + @Test + fun testValidValues() { + // language="unit file (systemd)" + val file = """ + [Unit] + JobRunningTimeoutSec=10 + JobRunningTimeoutSec=10s + JobRunningTimeoutSec=100ms + JobRunningTimeoutSec=1m + JobRunningTimeoutSec=1h + JobRunningTimeoutSec=1d + JobRunningTimeoutSec=infinity + JobRunningTimeoutSec=10 s + JobRunningTimeoutSec=1.5h + JobRunningTimeoutSec=1min 30s + JobRunningTimeoutSec=2hour + """.trimIndent() + + setupFileInEditor("file.service", file) + enableInspection(InvalidValueInspection::class.java) + assertSize(0, myFixture.doHighlighting()) + } + + @Test + fun testInvalidValues() { + // language="unit file (systemd)" + val file = """ + [Unit] + JobRunningTimeoutSec=invalid + JobRunningTimeoutSec=10x + JobRunningTimeoutSec=10.5.2s + """.trimIndent() + + setupFileInEditor("file.service", file) + enableInspection(InvalidValueInspection::class.java) + assertSize(3, myFixture.doHighlighting()) + } +} diff --git a/src/test/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/inspections/ai/ConfigParseNamespaceFlagsOptionValueTest.kt b/src/test/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/inspections/ai/ConfigParseNamespaceFlagsOptionValueTest.kt new file mode 100644 index 0000000..343ddd2 --- /dev/null +++ b/src/test/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/inspections/ai/ConfigParseNamespaceFlagsOptionValueTest.kt @@ -0,0 +1,122 @@ +package net.sjrx.intellij.plugins.systemdunitfiles.inspections.ai + +import net.sjrx.intellij.plugins.systemdunitfiles.AbstractUnitFileTest +import net.sjrx.intellij.plugins.systemdunitfiles.inspections.InvalidValueInspection +import org.junit.Test + +class ConfigParseNamespaceFlagsOptionValueTest : AbstractUnitFileTest() { + + @Test + fun testValidSingleNamespaceTypes() { + // language="unit file (systemd)" + val file = """ + [Service] + RestrictNamespaces=cgroup + RestrictNamespaces=ipc + RestrictNamespaces=net + RestrictNamespaces=mnt + RestrictNamespaces=pid + RestrictNamespaces=user + RestrictNamespaces=uts + RestrictNamespaces=time + """.trimIndent() + + setupFileInEditor("file.service", file) + enableInspection(InvalidValueInspection::class.java) + assertSize(0, myFixture.doHighlighting()) + } + + @Test + fun testValidWhitespaceSeparatedList() { + // language="unit file (systemd)" + val file = """ + [Service] + RestrictNamespaces=cgroup ipc + RestrictNamespaces=mnt uts ipc + RestrictNamespaces=cgroup ipc net mnt pid user uts time + """.trimIndent() + + setupFileInEditor("file.service", file) + enableInspection(InvalidValueInspection::class.java) + assertSize(0, myFixture.doHighlighting()) + } + + @Test + fun testValidInvertedList() { + // language="unit file (systemd)" + val file = """ + [Service] + RestrictNamespaces=~cgroup + RestrictNamespaces=~cgroup net + RestrictNamespaces=~mnt uts ipc + """.trimIndent() + + setupFileInEditor("file.service", file) + enableInspection(InvalidValueInspection::class.java) + assertSize(0, myFixture.doHighlighting()) + } + + @Test + fun testValidBooleans() { + // language="unit file (systemd)" + val file = """ + [Service] + RestrictNamespaces=yes + RestrictNamespaces=no + RestrictNamespaces=true + RestrictNamespaces=false + RestrictNamespaces=on + RestrictNamespaces=off + RestrictNamespaces=1 + RestrictNamespaces=0 + """.trimIndent() + + setupFileInEditor("file.service", file) + enableInspection(InvalidValueInspection::class.java) + assertSize(0, myFixture.doHighlighting()) + } + + @Test + fun testValidDelegateNamespaces() { + // language="unit file (systemd)" + val file = """ + [Service] + DelegateNamespaces=mnt + DelegateNamespaces=~user + DelegateNamespaces=yes + """.trimIndent() + + setupFileInEditor("file.service", file) + enableInspection(InvalidValueInspection::class.java) + assertSize(0, myFixture.doHighlighting()) + } + + @Test + fun testInvalidValues() { + // language="unit file (systemd)" + val file = """ + [Service] + RestrictNamespaces=invalid_value_1 + RestrictNamespaces=foo bar + RestrictNamespaces=cgroup,ipc + """.trimIndent() + + setupFileInEditor("file.service", file) + enableInspection(InvalidValueInspection::class.java) + assertSize(3, myFixture.doHighlighting()) + } + + @Test + fun testInvalidTrailingTilde() { + // language="unit file (systemd)" + val file = """ + [Service] + RestrictNamespaces=cgroup~ + RestrictNamespaces=cgroup ~ipc + """.trimIndent() + + setupFileInEditor("file.service", file) + enableInspection(InvalidValueInspection::class.java) + assertSize(2, myFixture.doHighlighting()) + } +} diff --git a/src/test/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/inspections/ai/ConfigParseProtectHostnameOptionValueTest.kt b/src/test/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/inspections/ai/ConfigParseProtectHostnameOptionValueTest.kt new file mode 100644 index 0000000..943833e --- /dev/null +++ b/src/test/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/inspections/ai/ConfigParseProtectHostnameOptionValueTest.kt @@ -0,0 +1,65 @@ +package net.sjrx.intellij.plugins.systemdunitfiles.inspections.ai + +import net.sjrx.intellij.plugins.systemdunitfiles.AbstractUnitFileTest +import net.sjrx.intellij.plugins.systemdunitfiles.inspections.InvalidValueInspection +import org.junit.Test + +class ConfigParseProtectHostnameOptionValueTest : AbstractUnitFileTest() { + + @Test + fun testValidBooleanValues() { + // language="unit file (systemd)" + val file = """ + [Service] + ProtectHostname=yes + ProtectHostname=no + ProtectHostname=true + ProtectHostname=false + ProtectHostname=on + ProtectHostname=off + ProtectHostname=1 + ProtectHostname=0 + ProtectHostname=private + """.trimIndent() + + setupFileInEditor("file.service", file) + enableInspection(InvalidValueInspection::class.java) + val highlights = myFixture.doHighlighting() + assertSize(0, highlights) + } + + @Test + fun testValidKeywordWithHostname() { + // language="unit file (systemd)" + val file = """ + [Service] + ProtectHostname=yes:my-host + ProtectHostname=private:example.com + ProtectHostname=true:foo.bar.example + ProtectHostname=on:host1 + ProtectHostname=1:a-b-c.d + """.trimIndent() + + setupFileInEditor("file.service", file) + enableInspection(InvalidValueInspection::class.java) + val highlights = myFixture.doHighlighting() + assertSize(0, highlights) + } + + @Test + fun testInvalidValues() { + // language="unit file (systemd)" + val file = """ + [Service] + ProtectHostname=invalid + ProtectHostname=yes:-bad-leading-hyphen + ProtectHostname=private:bad..double.dot + ProtectHostname=yes:bad_underscore + """.trimIndent() + + setupFileInEditor("file.service", file) + enableInspection(InvalidValueInspection::class.java) + val highlights = myFixture.doHighlighting() + assertSize(4, highlights) + } +} diff --git a/src/test/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/inspections/ai/ConfigParseRequiredFamilyForOnlineOptionValueTest.kt b/src/test/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/inspections/ai/ConfigParseRequiredFamilyForOnlineOptionValueTest.kt new file mode 100644 index 0000000..5d5f5ed --- /dev/null +++ b/src/test/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/inspections/ai/ConfigParseRequiredFamilyForOnlineOptionValueTest.kt @@ -0,0 +1,42 @@ +package net.sjrx.intellij.plugins.systemdunitfiles.inspections.ai + +import net.sjrx.intellij.plugins.systemdunitfiles.AbstractUnitFileTest +import net.sjrx.intellij.plugins.systemdunitfiles.inspections.InvalidValueInspection +import org.junit.Test + +class ConfigParseRequiredFamilyForOnlineOptionValueTest : AbstractUnitFileTest() { + + @Test + fun testValidValues() { + // language="unit file (systemd)" + val file = """ + [Link] + RequiredFamilyForOnline=ipv4 + RequiredFamilyForOnline=ipv6 + RequiredFamilyForOnline=both + RequiredFamilyForOnline=any + """.trimIndent() + + setupFileInEditor("file.network", file) + enableInspection(InvalidValueInspection::class.java) + val highlights = myFixture.doHighlighting() + + assertSize(0, highlights) + } + + @Test + fun testInvalidValues() { + // language="unit file (systemd)" + val file = """ + [Link] + RequiredFamilyForOnline=invalid + RequiredFamilyForOnline=value + """.trimIndent() + + setupFileInEditor("file.network", file) + enableInspection(InvalidValueInspection::class.java) + val highlights = myFixture.doHighlighting() + + assertSize(2, highlights) + } +} diff --git a/src/test/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/inspections/ai/ConfigParseServiceTimeoutAbortOptionValueTest.kt b/src/test/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/inspections/ai/ConfigParseServiceTimeoutAbortOptionValueTest.kt new file mode 100644 index 0000000..7ca97cf --- /dev/null +++ b/src/test/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/inspections/ai/ConfigParseServiceTimeoutAbortOptionValueTest.kt @@ -0,0 +1,45 @@ +package net.sjrx.intellij.plugins.systemdunitfiles.inspections.ai + +import net.sjrx.intellij.plugins.systemdunitfiles.AbstractUnitFileTest +import net.sjrx.intellij.plugins.systemdunitfiles.inspections.InvalidValueInspection +import org.junit.Test + +class ConfigParseServiceTimeoutAbortOptionValueTest : AbstractUnitFileTest() { + + @Test + fun testValidValues() { + // language="unit file (systemd)" + val file = """ + [Service] + TimeoutAbortSec=10 + TimeoutAbortSec=10s + TimeoutAbortSec=500ms + TimeoutAbortSec=5min + TimeoutAbortSec=2hour + TimeoutAbortSec=infinity + """.trimIndent() + + setupFileInEditor("file.service", file) + enableInspection(InvalidValueInspection::class.java) + val highlights = myFixture.doHighlighting() + + assertSize(0, highlights) + } + + @Test + fun testInvalidValues() { + // language="unit file (systemd)" + val file = """ + [Service] + TimeoutAbortSec=abc + TimeoutAbortSec=-10 + TimeoutAbortSec=10x + """.trimIndent() + + setupFileInEditor("file.service", file) + enableInspection(InvalidValueInspection::class.java) + val highlights = myFixture.doHighlighting() + + assertSize(3, highlights) + } +} diff --git a/src/test/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/inspections/ai/ConfigParseServiceTimeoutOptionValueTest.kt b/src/test/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/inspections/ai/ConfigParseServiceTimeoutOptionValueTest.kt new file mode 100644 index 0000000..a746988 --- /dev/null +++ b/src/test/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/inspections/ai/ConfigParseServiceTimeoutOptionValueTest.kt @@ -0,0 +1,54 @@ +package net.sjrx.intellij.plugins.systemdunitfiles.inspections.ai + +import net.sjrx.intellij.plugins.systemdunitfiles.AbstractUnitFileTest +import net.sjrx.intellij.plugins.systemdunitfiles.inspections.InvalidValueInspection +import org.junit.Test + +class ConfigParseServiceTimeoutOptionValueTest : AbstractUnitFileTest() { + + @Test + fun testValidValues() { + // Fixture Setup + // language="unit file (systemd)" + val file = """ + [Service] + TimeoutSec=infinity + TimeoutStartSec=5s + TimeoutSec=10m + TimeoutStartSec=30 + TimeoutSec=0 + TimeoutStartSec=500ms + TimeoutSec=2h + TimeoutStartSec=1min 30s + """.trimIndent() + + // Execute SUT + setupFileInEditor("file.service", file) + enableInspection(InvalidValueInspection::class.java) + val highlights = myFixture.doHighlighting() + + // Verification + assertSize(0, highlights) + } + + @Test + fun testInvalidValues() { + // Fixture Setup + // language="unit file (systemd)" + val file = """ + [Service] + TimeoutStartSec=abc + TimeoutSec=-10s + TimeoutStartSec=INFINITY + TimeoutSec=forever + """.trimIndent() + + // Execute SUT + setupFileInEditor("file.service", file) + enableInspection(InvalidValueInspection::class.java) + val highlights = myFixture.doHighlighting() + + // Verification + assertSize(4, highlights) + } +} diff --git a/src/test/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/inspections/ai/ConfigParseSiUint64OptionValueTest.kt b/src/test/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/inspections/ai/ConfigParseSiUint64OptionValueTest.kt new file mode 100644 index 0000000..3ecffdf --- /dev/null +++ b/src/test/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/inspections/ai/ConfigParseSiUint64OptionValueTest.kt @@ -0,0 +1,51 @@ +package net.sjrx.intellij.plugins.systemdunitfiles.inspections.ai + +import net.sjrx.intellij.plugins.systemdunitfiles.AbstractUnitFileTest +import net.sjrx.intellij.plugins.systemdunitfiles.inspections.InvalidValueInspection +import org.junit.Test + +class ConfigParseSiUint64OptionValueTest : AbstractUnitFileTest() { + + @Test + fun testValidValues() { + // Fixture Setup + // language="unit file (systemd)" + val file = """ + [Link] + BitsPerSecond=1000 + BitsPerSecond=1K + BitsPerSecond=1M + BitsPerSecond=1.5G + BitsPerSecond=2T + """.trimIndent() + + // Execute SUT + setupFileInEditor("file.link", file) + enableInspection(InvalidValueInspection::class.java) + val highlights = myFixture.doHighlighting() + + // Verification + assertSize(0, highlights) + } + + @Test + fun testInvalidValues() { + // Fixture Setup + // language="unit file (systemd)" + val file = """ + [Link] + BitsPerSecond=abc + BitsPerSecond=-100 + BitsPerSecond=1k + BitsPerSecond=1Kb + """.trimIndent() + + // Execute SUT + setupFileInEditor("file.link", file) + enableInspection(InvalidValueInspection::class.java) + val highlights = myFixture.doHighlighting() + + // Verification + assertSize(4, highlights) + } +} diff --git a/src/test/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/inspections/ai/ConfigParseSrIovLinkStateOptionValueTest.kt b/src/test/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/inspections/ai/ConfigParseSrIovLinkStateOptionValueTest.kt new file mode 100644 index 0000000..3b58bfa --- /dev/null +++ b/src/test/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/inspections/ai/ConfigParseSrIovLinkStateOptionValueTest.kt @@ -0,0 +1,46 @@ +package net.sjrx.intellij.plugins.systemdunitfiles.inspections.ai + +import net.sjrx.intellij.plugins.systemdunitfiles.AbstractUnitFileTest +import net.sjrx.intellij.plugins.systemdunitfiles.inspections.InvalidValueInspection +import org.junit.Test + +class ConfigParseSrIovLinkStateOptionValueTest : AbstractUnitFileTest() { + + @Test + fun testValidValues() { + // language="unit file (systemd)" + val file = """ + [SR-IOV] + LinkState=auto + LinkState=yes + LinkState=no + LinkState=true + LinkState=false + LinkState=on + LinkState=off + LinkState=1 + LinkState=0 + """.trimIndent() + + setupFileInEditor("file.link", file) + enableInspection(InvalidValueInspection::class.java) + val highlights = myFixture.doHighlighting() + assertSize(0, highlights) + } + + @Test + fun testInvalidValues() { + // language="unit file (systemd)" + val file = """ + [SR-IOV] + LinkState=invalid_value_1 + LinkState=enable + LinkState=disable + """.trimIndent() + + setupFileInEditor("file.link", file) + enableInspection(InvalidValueInspection::class.java) + val highlights = myFixture.doHighlighting() + assertSize(3, highlights) + } +} diff --git a/src/test/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/inspections/ai/ConfigParseStringOptionValueTest.kt b/src/test/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/inspections/ai/ConfigParseStringOptionValueTest.kt new file mode 100644 index 0000000..82e8339 --- /dev/null +++ b/src/test/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/inspections/ai/ConfigParseStringOptionValueTest.kt @@ -0,0 +1,45 @@ +package net.sjrx.intellij.plugins.systemdunitfiles.inspections.ai + +import net.sjrx.intellij.plugins.systemdunitfiles.AbstractUnitFileTest +import net.sjrx.intellij.plugins.systemdunitfiles.inspections.InvalidValueInspection +import org.junit.Test + +class ConfigParseStringOptionValueTest : AbstractUnitFileTest() { + + @Test + fun testValidValues() { + // language="unit file (systemd)" + val file = """ + [Tun] + User=systemd-network + User=ftp + User=user-name + User=user.with.dots + User=user with spaces + User=glob*pattern + User=glob?pattern + User=glob[abc]pattern + """.trimIndent() + + setupFileInEditor("file.netdev", file) + enableInspection(InvalidValueInspection::class.java) + val highlights = myFixture.doHighlighting() + assertSize(0, highlights) + } + + @Test + fun testInvalidValues() { + // language="unit file (systemd)" + val file = """ + [Tun] + User=user"name + User=user'name + User=user\name + """.trimIndent() + + setupFileInEditor("file.netdev", file) + enableInspection(InvalidValueInspection::class.java) + val highlights = myFixture.doHighlighting() + assertSize(3, highlights) + } +} diff --git a/src/test/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/inspections/ai/ConfigParseTokenBucketFilterLatencyOptionValueTest.kt b/src/test/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/inspections/ai/ConfigParseTokenBucketFilterLatencyOptionValueTest.kt new file mode 100644 index 0000000..8b52230 --- /dev/null +++ b/src/test/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/inspections/ai/ConfigParseTokenBucketFilterLatencyOptionValueTest.kt @@ -0,0 +1,44 @@ +package net.sjrx.intellij.plugins.systemdunitfiles.inspections.ai + +import net.sjrx.intellij.plugins.systemdunitfiles.AbstractUnitFileTest +import net.sjrx.intellij.plugins.systemdunitfiles.inspections.InvalidValueInspection +import org.junit.Test + +class ConfigParseTokenBucketFilterLatencyOptionValueTest : AbstractUnitFileTest() { + + @Test + fun testValidValues() { + // language="unit file (systemd)" + val file = """ + [TokenBucketFilter] + LatencySec=10s + LatencySec=100ms + LatencySec=1m + LatencySec=1h + LatencySec=500us + LatencySec=42 + LatencySec=1.5s + LatencySec=infinity + LatencySec=2hour + """.trimIndent() + + setupFileInEditor("file.network", file) + enableInspection(InvalidValueInspection::class.java) + assertSize(0, myFixture.doHighlighting()) + } + + @Test + fun testInvalidValues() { + // language="unit file (systemd)" + val file = """ + [TokenBucketFilter] + LatencySec=invalid + LatencySec=-10 + LatencySec=10x + """.trimIndent() + + setupFileInEditor("file.network", file) + enableInspection(InvalidValueInspection::class.java) + assertSize(3, myFixture.doHighlighting()) + } +} diff --git a/src/test/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/inspections/ai/ConfigParseTriggerUnitOptionValueTest.kt b/src/test/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/inspections/ai/ConfigParseTriggerUnitOptionValueTest.kt new file mode 100644 index 0000000..ee7a485 --- /dev/null +++ b/src/test/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/inspections/ai/ConfigParseTriggerUnitOptionValueTest.kt @@ -0,0 +1,96 @@ +package net.sjrx.intellij.plugins.systemdunitfiles.inspections.ai + +import net.sjrx.intellij.plugins.systemdunitfiles.AbstractUnitFileTest +import net.sjrx.intellij.plugins.systemdunitfiles.inspections.InvalidValueInspection +import org.junit.Test + +class ConfigParseTriggerUnitOptionValueTest : AbstractUnitFileTest() { + + @Test + fun testValidUnitNames() { + // Fixture Setup + // language="unit file (systemd)" + val file = """ + [Path] + Unit=foo.service + Unit=bar.socket + Unit=baz.target + Unit=my-app.mount + Unit=net_dev.automount + Unit=tmp.timer + Unit=swapfile.swap + Unit=watcher.path + Unit=workload.slice + Unit=session.scope + Unit=fs-home.device + """.trimIndent() + + // Execute SUT + setupFileInEditor("file.path", file) + enableInspection(InvalidValueInspection::class.java) + val highlights = myFixture.doHighlighting() + + // Verification + assertSize(0, highlights) + } + + @Test + fun testValidTemplateAndComplexNames() { + // Fixture Setup + // language="unit file (systemd)" + val file = """ + [Path] + Unit=getty@tty1.service + Unit=user@1000.service + Unit=foo.bar.service + Unit=a-b_c.service + """.trimIndent() + + // Execute SUT + setupFileInEditor("file.path", file) + enableInspection(InvalidValueInspection::class.java) + val highlights = myFixture.doHighlighting() + + // Verification + assertSize(0, highlights) + } + + @Test + fun testInvalidUnitTypes() { + // Fixture Setup + // language="unit file (systemd)" + val file = """ + [Path] + Unit=foo.bogus + Unit=bar.unknown + Unit=foo + """.trimIndent() + + // Execute SUT + setupFileInEditor("file.path", file) + enableInspection(InvalidValueInspection::class.java) + val highlights = myFixture.doHighlighting() + + // Verification + assertSize(3, highlights) + } + + @Test + fun testInvalidCharacters() { + // Fixture Setup + // language="unit file (systemd)" + val file = """ + [Path] + Unit=foo bar.service + Unit=foo/bar.service + """.trimIndent() + + // Execute SUT + setupFileInEditor("file.path", file) + enableInspection(InvalidValueInspection::class.java) + val highlights = myFixture.doHighlighting() + + // Verification + assertSize(2, highlights) + } +} diff --git a/src/test/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/inspections/ai/ConfigParseUdevPropertyNameOptionValueTest.kt b/src/test/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/inspections/ai/ConfigParseUdevPropertyNameOptionValueTest.kt new file mode 100644 index 0000000..a78439b --- /dev/null +++ b/src/test/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/inspections/ai/ConfigParseUdevPropertyNameOptionValueTest.kt @@ -0,0 +1,116 @@ +package net.sjrx.intellij.plugins.systemdunitfiles.inspections.ai + +import net.sjrx.intellij.plugins.systemdunitfiles.AbstractUnitFileTest +import net.sjrx.intellij.plugins.systemdunitfiles.inspections.InvalidValueInspection +import org.junit.Test + +class ConfigParseUdevPropertyNameOptionValueTest : AbstractUnitFileTest() { + + @Test + fun testValidSingleProperty() { + // Fixture Setup + // language="unit file (systemd)" + val file = """ + [Link] + UnsetProperty=ID_NET_NAME + """.trimIndent() + + // Execute SUT + setupFileInEditor("file.link", file) + enableInspection(InvalidValueInspection::class.java) + val highlights = myFixture.doHighlighting() + + // Verification + assertSize(0, highlights) + } + + @Test + fun testValidMultipleProperties() { + // Fixture Setup + // language="unit file (systemd)" + val file = """ + [Link] + UnsetProperty=ID_NET_NAME ID_NET_NAME_PATH ID_NET_NAME_SLOT + """.trimIndent() + + // Execute SUT + setupFileInEditor("file.link", file) + enableInspection(InvalidValueInspection::class.java) + val highlights = myFixture.doHighlighting() + + // Verification + assertSize(0, highlights) + } + + @Test + fun testValidLowercaseAndUnderscoreLeading() { + // Fixture Setup + // language="unit file (systemd)" + val file = """ + [Link] + ImportProperty=lowercase_ok _leading_underscore MIXED_Case123 + """.trimIndent() + + // Execute SUT + setupFileInEditor("file.link", file) + enableInspection(InvalidValueInspection::class.java) + val highlights = myFixture.doHighlighting() + + // Verification + assertSize(0, highlights) + } + + @Test + fun testInvalidLeadingDigit() { + // Fixture Setup + // language="unit file (systemd)" + val file = """ + [Link] + UnsetProperty=1INVALID + """.trimIndent() + + // Execute SUT + setupFileInEditor("file.link", file) + enableInspection(InvalidValueInspection::class.java) + val highlights = myFixture.doHighlighting() + + // Verification + assertSize(1, highlights) + } + + @Test + fun testInvalidContainsHyphen() { + // Fixture Setup + // language="unit file (systemd)" + val file = """ + [Link] + UnsetProperty=ID-NET-NAME + """.trimIndent() + + // Execute SUT + setupFileInEditor("file.link", file) + enableInspection(InvalidValueInspection::class.java) + val highlights = myFixture.doHighlighting() + + // Verification + assertSize(1, highlights) + } + + @Test + fun testInvalidContainsDot() { + // Fixture Setup + // language="unit file (systemd)" + val file = """ + [Link] + ImportProperty=ID.NET.NAME + """.trimIndent() + + // Execute SUT + setupFileInEditor("file.link", file) + enableInspection(InvalidValueInspection::class.java) + val highlights = myFixture.doHighlighting() + + // Verification + assertSize(1, highlights) + } +} diff --git a/src/test/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/inspections/ai/ConfigParseWolOptionValueTest.kt b/src/test/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/inspections/ai/ConfigParseWolOptionValueTest.kt new file mode 100644 index 0000000..1792b21 --- /dev/null +++ b/src/test/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/inspections/ai/ConfigParseWolOptionValueTest.kt @@ -0,0 +1,115 @@ +package net.sjrx.intellij.plugins.systemdunitfiles.inspections.ai + +import net.sjrx.intellij.plugins.systemdunitfiles.AbstractUnitFileTest +import net.sjrx.intellij.plugins.systemdunitfiles.inspections.InvalidValueInspection +import org.junit.Test + +class ConfigParseWolOptionValueTest : AbstractUnitFileTest() { + + @Test + fun testValidOff() { + // language="unit file (systemd)" + val file = """ + [Link] + WakeOnLan=off + """.trimIndent() + + setupFileInEditor("file.link", file) + enableInspection(InvalidValueInspection::class.java) + val highlights = myFixture.doHighlighting() + assertSize(0, highlights) + } + + @Test + fun testValidSingleFlags() { + // language="unit file (systemd)" + val file = """ + [Link] + WakeOnLan=phy + WakeOnLan=unicast + WakeOnLan=multicast + WakeOnLan=broadcast + WakeOnLan=arp + WakeOnLan=magic + WakeOnLan=secureon + """.trimIndent() + + setupFileInEditor("file.link", file) + enableInspection(InvalidValueInspection::class.java) + val highlights = myFixture.doHighlighting() + assertSize(0, highlights) + } + + @Test + fun testValidMultipleFlags() { + // language="unit file (systemd)" + val file = """ + [Link] + WakeOnLan=phy magic + WakeOnLan=unicast multicast broadcast + WakeOnLan=phy unicast multicast broadcast arp magic secureon + """.trimIndent() + + setupFileInEditor("file.link", file) + enableInspection(InvalidValueInspection::class.java) + val highlights = myFixture.doHighlighting() + assertSize(0, highlights) + } + + @Test + fun testInvalidUnknownFlag() { + // language="unit file (systemd)" + val file = """ + [Link] + WakeOnLan=bogus + """.trimIndent() + + setupFileInEditor("file.link", file) + enableInspection(InvalidValueInspection::class.java) + val highlights = myFixture.doHighlighting() + assertSize(1, highlights) + } + + @Test + fun testInvalidMixedWithUnknown() { + // language="unit file (systemd)" + val file = """ + [Link] + WakeOnLan=phy bogus + """.trimIndent() + + setupFileInEditor("file.link", file) + enableInspection(InvalidValueInspection::class.java) + val highlights = myFixture.doHighlighting() + assertSize(1, highlights) + } + + @Test + fun testInvalidCommaSeparator() { + // language="unit file (systemd)" + val file = """ + [Link] + WakeOnLan=phy,magic + """.trimIndent() + + setupFileInEditor("file.link", file) + enableInspection(InvalidValueInspection::class.java) + val highlights = myFixture.doHighlighting() + assertSize(1, highlights) + } + + @Test + fun testInvalidOffMixed() { + // off is only valid as a standalone value + // language="unit file (systemd)" + val file = """ + [Link] + WakeOnLan=off phy + """.trimIndent() + + setupFileInEditor("file.link", file) + enableInspection(InvalidValueInspection::class.java) + val highlights = myFixture.doHighlighting() + assertSize(1, highlights) + } +}