Command line interface negative tests. These tests are designed to test that bad inputs to the cmd line are handled cleanly and that errors are correctly thrown. Note that many tests are mutations of a valid positive test cmd line, to ensure that the base cmd line is valid bef
| 1435 | |
| 1436 | |
| 1437 | class CLINTest(CLITestBase): |
| 1438 | ''' |
| 1439 | Command line interface negative tests. |
| 1440 | |
| 1441 | These tests are designed to test that bad inputs to the cmd line are |
| 1442 | handled cleanly and that errors are correctly thrown. |
| 1443 | |
| 1444 | Note that many tests are mutations of a valid positive test cmd line, |
| 1445 | to ensure that the base cmd line is valid before it is mutated many |
| 1446 | of these tests include a *positive test* to ensure that the starting point |
| 1447 | is actually a valid cmd line (otherwise we could be throwing an |
| 1448 | arbitrary error). |
| 1449 | ''' |
| 1450 | # pylint: disable=too-many-public-methods |
| 1451 | |
| 1452 | def exec(self, cmd: list[str | Path], expect_pass: bool = False) -> None: |
| 1453 | ''' |
| 1454 | Execute a negative test. |
| 1455 | |
| 1456 | Test will automatically fail if: |
| 1457 | |
| 1458 | * The subprocess return code is zero, unless expect_pass is True. |
| 1459 | * The subprocess correctly returned non-zero, but without any error |
| 1460 | message. |
| 1461 | * The subprocess dies with any kind of signal. |
| 1462 | |
| 1463 | Args: |
| 1464 | cmd (list(str)): The cmd to execute. |
| 1465 | expect_pass (bool): True if this cmd is actually expected to |
| 1466 | pass, which is used to validate commands before mutating them. |
| 1467 | ''' |
| 1468 | try: |
| 1469 | cmd_str = [str(x) for x in cmd] |
| 1470 | result = sp.run(cmd_str, stdout=sp.PIPE, stderr=sp.PIPE, |
| 1471 | text=True, check=True) |
| 1472 | rcode = result.returncode |
| 1473 | rstdout = result.stdout |
| 1474 | rstderr = result.stderr |
| 1475 | |
| 1476 | except sp.CalledProcessError as ex: |
| 1477 | rcode = ex.returncode |
| 1478 | rstdout = ex.stdout |
| 1479 | rstderr = ex.stderr |
| 1480 | |
| 1481 | passed = rcode == 0 |
| 1482 | |
| 1483 | # Emit debug logging if needed (negative rcode is a signal) |
| 1484 | bad_result = (passed != expect_pass) or (rcode < 0) |
| 1485 | |
| 1486 | if ASTCENC_CLI_ALWAYS or (bad_result and ASTCENC_CLI_ON_ERROR_NEG): |
| 1487 | print('\n' + ' '.join(cmd_str)) |
| 1488 | |
| 1489 | if ASTCENC_LOG_ALWAYS or (bad_result and ASTCENC_LOG_ON_ERROR_NEG): |
| 1490 | print(rstdout) |
| 1491 | print(rstderr) |
| 1492 | |
| 1493 | # If we expected a pass, then rcode == 0 |
| 1494 | if expect_pass: |
nothing calls this directly
no outgoing calls
no test coverage detected