< Summary - Results for net8.0, Release

Information
Class: LockCheck.Linux.LockInfo
Assembly: LockCheck
File(s): /home/runner/work/LockCheck/LockCheck/src/LockCheck/Linux/LockInfo.cs
Tag: 96_11660771111
Line coverage
85%
Covered lines: 24
Uncovered lines: 4
Coverable lines: 28
Total lines: 80
Line coverage: 85.7%
Branch coverage
50%
Covered branches: 5
Total branches: 10
Branch coverage: 50%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
get_LockType()100%210%
set_LockType(...)100%11100%
get_LockMode()100%210%
set_LockMode(...)100%11100%
get_LockAccess()100%210%
set_LockAccess(...)100%11100%
get_ProcessId()100%11100%
set_ProcessId(...)100%11100%
get_InodeInfo()100%11100%
set_InodeInfo(...)100%11100%
ParseLine(...)50%10.531082.61%

File(s)

/home/runner/work/LockCheck/LockCheck/src/LockCheck/Linux/LockInfo.cs

#LineLine coverage
 1using System;
 2using System.IO;
 3
 4namespace LockCheck.Linux;
 5
 6internal class LockInfo
 7{
 28    public string? LockType { get; private set; }
 29    public string? LockMode { get; private set; }
 210    public string? LockAccess { get; private set; }
 211    public int ProcessId { get; private set; }
 212    public InodeInfo InodeInfo { get; private set; }
 13
 14    public static LockInfo ParseLine(string line)
 15    {
 16        // Each line has 8 (or 9 if you count the "->" marker) fields separated by spaces.
 17        // Additional fields after that are possible, but can be ignored.
 18        // The values for the LockType, LockMode, and LockAccess fields are manifold.
 19        // So we don't interpret them, but just store them as strings. They are only
 20        // provided as informational values anyway and not used for program logic.
 21        //
 22        //  1: POSIX ADVISORY  READ  5433 08:01:7864448 128 128
 23        //  2: FLOCK ADVISORY  WRITE 2001 08:01:7864554 0 EOF
 24        //  3: FLOCK ADVISORY  WRITE 1568 00:2f:32388 0 EOF
 25        //  4: POSIX ADVISORY  WRITE 699 00:16:28457 0 EOF
 26        //  5: POSIX ADVISORY  WRITE 764 00:16:21448 0 0
 27        //  5: -> POSIX ADVISORY  WRITE 766 00:16:21448 0 0
 28        //  6: POSIX ADVISORY  READ  3548 08:01:7867240 1 1
 29        //  7: POSIX ADVISORY  READ  3548 08:01:7865567 1826 2335
 30        //  8: OFDLCK ADVISORY  WRITE -1 08:01:8713209 128 191
 31        //
 32        // The major:minor device numbers (e.g. 08:01:...) might not be actual inode numbers
 33        // in case the respective FS is not a physical one (e.g. not ext4, but tempfs or procfs).
 34        // https://utcc.utoronto.ca/~cks/space/blog/linux/ProcLocksNotes has a nice explanation.
 35        // In our case we don't care, because calling code looks up "in reverse" anyway. That is,
 36        // it has an inode for an actual file/directory and needs this information to see if it
 37        // is "locked".
 38
 239        var span = line.AsSpan();
 240        int count = span.Count(' ') + 1;
 241        if (count < 6)
 42        {
 043            throw new IOException($"Unexpected number of fields {count} in '/proc/locks' ({line})");
 44        }
 45
 246        Span<Range> ranges = count < 128 ? stackalloc Range[count] : new Range[count];
 247        int num = MemoryExtensions.Split(span, ranges, ' ', StringSplitOptions.RemoveEmptyEntries);
 48
 249        int offset = 0;
 250        offset++; // Ignore first item (always the "ID" (e.g. "1:")
 251        if (span[ranges[offset]] == "->")
 52        {
 53            // "Blocked" optional marker
 054            offset++;
 55        }
 56
 257        var result = new LockInfo
 258        {
 259            LockType = span[ranges[offset++]].ToString(),
 260            LockMode = span[ranges[offset++]].ToString(),
 261            LockAccess = span[ranges[offset++]].ToString()
 262        };
 63
 264        if (!int.TryParse(span[ranges[offset++]], out int processId))
 65        {
 066            throw new IOException($"Invalid process ID '{span[ranges[offset]]}' in '/proc/locks' ({line})");
 67        }
 68
 269        result.ProcessId = processId;
 70
 271        if (!InodeInfo.TryParse(span[ranges[offset++]], out var inodeInfo))
 72        {
 073            throw new IOException($"Invalid Inode '{span[ranges[offset]]}' specification in '/proc/locks' ({line})");
 74        }
 75
 276        result.InodeInfo = inodeInfo;
 77
 278        return result;
 79    }
 80}