1 #include "mctest.h"
2 #include "mc/mcreq-flush-inl.h"
3 
4 class McFlush : public ::testing::Test {};
5 
6 struct MyCookie {
7     int ncalled;
8     void *exp_kbuf;
MyCookieMyCookie9     MyCookie() : ncalled(0), exp_kbuf(NULL) {}
10 };
11 
12 extern "C" {
13 static void
buf_free_callback(mc_PIPELINE *,const void * cookie,void * kbuf,void * vbuf)14 buf_free_callback(mc_PIPELINE *, const void *cookie, void *kbuf, void *vbuf)
15 {
16     MyCookie *ck = (MyCookie *)cookie;
17     EXPECT_TRUE(kbuf == ck->exp_kbuf);
18     ck->ncalled++;
19 }
20 }
21 
TEST_F(McFlush,testBasicFlush)22 TEST_F(McFlush, testBasicFlush)
23 {
24     CQWrap cq;
25     PacketWrap pw;
26 
27     cq.setBufFreeCallback(buf_free_callback);
28     pw.setContigKey("1234");
29     ASSERT_TRUE(pw.reservePacket(&cq));
30 
31     MyCookie cookie;
32     cookie.exp_kbuf = pw.pktbuf;
33 
34     pw.setCookie(&cookie);
35     pw.setHeaderSize();
36     pw.copyHeader();
37     mcreq_enqueue_packet(pw.pipeline, pw.pkt);
38     mcreq_packet_handled(pw.pipeline, pw.pkt);
39 
40     nb_IOV iovs[10];
41 
42     unsigned toFlush = mcreq_flush_iov_fill(pw.pipeline, iovs, 10, NULL);
43     EXPECT_EQ(28, toFlush);
44     mcreq_flush_done(pw.pipeline, 8, toFlush);
45 
46     toFlush = mcreq_flush_iov_fill(pw.pipeline, iovs, 10, NULL);
47     EXPECT_EQ(20, toFlush);
48     mcreq_flush_done(pw.pipeline, toFlush, toFlush);
49 
50     toFlush = mcreq_flush_iov_fill(pw.pipeline, iovs, 10, NULL);
51     ASSERT_EQ(0, toFlush);
52     ASSERT_EQ(1, cookie.ncalled);
53 }
54 
TEST_F(McFlush,testFlushedUnhandled)55 TEST_F(McFlush, testFlushedUnhandled)
56 {
57     CQWrap cq;
58     PacketWrap pw;
59     cq.setBufFreeCallback(buf_free_callback);
60     pw.setContigKey("1234");
61 
62     MyCookie cookie;
63     cookie.exp_kbuf = pw.pktbuf;
64 
65     ASSERT_TRUE(pw.reservePacket(&cq));
66     pw.setCookie(&cookie);
67     pw.setHeaderSize();
68     pw.copyHeader();
69 
70     mcreq_enqueue_packet(pw.pipeline, pw.pkt);
71 
72     nb_IOV iovs[10];
73     unsigned toFlush = mcreq_flush_iov_fill(pw.pipeline, iovs, 10, NULL);
74     ASSERT_EQ(28, toFlush);
75     mcreq_flush_done(pw.pipeline, toFlush, toFlush);
76 
77     ASSERT_EQ(0, cookie.ncalled);
78     ASSERT_NE(0, pw.pkt->flags & MCREQ_F_FLUSHED);
79 
80     ASSERT_EQ(pw.pkt, mcreq_pipeline_remove(pw.pipeline, pw.pkt->opaque));
81     mcreq_packet_handled(pw.pipeline, pw.pkt);
82     ASSERT_EQ(1, cookie.ncalled);
83 }
84 
TEST_F(McFlush,testFlushCopy)85 TEST_F(McFlush, testFlushCopy)
86 {
87     CQWrap cq;
88     PacketWrap pw;
89     cq.setBufFreeCallback(buf_free_callback);
90     pw.setCopyKey("Hello");
91     ASSERT_TRUE(pw.reservePacket(&cq));
92 
93     MyCookie cookie;
94     pw.setHeaderSize();
95     pw.copyHeader();
96     pw.setCookie(&cookie);
97     mcreq_enqueue_packet(pw.pipeline, pw.pkt);
98 
99     nb_IOV iov[10];
100     unsigned int toFlush = mcreq_flush_iov_fill(pw.pipeline, iov, 10, NULL);
101     mcreq_flush_done(pw.pipeline, toFlush, toFlush);
102     mcreq_pipeline_remove(pw.pipeline, pw.pkt->opaque);
103     mcreq_packet_handled(pw.pipeline, pw.pkt);
104     ASSERT_EQ(0, cookie.ncalled);
105 }
106 
107 
TEST_F(McFlush,testMultiFlush)108 TEST_F(McFlush, testMultiFlush)
109 {
110     CQWrap cq;
111     int counter = 0;
112     const int nitems = 10;
113     MyCookie **cookies;
114 
115     cookies = new MyCookie*[nitems];
116     PacketWrap **pws = new PacketWrap*[nitems];
117     cq.setBufFreeCallback(buf_free_callback);
118 
119     for (int ii = 0; ii < nitems; ii++) {
120         PacketWrap *pw = new PacketWrap;
121         pws[ii] = pw;
122         char curkey[128];
123         sprintf(curkey, "Key_%d", ii);
124         pw->setContigKey(curkey);
125 
126         cookies[ii] = new MyCookie;
127         cookies[ii]->exp_kbuf = pw->pktbuf;
128 
129         ASSERT_TRUE(pw->reservePacket(&cq));
130 
131         pw->setCookie(cookies[ii]);
132         mcreq_enqueue_packet(pw->pipeline, pw->pkt);
133         pw->setHeaderSize();
134         pw->copyHeader();
135         mcreq_packet_handled(pw->pipeline, pw->pkt);
136         mcreq_pipeline_remove(pw->pipeline, pw->pkt->opaque);
137     }
138 
139     for (unsigned ii = 0; ii < cq.npipelines; ii++) {
140         mc_PIPELINE *pipeline = cq.pipelines[ii];
141         nb_IOV iov[10];
142         unsigned toFlush = mcreq_flush_iov_fill(pipeline, iov, 10, NULL);
143         if (toFlush) {
144             mcreq_flush_done(pipeline, toFlush, toFlush);
145         }
146     }
147 
148     for (int ii = 0; ii < nitems; ii++) {
149         ASSERT_EQ(1, cookies[ii]->ncalled);
150         delete cookies[ii];
151         delete pws[ii];
152     }
153     delete[] cookies;
154     delete[] pws;
155 }
156 
TEST_F(McFlush,testPartialFlush)157 TEST_F(McFlush, testPartialFlush)
158 {
159     CQWrap cq;
160     PacketWrap pw;
161     MyCookie cookie;
162 
163     cq.setBufFreeCallback(buf_free_callback);
164     pw.setContigKey("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa");
165     ASSERT_TRUE(pw.reservePacket(&cq));
166     pw.setCookie(&cookie);
167     cookie.exp_kbuf = pw.pktbuf;
168     pw.setHeaderSize();
169     pw.copyHeader();
170     mcreq_enqueue_packet(pw.pipeline, pw.pkt);
171 
172     nb_IOV iov[1];
173     unsigned int toFlush = 0;
174     do {
175         toFlush = mcreq_flush_iov_fill(pw.pipeline, iov, 1, NULL);
176         if (toFlush) {
177             mcreq_flush_done(pw.pipeline, 1, toFlush);
178         }
179     } while (toFlush > 0);
180 
181     ASSERT_NE(0, pw.pkt->flags & MCREQ_F_FLUSHED);
182     mcreq_pipeline_remove(pw.pipeline, pw.pkt->opaque);
183     mcreq_packet_handled(pw.pipeline, pw.pkt);
184     ASSERT_EQ(1, cookie.ncalled);
185 }
186