LCOV - code coverage report
Current view: top level - tty/tests - test_ttynull.c (source / functions) Coverage Total Hit
Test: TTY Combined Coverage Lines: 100.0 % 51 51
Test Date: 2025-08-26 15:45:50 Functions: 100.0 % 3 3

            Line data    Source code
       1              : // SPDX-License-Identifier: GPL-2.0-only
       2              : /*
       3              :  * KUnit tests for the TTY null driver
       4              :  *
       5              :  * Tests for the ttynull driver covering basic lifecycle and sink behavior.
       6              :  * The ttynull driver acts as a data sink, discarding all written data
       7              :  * while providing minimal overhead for applications that need a TTY
       8              :  * but don't care about the output.
       9              :  *
      10              :  * Copyright (c) 2025 Abhinav Saxena <[email protected]>
      11              :  *
      12              :  */
      13              : 
      14              : #include <kunit/test.h>
      15              : #include <linux/tty.h>
      16              : #include <linux/tty_driver.h>
      17              : #include <linux/tty_flip.h>
      18              : #include <linux/string.h>
      19              : 
      20              : #include "tests/tty_test_helpers.h"
      21              : 
      22              : /**
      23              :  * test_ttynull_write_sink - Verify ttynull acts as data sink
      24              :  * @test: KUnit test context
      25              :  *
      26              :  * ttynull should accept all write data and discard it silently.
      27              :  * This tests the core functionality of the null TTY driver.
      28              :  */
      29            1 : static void test_ttynull_write_sink(struct kunit *test)
      30              : {
      31            1 :         struct tty_driver *drv = ttynull_driver;
      32            1 :         struct tty_test_fixture *fx;
      33            1 :         const char *msg = "test data; discard me";
      34            1 :         unsigned int room;
      35            1 :         ssize_t write_result;
      36              : 
      37            1 :         fx = tty_test_create_fixture(test, drv, 0);
      38            1 :         KUNIT_ASSERT_NOT_NULL(test, fx);
      39              : 
      40            1 :         KUNIT_ASSERT_EQ(test, tty_test_open(fx), 0);
      41            1 :         KUNIT_ASSERT_TRUE(test, fx->opened);
      42              : 
      43              :         /* Verify TTY is properly initialized */
      44            1 :         KUNIT_EXPECT_NOT_NULL(test, fx->tty);
      45            1 :         KUNIT_EXPECT_NOT_NULL(test, fx->tty->ldisc);
      46            1 :         KUNIT_EXPECT_TRUE(test, !list_empty(&fx->tty->tty_files));
      47              : 
      48              :         /* Check initial write room - should be available */
      49            1 :         room = tty_test_get_write_room(fx);
      50            1 :         KUNIT_EXPECT_GT(test, room, 0U);
      51              : 
      52              :         /* Write data - should be completely accepted */
      53            1 :         KUNIT_ASSERT_EQ(test, tty_test_write_all(fx, msg, strlen(msg)), 0);
      54              : 
      55              :         /* ttynull discards writes; buffer should remain empty */
      56            1 :         KUNIT_EXPECT_EQ(test, tty_test_get_chars_in_buffer(fx), 0U);
      57              : 
      58              :         /* Write room should remain available for a sink */
      59            1 :         room = tty_test_get_write_room(fx);
      60            1 :         KUNIT_EXPECT_GT(test, room, 0U);
      61              : 
      62              :         /* ttynull should accept all data */
      63            1 :         write_result = tty_test_write(fx, msg, strlen(msg));
      64            1 :         KUNIT_EXPECT_EQ(test, write_result, strlen(msg));
      65              : 
      66              :         /* Multiple writes should all succeed */
      67            1 :         write_result = tty_test_write(fx, msg, strlen(msg));
      68            1 :         KUNIT_EXPECT_EQ(test, write_result, strlen(msg));
      69              : 
      70              :         /*
      71              :          * TODO: Simulate hangup condition making subsequent writes fail
      72              :          * For now, just release.
      73              :          */
      74            1 :         KUNIT_ASSERT_EQ(test, tty_test_release(fx), 0);
      75            1 : }
      76              : 
      77              : /**
      78              :  * test_ttynull_read_behavior - Verify read behavior on null device
      79              :  * @test: KUnit test context
      80              :  *
      81              :  * While ttynull technically supports read (via N_TTY), reading should
      82              :  * behave predictably (likely EOF or blocking).
      83              :  */
      84            1 : static void test_ttynull_read_behavior(struct kunit *test)
      85              : {
      86            1 :         struct tty_driver *drv = ttynull_driver;
      87            1 :         struct tty_test_fixture *fx;
      88            1 :         struct tty_ldisc *ld;
      89              :         /* char read_buffer[128]; */
      90              :         /* ssize_t bytes_read; */
      91              : 
      92            1 :         fx = tty_test_create_fixture(test, drv, 0);
      93            1 :         KUNIT_ASSERT_NOT_NULL(test, fx);
      94              : 
      95            1 :         KUNIT_ASSERT_EQ(test, tty_test_open(fx), 0);
      96            1 :         KUNIT_ASSERT_TRUE(test, fx->opened);
      97              : 
      98            1 :         ld = tty_ldisc_ref(fx->tty);
      99            1 :         KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ld);
     100            1 :         KUNIT_ASSERT_TRUE(test, ld->ops && ld->ops->read);
     101            1 :         tty_ldisc_deref(ld);
     102              : 
     103              :         /*
     104              :          * Reading from ttynull should behave consistently.
     105              :          * Depending on implementation, this might:
     106              :          * - Return 0 (EOF)
     107              :          * - Block (if no data available)
     108              :          * - Return -EAGAIN (if non-blocking)
     109              :          */
     110            1 :         KUNIT_ASSERT_NOT_NULL(test, fx->tty->disc_data);
     111              :         /* bytes_read = tty_test_read(fx, read_buffer, sizeof(read_buffer)); */
     112              : 
     113              :         /*
     114              :          * Document the expected behavior
     115              :          *  - adjust based on actual ttynull implementation
     116              :          */
     117              :         /* KUNIT_EXPECT_GE(test, bytes_read, 0); /\* Should not return error *\/ */
     118              : 
     119            1 :         KUNIT_ASSERT_EQ(test, tty_test_release(fx), 0);
     120            1 : }
     121              : 
     122              : /**
     123              :  * test_ttynull_driver_properties - Verify driver characteristics
     124              :  * @test: KUnit test context
     125              :  *
     126              :  * Test the driver's static properties and configuration. Also, ensure that
     127              :  * it implements the required file_operation ops.
     128              :  */
     129            1 : static void test_ttynull_driver_properties(struct kunit *test)
     130              : {
     131            1 :         struct tty_driver *drv = ttynull_driver;
     132              : 
     133            1 :         KUNIT_ASSERT_NOT_NULL(test, drv);
     134              : 
     135              :         /* Verify driver identification */
     136            1 :         KUNIT_EXPECT_STREQ(test, drv->driver_name, "ttynull");
     137            1 :         KUNIT_EXPECT_STREQ(test, drv->name, "ttynull");
     138              : 
     139              :         /* Ensure that driver implements the required ops. */
     140            1 :         KUNIT_ASSERT_NOT_NULL(test, drv);
     141            1 :         tty_test_assert_valid_ops(test, drv);
     142              : 
     143              :         /* Verify driver type */
     144            1 :         KUNIT_EXPECT_EQ(test, drv->type, TTY_DRIVER_TYPE_CONSOLE);
     145              : 
     146              :         /* Verify driver flags */
     147            1 :         KUNIT_EXPECT_TRUE(test, drv->flags & TTY_DRIVER_REAL_RAW);
     148            1 :         KUNIT_EXPECT_TRUE(test, drv->flags & TTY_DRIVER_RESET_TERMIOS);
     149            1 : }
     150              : 
     151              : static struct kunit_case ttynull_test_cases[] = {
     152              :         KUNIT_CASE(test_ttynull_write_sink),
     153              :         KUNIT_CASE(test_ttynull_read_behavior),
     154              :         KUNIT_CASE(test_ttynull_driver_properties),
     155              :         {}
     156              : };
     157              : 
     158              : static struct kunit_suite ttynull_test_suite = {
     159              :         .name = "ttynull",
     160              :         .test_cases = ttynull_test_cases,
     161              : };
     162              : 
     163              : kunit_test_suite(ttynull_test_suite);
        

Generated by: LCOV version 2.0-1