summaryrefslogtreecommitdiffstats
path: root/tools/slang-unit-test/unit-test-process.cpp
blob: 3dccf1eaf658cf30b4caf54806468cb217e0f067 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
// unit-test-process.cpp

#include "../../source/core/slang-string-util.h"
#include "../../source/core/slang-process-util.h"
#include "../../source/core/slang-io.h"

#include "tools/unit-test/slang-unit-test.h"

using namespace Slang;

static SlangResult _countTest(UnitTestContext* context, Index size, Index crashIndex = -1)
{
    RefPtr<Process> process;

    /* Here we are trying to test what happens if the server produces a large amount of data, and
    we just wait for termination. Do we receive all of the data irrespective of how much there is? */

    {
        CommandLine cmdLine;
        
        cmdLine.setExecutable(context->executableDirectory, "test-proxy");
        cmdLine.addArg("count");
        
        StringBuilder buf;
        buf << size;

        cmdLine.addArg(buf);

        if (crashIndex >= 0)
        {
            buf.Clear();
            buf << crashIndex;
            cmdLine.addArg(buf);
        }

        SLANG_RETURN_ON_FAIL(Process::create(cmdLine, Process::Flag::AttachDebugger, process));
    }

    ExecuteResult exeRes;

#if 0
    /* It does block on ~4k of data which matches up with the buffer size, using this mechanism only works up to 4k on windows
    which matches the default pipe buffer size */
    process->waitForTermination();
#endif

    SLANG_RETURN_ON_FAIL(ProcessUtil::readUntilTermination(process, exeRes));

    Index v = 0;
    for (auto line : LineParser(exeRes.standardOutput.getUnownedSlice()))
    {
        if (line.getLength() == 0)
        {
            continue;
        }

        Index value;
        StringUtil::parseInt(line, value);

        if (value != v)
        {
            return SLANG_FAIL;
        }

        v++;
    }

    const Index endIndex = (crashIndex >= 0) ? (crashIndex + 1) : size;

    return v == endIndex ? SLANG_OK : SLANG_FAIL;
}

static SlangResult _countTests(UnitTestContext* context)
{
    const Index sizes[] = { 1, 10, 1000, 1000, 10000, 100000 };
    for (auto size : sizes)
    {
        SLANG_RETURN_ON_FAIL(_countTest(context, size));
        SLANG_RETURN_ON_FAIL(_countTest(context, size, size / 2));
    }

    return SLANG_OK;
}

static SlangResult _reflectTest(UnitTestContext* context)
{
    RefPtr<Process> process;
    {
        CommandLine cmdLine;
        cmdLine.setExecutable(context->executableDirectory, "test-proxy");
        cmdLine.addArg("reflect");
        SLANG_RETURN_ON_FAIL(Process::create(cmdLine, Process::Flag::AttachDebugger, process));
    }

    // Write a bunch of stuff to the stream
    Stream* readStream = process->getStream(Process::StreamType::StdOut);
    Stream* writeStream = process->getStream(Process::StreamType::StdIn);

    List<Byte> readBuffer;

    for (Index i = 0; i < 10000; i++)
    {
        SLANG_RETURN_ON_FAIL(StreamUtil::read(readStream, 0, readBuffer));

        StringBuilder buf;

        buf << i << " Hello " << i << "\n";
        SLANG_RETURN_ON_FAIL(writeStream->write(buf.getBuffer(), buf.getLength()));
    }

    const char end[] = "end\n";
    SLANG_RETURN_ON_FAIL(writeStream->write(end, SLANG_COUNT_OF(end) - 1));
    writeStream->flush();

    SLANG_RETURN_ON_FAIL(StreamUtil::readAll(readStream, 0, readBuffer));

    return SLANG_OK;
}

SLANG_UNIT_TEST(CommandLineProcess)
{
    SLANG_CHECK(SLANG_SUCCEEDED(_countTests(unitTestContext)));

    SLANG_CHECK(SLANG_SUCCEEDED(_reflectTest(unitTestContext)));
}