1// Copyright 2017 The Fuchsia Authors
2//
3// Use of this source code is governed by a MIT-style
4// license that can be found in the LICENSE file or at
5// https://opensource.org/licenses/MIT
6
7#include "tests.h"
8
9#include <err.h>
10#include <inttypes.h>
11#include <platform.h>
12#include <stdio.h>
13#include <string.h>
14
15#include <lib/debuglog.h>
16
17#include <zircon/types.h>
18
19#include <rand.h>
20
21static char buf[1048];
22
23static void uart_blocking_print_test(void)
24{
25    int count;
26
27    for (count = 0 ; count < 5 ; count++) {
28        snprintf(buf, sizeof(buf), "Blocking Test Count %d (FIRST LINE)\n"
29                 "AND THIS SHOULD BE THE SECOND LINE Count %d\n",
30                 count, count);
31        dlog_serial_write(buf, strlen(buf));
32    }
33}
34
35static void uart_nonblocking_print_test(void)
36{
37    int count;
38
39    for (count = 0 ; count < 5 ; count++) {
40        snprintf(buf, sizeof(buf), "NON-Blocking Test Count %d (FIRST LINE)\n"
41                 "AND THIS SHOULD BE THE SECOND LINE Count %d\n",
42                 count, count);
43        __kernel_serial_write(buf, strlen(buf));
44    }
45}
46
47static void uart_print_lots_of_lines(bool block)
48{
49    int count;
50    char *s = buf;
51    int i;
52#define TOTAL_LINES   1024
53#define MAX_SINGLE_LINE_LEN 128
54#define MIN_SINGLE_LINE_LEN  80
55
56    for (count = 0 ; count < TOTAL_LINES ; count++) {
57        if (block)
58            snprintf(buf, 1024, "BLOCK LINE: %d ", count);
59        else
60            snprintf(buf, 1024, "NON-BLOCK LINE: %d ", count);
61        // Pick a random line length between 80 and 128
62        i = (rand() % (MAX_SINGLE_LINE_LEN - MIN_SINGLE_LINE_LEN));
63        i += MIN_SINGLE_LINE_LEN;
64        i -= (int)strlen(buf); // Less what we've already snprintf'ed above
65        s = buf + strlen(buf);
66        while (i--) {
67            if ((rand() % 2) == 0)
68                *s++ = (char)((int)'a' + (int)(rand() % 26));
69            else
70                *s++ = (char)((int)'A' + (int)(rand() % 26));
71        }
72        *s++ = '\n';
73        *s = '\0';
74        if (block)
75            dlog_serial_write(buf, strlen(buf));
76        else
77            __kernel_serial_write(buf, strlen(buf));
78    }
79}
80
81int uart_tests(int, const cmd_args*, uint32_t) {
82    // Print out a few short lines, to test '\n' behavior
83    uart_blocking_print_test();
84    uart_nonblocking_print_test();
85    // Print a few long lines to test bulk output,
86    // both block and non-blocking
87    int i = 100;
88
89    while (i--) {
90        uart_print_lots_of_lines(true);
91        uart_print_lots_of_lines(false);
92        printf("Printed Count = %d\n", 100 - i);
93    }
94
95    return 0;
96}
97