+#define BUBTF_SIZE 80
+
+void test_qdSockWrite_buildUpBufferThenFlush(void)
+{
+ struct qdSocket sock;
+ char buf[BUBTF_SIZE];
+ int chunkSize, chunk, numChunks;
+ ssize_t ret;
+
+ memcpy(buf, DATA, BUBTF_SIZE);
+
+ for (chunkSize = 1; chunkSize < BUBTF_SIZE; ++chunkSize) {
+ qdSockInit(&sock);
+ qdMock_resetWriteBuf(0); // block all writes for the time being
+
+ numChunks = (BUBTF_SIZE / chunkSize) + ((BUBTF_SIZE % chunkSize) ? 1 : 0);
+
+ for (chunk = 0; chunk < numChunks; ++chunk) {
+ int offset = chunk * chunkSize;
+ int count = chunkSize;
+ if (offset + count > BUBTF_SIZE) {
+ count = BUBTF_SIZE - offset;
+ }
+ ret = qdSockWrite(&sock, &(buf[offset]), count);
+ TEST_ASSERT_EQUAL(0, ret); // nothing written, but should have been queued
+ }
+
+ // Now that we've queued up the writes, unblock the socket and let them flow out
+ qdMock_resetWriteBuf(BUBTF_SIZE);
+
+ ret = qdSockFlush(&sock);
+ TEST_ASSERT_EQUAL(BUBTF_SIZE, ret);
+
+ TEST_ASSERT_EQUAL(0, memcmp(buf, qdMock_getBytesWritten(), BUBTF_SIZE));
+ }
+}
+
+void test_qdSockWrite_bufferAfterPartialFlush(void)
+{
+ struct qdSocket sock;
+ char buf[BUBTF_SIZE];
+ int chunkSize, countWritten;
+ ssize_t ret;
+
+ chunkSize = BUBTF_SIZE / 4;
+
+ memcpy(buf, DATA, BUBTF_SIZE);
+
+ qdSockInit(&sock);
+ qdMock_resetWriteBuf(chunkSize);
+
+ // Write chunkSize bytes, and buffer another chunkSize bytes as pending
+ ret = qdSockWrite(&sock, buf, chunkSize * 2);
+ countWritten = chunkSize * 2;
+ TEST_ASSERT_EQUAL(chunkSize, ret);
+
+ // Should have already written the first chunkSize bytes of buf
+ TEST_ASSERT_EQUAL(0, memcmp(buf, qdMock_getBytesWritten(), chunkSize));
+
+ // Queue a further chunkSize bytes
+ ret = qdSockWrite(&sock, (buf + countWritten), chunkSize);
+ countWritten += chunkSize;
+ TEST_ASSERT_EQUAL(0, ret); // nothing flushed, because socket is "blocked"
+
+ // Flush chunkSize bytes
+ qdMock_resetWriteBuf(chunkSize);
+ ret = qdSockFlush(&sock);
+ TEST_ASSERT_EQUAL(chunkSize, ret);
+ TEST_ASSERT_EQUAL(0, memcmp((buf + chunkSize), qdMock_getBytesWritten(), chunkSize));
+
+ // The story so far:
+ // Wrote (chunkSize * 3) bytes
+ // Flushed (chunkSize * 2) bytes
+ // Not yet written: BUBTF_SIZE - (chunkSize * 3) bytes
+
+ // Queue the rest of the data
+ ret = qdSockWrite(&sock, (buf + countWritten), (BUBTF_SIZE - countWritten));
+ countWritten = BUBTF_SIZE;
+ TEST_ASSERT_EQUAL(0, ret); // socket is blocked, so nothing made it through
+
+ // Flush the rest
+ qdMock_resetWriteBuf(BUBTF_SIZE);
+ ret = qdSockFlush(&sock);
+ TEST_ASSERT_EQUAL(BUBTF_SIZE - (chunkSize * 2), ret);
+ TEST_ASSERT_EQUAL(0, memcmp((buf + (chunkSize * 2)), qdMock_getBytesWritten(), (BUBTF_SIZE - (chunkSize * 2))));
+}