aboutsummaryrefslogtreecommitdiffstats
path: root/library/cpp/http/io/chunk_ut.cpp
blob: beaeababd25e2b8a04f684cb36b8dd7e6396a71e (plain) (blame)
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
#include "chunk.h"

#include <library/cpp/testing/unittest/registar.h>

#include <util/stream/file.h>
#include <util/system/tempfile.h>
#include <util/stream/null.h>

#define CDATA "./chunkedio"

Y_UNIT_TEST_SUITE(TestChunkedIO) {
    static const char test_data[] = "87s6cfbsudg cuisg s igasidftasiy tfrcua6s";

    TString CombString(const TString& s, size_t chunkSize) {
        TString result;
        for (size_t pos = 0; pos < s.size(); pos += 2 * chunkSize) 
            result += s.substr(pos, chunkSize); 
        return result; 
    } 
 
    void WriteTestData(IOutputStream * stream, TString * contents) {
        contents->clear(); 
        for (size_t i = 0; i < sizeof(test_data); ++i) { 
            stream->Write(test_data, i); 
            contents->append(test_data, i); 
        } 
    } 
 
    void ReadInSmallChunks(IInputStream * stream, TString * contents) {
        char buf[11]; 
        size_t read = 0; 
 
        contents->clear(); 
        do { 
            read = stream->Read(buf, sizeof(buf)); 
            contents->append(buf, read); 
        } while (read > 0); 
    } 
 
    void ReadCombed(IInputStream * stream, TString * contents, size_t chunkSize) {
        Y_ASSERT(chunkSize < 128);
        char buf[128]; 
 
        contents->clear(); 
        while (true) { 
            size_t read = stream->Load(buf, chunkSize); 
            contents->append(buf, read); 
            if (read == 0) 
                break; 
 
            size_t toSkip = chunkSize; 
            size_t skipped = 0; 
            do { 
                skipped = stream->Skip(toSkip); 
                toSkip -= skipped; 
            } while (skipped != 0 && toSkip != 0); 
        } 
    } 
 
    Y_UNIT_TEST(TestChunkedIo) {
        TTempFile tmpFile(CDATA);
        TString tmp;

        {
            TUnbufferedFileOutput fo(CDATA);
            TChunkedOutput co(&fo);
            WriteTestData(&co, &tmp); 
        } 

        { 
            TUnbufferedFileInput fi(CDATA);
            TChunkedInput ci(&fi); 
            TString r;

            ReadInSmallChunks(&ci, &r); 
 
            UNIT_ASSERT_EQUAL(r, tmp); 
        }

        {
            TUnbufferedFileInput fi(CDATA);
            TChunkedInput ci(&fi);
            TString r;

            ReadCombed(&ci, &r, 11); 

            UNIT_ASSERT_EQUAL(r, CombString(tmp, 11)); 
        }
    }

    Y_UNIT_TEST(TestBadChunk) {
        bool hasError = false;

        try {
            TString badChunk = "10\r\nqwerty";
            TMemoryInput mi(badChunk.data(), badChunk.size());
            TChunkedInput ci(&mi);
            TransferData(&ci, &Cnull);
        } catch (...) {
            hasError = true;
        }

        UNIT_ASSERT(hasError);
    }
}