github.com/ubuntu/ubuntu-report@v1.7.4-0.20240410144652-96f37d845fac/internal/metrics/binmocks_test.go (about) 1 package metrics_test 2 3 import ( 4 "fmt" 5 "os" 6 "strings" 7 "testing" 8 ) 9 10 const ( 11 garbageOutput = `fdsofhoidshf fods gfpds 12 gpofgipogifd 13 fdspfds 14 15 gfoidgo 16 gfdojoi` 17 ) 18 19 // TestMetricsHelperProcess is available to both internal and package test 20 // to mock binaries (it's sub-executed) 21 func TestMetricsHelperProcess(*testing.T) { 22 if os.Getenv("GO_WANT_HELPER_PROCESS") != "1" { 23 return 24 } 25 defer os.Exit(0) 26 27 args := os.Args 28 for len(args) > 0 { 29 if args[0] == "--" { 30 args = args[1:] 31 break 32 } 33 args = args[1:] 34 } 35 if len(args) == 0 { 36 fmt.Fprintf(os.Stderr, "No command\n") 37 os.Exit(2) 38 } 39 40 cmd, args := args[0], args[1:] 41 switch cmd { 42 case "lspci": 43 if args[0] != "-n" { 44 fmt.Fprintf(os.Stderr, "Unexpected lspci arguments: %v\n", args) 45 os.Exit(1) 46 } 47 regularOutput := `00:00.0 0600: 8086:0104 (rev 09) 48 00:02.0 0300: 8086:0126 (rev 09) 49 00:16.0 0780: 8086:1c3a (rev 04) 50 00:16.3 0700: 8086:1c3d (rev 04) 51 00:19.0 0200: 8086:1502 (rev 04)` 52 switch args[1] { 53 case "one gpu": 54 fmt.Println(regularOutput) 55 case "multiple gpus": 56 fmt.Println(regularOutput) 57 fmt.Println("00:02.0 0300: 8086:0127 (rev 09)") 58 case "no revision number": 59 fmt.Println("00:02.0 0300: 8086:0126") 60 case "no gpu": 61 fmt.Println(`00:00.0 0600: 8086:0104 (rev 09) 62 00:16.0 0780: 8086:1c3a (rev 04) 63 00:16.3 0700: 8086:1c3d (rev 04) 64 00:19.0 0200: 8086:1502 (rev 04)`) 65 case "hexa numbers": 66 fmt.Println("00:02.0 0300: 8b86:a126 (rev 09)") 67 case "empty": 68 case "malformed gpu line": 69 fmt.Println("00:02.0 0300: 80860127 (rev 09)") 70 case "garbage": 71 fmt.Println(garbageOutput) 72 case "fail": 73 fmt.Println(regularOutput) // still print content 74 os.Exit(1) 75 } 76 77 case "lscpu": 78 if args[0] != "-J" { 79 fmt.Fprintf(os.Stderr, "Unexpected lscpu arguments: %v\n", args) 80 os.Exit(1) 81 } 82 regularOutput := `{ 83 "lscpu": [ 84 {"field": "Architecture:", "data": "x86_64"}, 85 {"field": "CPU op-mode(s):", "data": "32-bit, 64-bit"}, 86 {"field": "Byte Order:", "data": "Little Endian"}, 87 {"field": "CPU(s):", "data": "8"}, 88 {"field": "On-line CPU(s) list:", "data": "0-7"}, 89 {"field": "Thread(s) per core:", "data": "2"}, 90 {"field": "Core(s) per socket:", "data": "4"}, 91 {"field": "Socket(s):", "data": "1"}, 92 {"field": "NUMA node(s):", "data": "1"}, 93 {"field": "Vendor ID:", "data": "Genuine"}, 94 {"field": "CPU family:", "data": "6"}, 95 {"field": "Model:", "data": "158"}, 96 {"field": "Model name:", "data": "Intuis Corus i5-8300H CPU @ 2.30GHz"}, 97 {"field": "Stepping:", "data": "10"}, 98 {"field": "CPU MHz:", "data": "3419.835"}, 99 {"field": "CPU max MHz:", "data": "4000.0000"}, 100 {"field": "CPU min MHz:", "data": "800.0000"}, 101 {"field": "BogoMIPS:", "data": "4608.00"}, 102 {"field": "Virtualization:", "data": "VT-x"}, 103 {"field": "L1d cache:", "data": "32K"}, 104 {"field": "L1i cache:", "data": "32K"}, 105 {"field": "L2 cache:", "data": "256K"}, 106 {"field": "L3 cache:", "data": "8192K"}, 107 {"field": "NUMA node0 CPU(s):", "data": "0-7"}, 108 {"field": "Flags:", "data": "fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx pdpe1gb rdtscp lm constant_tsc art arch_perfmon pebs bts rep_good nopl xtopology nonstop_tsc cpuid aperfmperf tsc_known_freq pni pclmulqdq dtes64 monitor ds_cpl vmx est tm2 ssse3 sdbg fma cx16 xtpr pdcm pcid sse4_1 sse4_2 x2apic movbe popcnt tsc_deadline_timer aes xsave avx f16c rdrand lahf_lm abm 3dnowprefetch cpuid_fault epb invpcid_single pti ibrs ibpb stibp tpr_shadow vnmi flexpriority ept vpid fsgsbase tsc_adjust bmi1 avx2 smep bmi2 erms invpcid mpx rdseed adx smap clflushopt intel_pt xsaveopt xsavec xgetbv1 xsaves dtherm ida arat pln pts hwp hwp_notify hwp_act_window hwp_epp"} 109 ] 110 }` 111 switch args[1] { 112 case "regular": 113 fmt.Println(regularOutput) 114 case "missing one expected field": 115 fmt.Println(strings.Replace(regularOutput, "Vendor ID:", "", -1)) 116 case "missing one optional field": 117 fmt.Println(strings.Replace(regularOutput, "Virtualization vendor:", "", -1)) 118 case "virtualized": 119 fmt.Println(regularOutput) 120 fmt.Println(`{"field": "Hypervisor vendor:", "data": "KVM"}, 121 {"field": "Virtualization type:", "data": "full"},`) 122 case "without space": 123 fmt.Println(`{ 124 "lscpu": [ 125 {"field":"Architecture:","data":"x86_64"}, 126 {"field":"CPU op-mode(s):","data":"32-bit, 64-bit"}, 127 {"field":"Byte Order:","data":"Little Endian"}, 128 {"field":"CPU(s):","data":"8"}, 129 {"field":"On-line CPU(s) list:","data":"0-7"}, 130 {"field":"Thread(s) per core:","data":"2"}, 131 {"field":"Core(s) per socket:","data":"4"}, 132 {"field":"Socket(s):","data":"1"}, 133 {"field":"NUMA node(s):","data":"1"}, 134 {"field":"Vendor ID:","data":"Genuine"}, 135 {"field":"CPU family:","data":"6"}, 136 {"field":"Model:","data":"158"}, 137 {"field":"Model name:","data":"Intuis Corus i5-8300H CPU @ 2.30GHz"}, 138 {"field":"Stepping:","data":"10"}, 139 {"field":"CPU MHz:","data":"3419.835"}, 140 {"field":"CPU max MHz:","data":"4000.0000"}, 141 {"field":"CPU min MHz:","data":"800.0000"}, 142 {"field":"BogoMIPS:","data":"4608.00"}, 143 {"field":"Virtualization:","data":"VT-x"}, 144 {"field":"L1d cache:","data":"32K"}, 145 {"field":"L1i cache:","data":"32K"}, 146 {"field":"L2 cache:","data":"256K"}, 147 {"field":"L3 cache:","data":"8192K"}, 148 {"field":"NUMA node0 CPU(s):","data":"0-7"}, 149 {"field":"Flags:","data":"fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx pdpe1gb rdtscp lm constant_tsc art arch_perfmon pebs bts rep_good nopl xtopology nonstop_tsc cpuid aperfmperf tsc_known_freq pni pclmulqdq dtes64 monitor ds_cpl vmx est tm2 ssse3 sdbg fma cx16 xtpr pdcm pcid sse4_1 sse4_2 x2apic movbe popcnt tsc_deadline_timer aes xsave avx f16c rdrand lahf_lm abm 3dnowprefetch cpuid_fault epb invpcid_single pti ibrs ibpb stibp tpr_shadow vnmi flexpriority ept vpid fsgsbase tsc_adjust bmi1 avx2 smep bmi2 erms invpcid mpx rdseed adx smap clflushopt intel_pt xsaveopt xsavec xgetbv1 xsaves dtherm ida arat pln pts hwp hwp_notify hwp_act_window hwp_epp"} 150 ] 151 }`) 152 case "empty": 153 case "garbage": 154 fmt.Println(garbageOutput) 155 case "fail": 156 fmt.Println(regularOutput) // still print content 157 os.Exit(1) 158 } 159 160 case "xrandr": 161 regularOutput := `Screen 0: minimum 320 x 200, current 1920 x 1848, maximum 8192 x 8192 162 LVDS-1 connected primary 1366x768+0+1080 (normal left inverted right x axis y axis) 277mm x 156mm 163 1366x768 60.02*+ 164 1360x768 59.80 59.96 165 1024x768 60.04 60.00 166 HDMI-1 disconnected (normal left inverted right x axis y axis) 167 DP-1 disconnected (normal left inverted right x axis y axis)` 168 switch args[0] { 169 case "one screen": 170 fmt.Println(regularOutput) 171 case "multiple screens": 172 fmt.Println(regularOutput) 173 fmt.Println(`VGA-1 connected 1920x1080+0+0 (normal left inverted right x axis y axis) 510mm x 287mm 174 1920x1080 60.00*+ 175 1600x1200 60.00 176 1680x1050 59.95 `) 177 case "no screen": 178 fmt.Println("") 179 case "chosen resolution not first": 180 fmt.Println(`VGA-1 connected 1920x1080+0+0 (normal left inverted right x axis y axis) 510mm x 287mm 181 1920x1080 60.00 182 1600x1200 60.00*+ 183 1680x1050 59.95 `) 184 case "chosen resolution not preferred": 185 fmt.Println(`VGA-1 connected 1920x1080+0+0 (normal left inverted right x axis y axis) 510mm x 287mm 186 1920x1080 60.00* 187 1600x1200 60.00 + 188 1680x1050 59.95 `) 189 case "multiple frequencies for resolution": 190 fmt.Println(`VGA-1 connected 1920x1080+0+0 (normal left inverted right x axis y axis) 510mm x 287mm 191 1920x1080 60.00*+ 59.94 50.00 60.05 60.00 50.04`) 192 case "multiple frequencies select other resolution": 193 fmt.Println(`VGA-1 connected 1920x1080+0+0 (normal left inverted right x axis y axis) 510mm x 287mm 194 1920x1080 60.00 + 59.94 50.00* 60.05 60.00 50.04`) 195 case "multiple frequencies select other resolution on non preferred": 196 fmt.Println(`VGA-1 connected 1920x1080+0+0 (normal left inverted right x axis y axis) 510mm x 287mm 197 1920x1080 60.00 59.94 50.00* 60.05 60.00 50.04 198 1600x1200 60.00 +`) 199 case "no specified screen size": 200 fmt.Println(`VGA-1 connected 1920x1080+0+0 (normal left inverted right x axis y axis) 201 1920x1080 60.00*+ 202 1600x1200 60.00 203 1680x1050 59.95 `) 204 case "no chosen resolution": 205 fmt.Println(`VGA-1 connected 1920x1080+0+0 (normal left inverted right x axis y axis) 510mm x 287mm 206 1920x1080 60.00 207 1600x1200 60.00 208 1680x1050 59.95 `) 209 case "empty": 210 case "malformed screen line": 211 fmt.Println(`VGA-1 connected 1920x1080+0+0 (normal left inverted right x axis y axis) 510m x 287mm 212 1920x108160.00*+`) 213 case "garbage": 214 fmt.Println(garbageOutput) 215 case "fail": 216 fmt.Println(regularOutput) // still print content 217 os.Exit(1) 218 } 219 220 case "df": 221 regularOutput := `Sys. de fichiers blocs de 1K Utilisé Disponible Uti% Monté sur 222 udev 3992524 0 3992524 0% /dev 223 tmpfs 804812 2104 802708 1% /run 224 /dev/sda5 159431364 142492784 8816880 95% / 225 tmpfs 4024048 152728 3871320 4% /dev/shm 226 tmpfs 5120 4 5116 1% /run/lock` 227 switch args[0] { 228 case "one partition": 229 fmt.Println(regularOutput) 230 case "multiple partitions": 231 fmt.Println(regularOutput) 232 fmt.Println(`/dev/sdc2 309681364 102492784 2816880 5% /something`) 233 case "no partitions": 234 fmt.Println("") 235 case "filters loop devices": 236 fmt.Println(regularOutput) 237 fmt.Println(`/dev/loop0 132480 132480 0 100% /snap/gnome-3-26-1604/27 238 /dev/loop2 83584 83584 0 100% /snap/core/4110`) 239 case "empty": 240 case "malformed partition line string": 241 fmt.Println(`/dev/sda5 a159431364 142492784 8816880 95% /`) 242 case "malformed partition line one field": 243 fmt.Println(`/dev/sda5`) 244 case "garbage": 245 fmt.Println(garbageOutput) 246 case "fail": 247 fmt.Println(regularOutput) // still print content 248 os.Exit(1) 249 } 250 251 case "dpkg": 252 if args[0] != "--print-architecture" && args[0] != "--status" { 253 fmt.Fprintf(os.Stderr, "Unexpected dpkg arguments: %v\n", args) 254 os.Exit(1) 255 } 256 switch args[0] { 257 case "--print-architecture": 258 switch args[1] { 259 case "regular": 260 fmt.Println("amd64") 261 case "empty": 262 case "fail": 263 fmt.Println("amd64") // still print content 264 os.Exit(1) 265 } 266 case "--status": 267 if args[1] != "libc6" { 268 fmt.Fprintf(os.Stderr, "Unexpected dpkg --status arguments: %v\n", args) 269 os.Exit(1) 270 } 271 regularOutput := `Package: libc6 272 Status: install ok installed 273 Priority: optional 274 Section: libs 275 Installed-Size: 13111 276 Maintainer: Ubuntu Developers <ubuntu-devel-discuss@lists.ubuntu.com> 277 Architecture: amd64 278 Multi-Arch: same 279 Source: glibc 280 Version: 2.33-0ubuntu5 281 Replaces: libc6-amd64 282 Depends: libgcc-s1, libcrypt1 (>= 1:4.4.10-10ubuntu4) 283 Recommends: libidn2-0 (>= 2.0.5~), libnss-nis, libnss-nisplus 284 Suggests: glibc-doc, debconf | debconf-2.0, locales 285 Breaks: busybox (<< 1.30.1-6), fakeroot (<< 1.25.3-1.1ubuntu2~), hurd (<< 1:0.9.git20170910-1), ioquake3 (<< 1.36+u20200211.f2c61c1~dfsg-2~), iraf-fitsutil (<< 2018.07.06-4), libgegl-0.4-0 (<< 0.4.18), libtirpc1 (<< 0.2.3), locales (<< 2.33), locales-all (<< 2.33), macs (<< 2.2.7.1-3~), nocache (<< 1.1-1~), nscd (<< 2.33), openarena (<< 0.8.8+dfsg-4~), openssh-server (<< 1:8.2p1-4), r-cran-later (<< 0.7.5+dfsg-2), wcc (<< 0.0.2+dfsg-3) 286 Conffiles: 287 /etc/ld.so.conf.d/x86_64-linux-gnu.conf d4e7a7b88a71b5ffd9e2644e71a0cfab 288 Description: GNU C Library: Shared libraries 289 Contains the standard libraries that are used by nearly all programs on 290 the system. This package includes shared versions of the standard C library 291 and the standard math library, as well as many others. 292 Homepage: https://www.gnu.org/software/libc/libc.html 293 Original-Maintainer: GNU Libc Maintainers <debian-glibc@lists.debian.org> 294 Original-Vcs-Browser: https://salsa.debian.org/glibc-team/glibc 295 Original-Vcs-Git: https://salsa.debian.org/glibc-team/glibc.git` 296 297 switch args[2] { 298 case "regular", "no hwcap": 299 fmt.Println(regularOutput) 300 301 case "old version": 302 fmt.Println(`Package: libc6 303 Status: install ok installed 304 Priority: optional 305 Section: libs 306 Installed-Size: 13111 307 Maintainer: Ubuntu Developers <ubuntu-devel-discuss@lists.ubuntu.com> 308 Architecture: amd64 309 Multi-Arch: same 310 Source: glibc 311 Version: 2.32 312 Replaces: libc6-amd64 313 Depends: libgcc-s1, libcrypt1 (>= 1:4.4.10-10ubuntu4) 314 Recommends: libidn2-0 (>= 2.0.5~), libnss-nis, libnss-nisplus 315 Suggests: glibc-doc, debconf | debconf-2.0, locales 316 Breaks: busybox (<< 1.30.1-6), fakeroot (<< 1.25.3-1.1ubuntu2~), hurd (<< 1:0.9.git20170910-1), ioquake3 (<< 1.36+u20200211.f2c61c1~dfsg-2~), iraf-fitsutil (<< 2018.07.06-4), libgegl-0.4-0 (<< 0.4.18), libtirpc1 (<< 0.2.3), locales (<< 2.33), locales-all (<< 2.33), macs (<< 2.2.7.1-3~), nocache (<< 1.1-1~), nscd (<< 2.33), openarena (<< 0.8.8+dfsg-4~), openssh-server (<< 1:8.2p1-4), r-cran-later (<< 0.7.5+dfsg-2), wcc (<< 0.0.2+dfsg-3) 317 Conffiles: 318 /etc/ld.so.conf.d/x86_64-linux-gnu.conf d4e7a7b88a71b5ffd9e2644e71a0cfab 319 Description: GNU C Library: Shared libraries 320 Contains the standard libraries that are used by nearly all programs on 321 the system. This package includes shared versions of the standard C library 322 and the standard math library, as well as many others. 323 Homepage: https://www.gnu.org/software/libc/libc.html 324 Original-Maintainer: GNU Libc Maintainers <debian-glibc@lists.debian.org> 325 Original-Vcs-Browser: https://salsa.debian.org/glibc-team/glibc 326 Original-Vcs-Git: https://salsa.debian.org/glibc-team/glibc.git`) 327 328 case "not installed": 329 fmt.Println(`dpkg-query: package 'libc6' is not installed and no information is available 330 Use dpkg --info (= dpkg-deb --info) to examine archive files.`) 331 case "empty:": 332 case "fail": 333 // still print content 334 fmt.Println(regularOutput) 335 os.Exit(1) 336 } 337 338 } 339 340 case "/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2": 341 if args[0] != "--help" { 342 fmt.Fprintf(os.Stderr, "Unexpected ld arguments: %v\n", args) 343 os.Exit(1) 344 } 345 regularOutput := `Usage: /lib/x86_64-linux-gnu/ld-linux-x86-64.so.2 [OPTION]... EXECUTABLE-FILE [ARGS-FOR-PROGRAM...] 346 You have invoked 'ld.so', the program interpreter for dynamically-linked 347 ELF programs. Usually, the program interpreter is invoked automatically 348 when a dynamically-linked executable is started. 349 350 You may invoke the program interpreter program directly from the command 351 line to load and run an ELF executable file; this is like executing that 352 file itself, but always uses the program interpreter you invoked, 353 instead of the program interpreter specified in the executable file you 354 run. Invoking the program interpreter directly provides access to 355 additional diagnostics, and changing the dynamic linker behavior without 356 setting environment variables (which would be inherited by subprocesses). 357 358 --list list all dependencies and how they are resolved 359 --verify verify that given object really is a dynamically linked 360 object we can handle 361 --inhibit-cache Do not use /etc/ld.so.cache 362 --library-path PATH use given PATH instead of content of the environment 363 variable LD_LIBRARY_PATH 364 --glibc-hwcaps-prepend LIST 365 search glibc-hwcaps subdirectories in LIST 366 --glibc-hwcaps-mask LIST 367 only search built-in subdirectories if in LIST 368 --inhibit-rpath LIST ignore RUNPATH and RPATH information in object names 369 in LIST 370 --audit LIST use objects named in LIST as auditors 371 --preload LIST preload objects named in LIST 372 --argv0 STRING set argv[0] to STRING before running 373 --list-tunables list all tunables with minimum and maximum values 374 --list-diagnostics list diagnostics information 375 --help display this help and exit 376 --version output version information and exit 377 378 This program interpreter self-identifies as: /lib64/ld-linux-x86-64.so.2 379 380 Shared library search path: 381 (libraries located via /etc/ld.so.cache) 382 /lib/x86_64-linux-gnu (system search path) 383 /usr/lib/x86_64-linux-gnu (system search path) 384 /lib (system search path) 385 /usr/lib (system search path) 386 387 Subdirectories of glibc-hwcaps directories, in priority order: 388 x86-64-v4 389 x86-64-v3 (supported, searched) 390 x86-64-v2 (supported, searched) 391 392 Legacy HWCAP subdirectories under library search path directories: 393 x86_64 (AT_PLATFORM; supported, searched) 394 tls (supported, searched) 395 avx512_1 396 x86_64 (supported, searched)` 397 398 switch args[1] { 399 case "regular": 400 fmt.Println(regularOutput) 401 case "no hwcap": 402 fmt.Println(`Usage: /lib/x86_64-linux-gnu/ld-linux-x86-64.so.2 [OPTION]... EXECUTABLE-FILE [ARGS-FOR-PROGRAM...] 403 You have invoked 'ld.so', the program interpreter for dynamically-linked 404 ELF programs. Usually, the program interpreter is invoked automatically 405 when a dynamically-linked executable is started. 406 407 You may invoke the program interpreter program directly from the command 408 line to load and run an ELF executable file; this is like executing that 409 file itself, but always uses the program interpreter you invoked, 410 instead of the program interpreter specified in the executable file you 411 run. Invoking the program interpreter directly provides access to 412 additional diagnostics, and changing the dynamic linker behavior without 413 setting environment variables (which would be inherited by subprocesses). 414 415 --list list all dependencies and how they are resolved 416 --verify verify that given object really is a dynamically linked 417 object we can handle 418 --inhibit-cache Do not use /etc/ld.so.cache 419 --library-path PATH use given PATH instead of content of the environment 420 variable LD_LIBRARY_PATH 421 --glibc-hwcaps-prepend LIST 422 search glibc-hwcaps subdirectories in LIST 423 --glibc-hwcaps-mask LIST 424 only search built-in subdirectories if in LIST 425 --inhibit-rpath LIST ignore RUNPATH and RPATH information in object names 426 in LIST 427 --audit LIST use objects named in LIST as auditors 428 --preload LIST preload objects named in LIST 429 --argv0 STRING set argv[0] to STRING before running 430 --list-tunables list all tunables with minimum and maximum values 431 --list-diagnostics list diagnostics information 432 --help display this help and exit 433 --version output version information and exit 434 435 This program interpreter self-identifies as: /lib64/ld-linux-x86-64.so.2 436 437 Shared library search path: 438 (libraries located via /etc/ld.so.cache) 439 /lib/x86_64-linux-gnu (system search path) 440 /usr/lib/x86_64-linux-gnu (system search path) 441 /lib (system search path) 442 /usr/lib (system search path) 443 444 Subdirectories of glibc-hwcaps directories, in priority order: 445 x86-64-v4 446 x86-64-v3 447 x86-64-v2 448 449 Legacy HWCAP subdirectories under library search path directories: 450 x86_64 (AT_PLATFORM; supported, searched) 451 tls (supported, searched) 452 avx512_1 453 x86_64 (supported, searched)`) 454 455 case "empty": 456 case "fail": 457 fmt.Println(regularOutput) 458 os.Exit(1) 459 } 460 } 461 }