Example #1
0
func TestChunkMergers(t *testing.T) {
	Convey("ChunkMergers work properly.", t, func() {
		Convey("UnreliableUnorderedChunkMergers work properly", func() {
			chunks := []core.Chunk{
				// 3: "ABCD"
				core.Chunk{
					Sequence:    3,
					Subsequence: 1,
					Data:        []byte("ABC"),
				},
				core.Chunk{
					Sequence:    4,
					Subsequence: 2,
					Data:        []byte("D"),
				},

				// 7: "abcdefghk"
				core.Chunk{
					Sequence:    7,
					Subsequence: 1,
					Data:        []byte("abc"),
				},
				core.Chunk{
					Sequence:    8,
					Subsequence: 2,
					Data:        []byte("def"),
				},
				core.Chunk{
					Sequence:    9,
					Subsequence: 3,
					Data:        []byte("ghk"),
				},
				core.Chunk{
					Sequence:    10,
					Subsequence: 4,
					Data:        []byte(""),
				},

				// 12: "123"
				core.Chunk{
					Sequence:    12,
					Subsequence: 0,
					Data:        []byte("123"),
				},
			}
			Convey("when chunks come in order", func() {
				cm := core.MakeUnreliableUnorderedChunkMerger(10)
				packets := cm.AddChunk(chunks[0])
				So(len(packets), ShouldEqual, 0)
				packets = cm.AddChunk(chunks[1])
				So(len(packets), ShouldEqual, 1)
				So(string(packets[0]), ShouldEqual, "ABCD")

				packets = cm.AddChunk(chunks[2])
				So(len(packets), ShouldEqual, 0)
				packets = cm.AddChunk(chunks[3])
				So(len(packets), ShouldEqual, 0)
				packets = cm.AddChunk(chunks[4])
				So(len(packets), ShouldEqual, 0)
				packets = cm.AddChunk(chunks[5])
				So(len(packets), ShouldEqual, 1)
				So(string(packets[0]), ShouldEqual, "abcdefghk")

				packets = cm.AddChunk(chunks[6])
				So(len(packets), ShouldEqual, 1)
				So(string(packets[0]), ShouldEqual, "123")
			})

			Convey("when chunks come out of order", func() {
				cm := core.MakeUnreliableUnorderedChunkMerger(10)
				packets := cm.AddChunk(chunks[1])
				So(len(packets), ShouldEqual, 0)
				packets = cm.AddChunk(chunks[0])
				So(len(packets), ShouldEqual, 1)
				So(string(packets[0]), ShouldEqual, "ABCD")

				packets = cm.AddChunk(chunks[5])
				So(len(packets), ShouldEqual, 0)
				packets = cm.AddChunk(chunks[4])
				So(len(packets), ShouldEqual, 0)
				packets = cm.AddChunk(chunks[3])
				So(len(packets), ShouldEqual, 0)
				packets = cm.AddChunk(chunks[2])
				So(len(packets), ShouldEqual, 1)
				So(string(packets[0]), ShouldEqual, "abcdefghk")

				packets = cm.AddChunk(chunks[6])
				So(len(packets), ShouldEqual, 1)
				So(string(packets[0]), ShouldEqual, "123")
			})

			Convey("when duplicate chunks show up", func() {
				cm := core.MakeUnreliableUnorderedChunkMerger(10)
				packets := cm.AddChunk(chunks[0])
				So(len(packets), ShouldEqual, 0)
				packets = cm.AddChunk(chunks[1])
				So(len(packets), ShouldEqual, 1)
				So(string(packets[0]), ShouldEqual, "ABCD")

				// Repeat that packet, shouldn't get anything back.
				packets = cm.AddChunk(chunks[0])
				So(len(packets), ShouldEqual, 0)
				packets = cm.AddChunk(chunks[1])
				So(len(packets), ShouldEqual, 0)

				packets = cm.AddChunk(chunks[2])
				So(len(packets), ShouldEqual, 0)
				packets = cm.AddChunk(chunks[2])
				So(len(packets), ShouldEqual, 0)
				packets = cm.AddChunk(chunks[2])
				So(len(packets), ShouldEqual, 0)
				packets = cm.AddChunk(chunks[3])
				So(len(packets), ShouldEqual, 0)
				packets = cm.AddChunk(chunks[3])
				So(len(packets), ShouldEqual, 0)
				packets = cm.AddChunk(chunks[3])
				So(len(packets), ShouldEqual, 0)
				packets = cm.AddChunk(chunks[4])
				So(len(packets), ShouldEqual, 0)
				packets = cm.AddChunk(chunks[4])
				So(len(packets), ShouldEqual, 0)
				packets = cm.AddChunk(chunks[5])
				So(len(packets), ShouldEqual, 1)
				So(string(packets[0]), ShouldEqual, "abcdefghk")
				packets = cm.AddChunk(chunks[5])
				So(len(packets), ShouldEqual, 0)
				packets = cm.AddChunk(chunks[5])
				So(len(packets), ShouldEqual, 0)

				packets = cm.AddChunk(chunks[6])
				So(len(packets), ShouldEqual, 1)
				So(string(packets[0]), ShouldEqual, "123")
				packets = cm.AddChunk(chunks[6])
				So(len(packets), ShouldEqual, 0)
				packets = cm.AddChunk(chunks[6])
				So(len(packets), ShouldEqual, 0)
			})

			Convey("when old chunks show up", func() {
				cm := core.MakeUnreliableUnorderedChunkMerger(2)
				packets := cm.AddChunk(chunks[0])
				So(len(packets), ShouldEqual, 0)

				// This makes all of the other chunks look old, we shouldn't get back anything for them
				// now.
				packets = cm.AddChunk(chunks[6])
				So(len(packets), ShouldEqual, 1)

				packets = cm.AddChunk(chunks[1])
				So(len(packets), ShouldEqual, 0)

				packets = cm.AddChunk(chunks[2])
				So(len(packets), ShouldEqual, 0)
				packets = cm.AddChunk(chunks[3])
				So(len(packets), ShouldEqual, 0)
				packets = cm.AddChunk(chunks[4])
				So(len(packets), ShouldEqual, 0)
				packets = cm.AddChunk(chunks[5])
				So(len(packets), ShouldEqual, 0)

			})
		})

		Convey("UnreliableOrderedChunkMergers work properly", func() {
			chunks := []core.Chunk{
				// 3: "ABCD"
				core.Chunk{
					Sequence:    3,
					Subsequence: 1,
					Data:        []byte("ABC"),
				},
				core.Chunk{
					Sequence:    4,
					Subsequence: 2,
					Data:        []byte("D"),
				},

				// 7: "abcdefghk"
				core.Chunk{
					Sequence:    7,
					Subsequence: 1,
					Data:        []byte("abc"),
				},
				core.Chunk{
					Sequence:    8,
					Subsequence: 2,
					Data:        []byte("def"),
				},
				core.Chunk{
					Sequence:    9,
					Subsequence: 3,
					Data:        []byte("ghk"),
				},
				core.Chunk{
					Sequence:    10,
					Subsequence: 4,
					Data:        []byte(""),
				},

				// 12: "123"
				core.Chunk{
					Sequence:    12,
					Subsequence: 0,
					Data:        []byte("123"),
				},
			}
			Convey("when chunks come in order", func() {
				cm := core.MakeUnreliableOrderedChunkMerger(100)
				packets := cm.AddChunk(chunks[0])
				So(len(packets), ShouldEqual, 0)
				packets = cm.AddChunk(chunks[1])
				So(len(packets), ShouldEqual, 1)
				So(string(packets[0]), ShouldEqual, "ABCD")

				packets = cm.AddChunk(chunks[2])
				So(len(packets), ShouldEqual, 0)
				packets = cm.AddChunk(chunks[3])
				So(len(packets), ShouldEqual, 0)
				packets = cm.AddChunk(chunks[4])
				So(len(packets), ShouldEqual, 0)
				packets = cm.AddChunk(chunks[5])
				So(len(packets), ShouldEqual, 1)
				So(string(packets[0]), ShouldEqual, "abcdefghk")

				packets = cm.AddChunk(chunks[6])
				So(len(packets), ShouldEqual, 1)
				So(string(packets[0]), ShouldEqual, "123")
			})

			Convey("when chunks come out of order", func() {
				cm := core.MakeUnreliableOrderedChunkMerger(100)
				packets := cm.AddChunk(chunks[1])
				So(len(packets), ShouldEqual, 0)
				packets = cm.AddChunk(chunks[0])
				So(len(packets), ShouldEqual, 1)
				So(string(packets[0]), ShouldEqual, "ABCD")

				packets = cm.AddChunk(chunks[5])
				So(len(packets), ShouldEqual, 0)
				packets = cm.AddChunk(chunks[4])
				So(len(packets), ShouldEqual, 0)
				packets = cm.AddChunk(chunks[3])
				So(len(packets), ShouldEqual, 0)
				packets = cm.AddChunk(chunks[2])
				So(len(packets), ShouldEqual, 1)
				So(string(packets[0]), ShouldEqual, "abcdefghk")

				packets = cm.AddChunk(chunks[6])
				So(len(packets), ShouldEqual, 1)
				So(string(packets[0]), ShouldEqual, "123")
			})

			Convey("when packets come out of order", func() {
				cm := core.MakeUnreliableOrderedChunkMerger(100)
				packets := cm.AddChunk(chunks[1])
				So(len(packets), ShouldEqual, 0)

				packets = cm.AddChunk(chunks[5])
				So(len(packets), ShouldEqual, 0)
				packets = cm.AddChunk(chunks[4])
				So(len(packets), ShouldEqual, 0)
				packets = cm.AddChunk(chunks[3])
				So(len(packets), ShouldEqual, 0)
				packets = cm.AddChunk(chunks[2])
				So(len(packets), ShouldEqual, 1)
				So(string(packets[0]), ShouldEqual, "abcdefghk")

				// Finish the first packet, we shouldn't get it.
				packets = cm.AddChunk(chunks[0])
				So(len(packets), ShouldEqual, 0)

				packets = cm.AddChunk(chunks[6])
				So(len(packets), ShouldEqual, 1)
				So(string(packets[0]), ShouldEqual, "123")
			})

			Convey("when duplicate chunks show up", func() {
				cm := core.MakeUnreliableOrderedChunkMerger(100)
				packets := cm.AddChunk(chunks[0])
				So(len(packets), ShouldEqual, 0)
				packets = cm.AddChunk(chunks[1])
				So(len(packets), ShouldEqual, 1)
				So(string(packets[0]), ShouldEqual, "ABCD")

				// Repeat that packet, shouldn't get anything back.
				packets = cm.AddChunk(chunks[0])
				So(len(packets), ShouldEqual, 0)
				packets = cm.AddChunk(chunks[1])
				So(len(packets), ShouldEqual, 0)

				packets = cm.AddChunk(chunks[2])
				So(len(packets), ShouldEqual, 0)
				packets = cm.AddChunk(chunks[2])
				So(len(packets), ShouldEqual, 0)
				packets = cm.AddChunk(chunks[2])
				So(len(packets), ShouldEqual, 0)
				packets = cm.AddChunk(chunks[3])
				So(len(packets), ShouldEqual, 0)
				packets = cm.AddChunk(chunks[3])
				So(len(packets), ShouldEqual, 0)
				packets = cm.AddChunk(chunks[3])
				So(len(packets), ShouldEqual, 0)
				packets = cm.AddChunk(chunks[4])
				So(len(packets), ShouldEqual, 0)
				packets = cm.AddChunk(chunks[4])
				So(len(packets), ShouldEqual, 0)
				packets = cm.AddChunk(chunks[5])
				So(len(packets), ShouldEqual, 1)
				So(string(packets[0]), ShouldEqual, "abcdefghk")
				packets = cm.AddChunk(chunks[5])
				So(len(packets), ShouldEqual, 0)
				packets = cm.AddChunk(chunks[5])
				So(len(packets), ShouldEqual, 0)

				packets = cm.AddChunk(chunks[6])
				So(len(packets), ShouldEqual, 1)
				So(string(packets[0]), ShouldEqual, "123")
				packets = cm.AddChunk(chunks[6])
				So(len(packets), ShouldEqual, 0)
				packets = cm.AddChunk(chunks[6])
				So(len(packets), ShouldEqual, 0)
			})

			Convey("when old chunks show up", func() {
				cm := core.MakeUnreliableOrderedChunkMerger(3)
				packets := cm.AddChunk(chunks[0])
				So(len(packets), ShouldEqual, 0)

				// This makes all of the other chunks look old, we shouldn't get back anything for them
				// now.
				packets = cm.AddChunk(chunks[6])
				So(len(packets), ShouldEqual, 1)

				packets = cm.AddChunk(chunks[1])
				So(len(packets), ShouldEqual, 0)

				packets = cm.AddChunk(chunks[2])
				So(len(packets), ShouldEqual, 0)
				packets = cm.AddChunk(chunks[3])
				So(len(packets), ShouldEqual, 0)
				packets = cm.AddChunk(chunks[4])
				So(len(packets), ShouldEqual, 0)
				packets = cm.AddChunk(chunks[5])
				So(len(packets), ShouldEqual, 0)

			})
		})

		Convey("ReliableUnorderedChunkMergers work properly", func() {
			chunks := []core.Chunk{
				// 3: "ABCDEFGHIJ"
				core.Chunk{
					Sequence:    3,
					Subsequence: 1,
					Data:        []byte("ABC"),
				},
				core.Chunk{
					Sequence:    4,
					Subsequence: 2,
					Data:        []byte("DEF"),
				},
				core.Chunk{
					Sequence:    5,
					Subsequence: 3,
					Data:        []byte("GHI"),
				},
				core.Chunk{
					Sequence:    6,
					Subsequence: 4,
					Data:        []byte("J"),
				},

				// 7: "abcdefghk"
				core.Chunk{
					Sequence:    7,
					Subsequence: 1,
					Data:        []byte("abc"),
				},
				core.Chunk{
					Sequence:    8,
					Subsequence: 2,
					Data:        []byte("def"),
				},
				core.Chunk{
					Sequence:    9,
					Subsequence: 3,
					Data:        []byte("ghk"),
				},
				core.Chunk{
					Sequence:    10,
					Subsequence: 4,
					Data:        []byte(""),
				},

				// 11: "123"
				core.Chunk{
					Sequence:    11,
					Subsequence: 0,
					Data:        []byte("123"),
				},

				// 12: "456"
				core.Chunk{
					Sequence:    12,
					Subsequence: 0,
					Data:        []byte("456"),
				},

				// 1000: "FUTURE"
				core.Chunk{
					Sequence:    1000,
					Subsequence: 1,
					Data:        []byte("FUT"),
				},
				core.Chunk{
					Sequence:    1001,
					Subsequence: 2,
					Data:        []byte("URE"),
				},
				core.Chunk{
					Sequence:    1002,
					Subsequence: 3,
					Data:        []byte(""),
				},
			}
			Convey("when chunks come in order", func() {
				cm := core.MakeReliableUnorderedChunkMerger(3)
				packets := cm.AddChunk(chunks[0])
				So(len(packets), ShouldEqual, 0)
				packets = cm.AddChunk(chunks[1])
				So(len(packets), ShouldEqual, 0)
				packets = cm.AddChunk(chunks[2])
				So(len(packets), ShouldEqual, 0)
				packets = cm.AddChunk(chunks[3])
				So(len(packets), ShouldEqual, 1)
				So(string(packets[0]), ShouldEqual, "ABCDEFGHIJ")

				packets = cm.AddChunk(chunks[4])
				So(len(packets), ShouldEqual, 0)
				packets = cm.AddChunk(chunks[5])
				So(len(packets), ShouldEqual, 0)
				packets = cm.AddChunk(chunks[6])
				So(len(packets), ShouldEqual, 0)
				packets = cm.AddChunk(chunks[7])
				So(len(packets), ShouldEqual, 1)
				So(string(packets[0]), ShouldEqual, "abcdefghk")

				packets = cm.AddChunk(chunks[8])
				So(len(packets), ShouldEqual, 1)
				So(string(packets[0]), ShouldEqual, "123")

				packets = cm.AddChunk(chunks[9])
				So(len(packets), ShouldEqual, 1)
				So(string(packets[0]), ShouldEqual, "456")
			})

			Convey("when chunks come out of order", func() {
				cm := core.MakeReliableUnorderedChunkMerger(3)
				packets := cm.AddChunk(chunks[0])
				So(len(packets), ShouldEqual, 0)
				packets = cm.AddChunk(chunks[1])
				So(len(packets), ShouldEqual, 0)
				packets = cm.AddChunk(chunks[2])
				So(len(packets), ShouldEqual, 0)
				packets = cm.AddChunk(chunks[3])
				So(len(packets), ShouldEqual, 1)
				So(string(packets[0]), ShouldEqual, "ABCDEFGHIJ")

				packets = cm.AddChunk(chunks[5])
				So(len(packets), ShouldEqual, 0)
				packets = cm.AddChunk(chunks[4])
				So(len(packets), ShouldEqual, 0)
				packets = cm.AddChunk(chunks[7])
				So(len(packets), ShouldEqual, 0)
				packets = cm.AddChunk(chunks[6])
				So(len(packets), ShouldEqual, 1)
				So(string(packets[0]), ShouldEqual, "abcdefghk")

				packets = cm.AddChunk(chunks[9])
				So(len(packets), ShouldEqual, 1)
				So(string(packets[0]), ShouldEqual, "456")

				packets = cm.AddChunk(chunks[8])
				So(len(packets), ShouldEqual, 1)
				So(string(packets[0]), ShouldEqual, "123")
			})

			Convey("when packets come out of order", func() {
				cm := core.MakeReliableUnorderedChunkMerger(3)

				packets := cm.AddChunk(chunks[9])
				So(len(packets), ShouldEqual, 1)
				So(string(packets[0]), ShouldEqual, "456")

				packets = cm.AddChunk(chunks[5])
				So(len(packets), ShouldEqual, 0)
				packets = cm.AddChunk(chunks[4])
				So(len(packets), ShouldEqual, 0)
				packets = cm.AddChunk(chunks[7])
				So(len(packets), ShouldEqual, 0)
				packets = cm.AddChunk(chunks[6])
				So(len(packets), ShouldEqual, 1)
				So(string(packets[0]), ShouldEqual, "abcdefghk")

				packets = cm.AddChunk(chunks[0])
				So(len(packets), ShouldEqual, 0)
				packets = cm.AddChunk(chunks[1])
				So(len(packets), ShouldEqual, 0)
				packets = cm.AddChunk(chunks[2])
				So(len(packets), ShouldEqual, 0)
				packets = cm.AddChunk(chunks[3])
				So(len(packets), ShouldEqual, 1)
				So(string(packets[0]), ShouldEqual, "ABCDEFGHIJ")

				packets = cm.AddChunk(chunks[8])
				So(len(packets), ShouldEqual, 1)
				So(string(packets[0]), ShouldEqual, "123")
			})

			Convey("when duplicate chunks show up", func() {
				cm := core.MakeReliableUnorderedChunkMerger(3)
				packets := cm.AddChunk(chunks[0])
				So(len(packets), ShouldEqual, 0)
				packets = cm.AddChunk(chunks[1])
				So(len(packets), ShouldEqual, 0)
				packets = cm.AddChunk(chunks[2])
				So(len(packets), ShouldEqual, 0)
				packets = cm.AddChunk(chunks[3])
				So(len(packets), ShouldEqual, 1)
				So(string(packets[0]), ShouldEqual, "ABCDEFGHIJ")

				// Resend every chunk in that packet, shouldn't get anything back.
				packets = cm.AddChunk(chunks[0])
				So(len(packets), ShouldEqual, 0)
				packets = cm.AddChunk(chunks[1])
				So(len(packets), ShouldEqual, 0)
				packets = cm.AddChunk(chunks[2])
				So(len(packets), ShouldEqual, 0)
				packets = cm.AddChunk(chunks[3])
				So(len(packets), ShouldEqual, 0)

				packets = cm.AddChunk(chunks[5])
				So(len(packets), ShouldEqual, 0)
				packets = cm.AddChunk(chunks[5])
				So(len(packets), ShouldEqual, 0)
				packets = cm.AddChunk(chunks[4])
				So(len(packets), ShouldEqual, 0)
				packets = cm.AddChunk(chunks[4])
				So(len(packets), ShouldEqual, 0)
				packets = cm.AddChunk(chunks[7])
				So(len(packets), ShouldEqual, 0)
				packets = cm.AddChunk(chunks[6])
				So(len(packets), ShouldEqual, 1)
				So(string(packets[0]), ShouldEqual, "abcdefghk")
				packets = cm.AddChunk(chunks[6])
				So(len(packets), ShouldEqual, 0)

				packets = cm.AddChunk(chunks[8])
				So(len(packets), ShouldEqual, 1)
				So(string(packets[0]), ShouldEqual, "123")
				packets = cm.AddChunk(chunks[8])
				So(len(packets), ShouldEqual, 0)

				packets = cm.AddChunk(chunks[9])
				So(len(packets), ShouldEqual, 1)
				So(string(packets[0]), ShouldEqual, "456")
				packets = cm.AddChunk(chunks[9])
				So(len(packets), ShouldEqual, 0)
			})

			Convey("when old chunks show up", func() {
				cm := core.MakeReliableUnorderedChunkMerger(3)
				packets := cm.AddChunk(chunks[10])
				So(len(packets), ShouldEqual, 0)
				packets = cm.AddChunk(chunks[11])
				So(len(packets), ShouldEqual, 0)
				packets = cm.AddChunk(chunks[12])
				So(len(packets), ShouldEqual, 1)
				So(string(packets[0]), ShouldEqual, "FUTURE")

				// Now send some super-old packets that we haven't gotten yet.
				packets = cm.AddChunk(chunks[0])
				So(len(packets), ShouldEqual, 0)
				packets = cm.AddChunk(chunks[1])
				So(len(packets), ShouldEqual, 0)
				packets = cm.AddChunk(chunks[2])
				So(len(packets), ShouldEqual, 0)
				packets = cm.AddChunk(chunks[3])
				So(len(packets), ShouldEqual, 1)
				So(string(packets[0]), ShouldEqual, "ABCDEFGHIJ")

				packets = cm.AddChunk(chunks[4])
				So(len(packets), ShouldEqual, 0)
				packets = cm.AddChunk(chunks[5])
				So(len(packets), ShouldEqual, 0)
				packets = cm.AddChunk(chunks[6])
				So(len(packets), ShouldEqual, 0)
				packets = cm.AddChunk(chunks[7])
				So(len(packets), ShouldEqual, 1)
				So(string(packets[0]), ShouldEqual, "abcdefghk")

				packets = cm.AddChunk(chunks[8])
				So(len(packets), ShouldEqual, 1)
				So(string(packets[0]), ShouldEqual, "123")

				packets = cm.AddChunk(chunks[9])
				So(len(packets), ShouldEqual, 1)
				So(string(packets[0]), ShouldEqual, "456")
			})
		})

		Convey("ReliableOrderedChunkMergers work properly", func() {
			chunks := []core.Chunk{
				// 3: "ABCDEFGHIJ"
				core.Chunk{
					Sequence:    3,
					Subsequence: 1,
					Data:        []byte("ABC"),
				},
				core.Chunk{
					Sequence:    4,
					Subsequence: 2,
					Data:        []byte("DEF"),
				},
				core.Chunk{
					Sequence:    5,
					Subsequence: 3,
					Data:        []byte("GHI"),
				},
				core.Chunk{
					Sequence:    6,
					Subsequence: 4,
					Data:        []byte("J"),
				},

				// 7: "abcdefghk"
				core.Chunk{
					Sequence:    7,
					Subsequence: 1,
					Data:        []byte("abc"),
				},
				core.Chunk{
					Sequence:    8,
					Subsequence: 2,
					Data:        []byte("def"),
				},
				core.Chunk{
					Sequence:    9,
					Subsequence: 3,
					Data:        []byte("ghk"),
				},
				core.Chunk{
					Sequence:    10,
					Subsequence: 4,
					Data:        []byte(""),
				},

				// 11: "123"
				core.Chunk{
					Sequence:    11,
					Subsequence: 0,
					Data:        []byte("123"),
				},

				// 12: "456"
				core.Chunk{
					Sequence:    12,
					Subsequence: 0,
					Data:        []byte("456"),
				},

				// 1000: "FUTURE"
				core.Chunk{
					Sequence:    1000,
					Subsequence: 1,
					Data:        []byte("FUT"),
				},
				core.Chunk{
					Sequence:    1001,
					Subsequence: 2,
					Data:        []byte("URE"),
				},
				core.Chunk{
					Sequence:    1002,
					Subsequence: 3,
					Data:        []byte(""),
				},
			}
			Convey("when chunks come in order", func() {
				cm := core.MakeReliableOrderedChunkMerger(3)
				packets := cm.AddChunk(chunks[0])
				So(len(packets), ShouldEqual, 0)
				packets = cm.AddChunk(chunks[1])
				So(len(packets), ShouldEqual, 0)
				packets = cm.AddChunk(chunks[2])
				So(len(packets), ShouldEqual, 0)
				packets = cm.AddChunk(chunks[3])
				So(len(packets), ShouldEqual, 1)
				So(string(packets[0]), ShouldEqual, "ABCDEFGHIJ")

				packets = cm.AddChunk(chunks[4])
				So(len(packets), ShouldEqual, 0)
				packets = cm.AddChunk(chunks[5])
				So(len(packets), ShouldEqual, 0)
				packets = cm.AddChunk(chunks[6])
				So(len(packets), ShouldEqual, 0)
				packets = cm.AddChunk(chunks[7])
				So(len(packets), ShouldEqual, 1)
				So(string(packets[0]), ShouldEqual, "abcdefghk")

				packets = cm.AddChunk(chunks[8])
				So(len(packets), ShouldEqual, 1)
				So(string(packets[0]), ShouldEqual, "123")

				packets = cm.AddChunk(chunks[9])
				So(len(packets), ShouldEqual, 1)
				So(string(packets[0]), ShouldEqual, "456")
			})

			Convey("when chunks come out of order", func() {
				cm := core.MakeReliableOrderedChunkMerger(3)
				packets := cm.AddChunk(chunks[0])
				So(len(packets), ShouldEqual, 0)
				packets = cm.AddChunk(chunks[1])
				So(len(packets), ShouldEqual, 0)
				packets = cm.AddChunk(chunks[2])
				So(len(packets), ShouldEqual, 0)
				packets = cm.AddChunk(chunks[3])
				So(len(packets), ShouldEqual, 1)
				So(string(packets[0]), ShouldEqual, "ABCDEFGHIJ")

				packets = cm.AddChunk(chunks[5])
				So(len(packets), ShouldEqual, 0)
				packets = cm.AddChunk(chunks[4])
				So(len(packets), ShouldEqual, 0)
				packets = cm.AddChunk(chunks[7])
				So(len(packets), ShouldEqual, 0)
				packets = cm.AddChunk(chunks[6])
				So(len(packets), ShouldEqual, 1)
				So(string(packets[0]), ShouldEqual, "abcdefghk")

				packets = cm.AddChunk(chunks[8])
				So(len(packets), ShouldEqual, 1)
				So(string(packets[0]), ShouldEqual, "123")

				packets = cm.AddChunk(chunks[9])
				So(len(packets), ShouldEqual, 1)
				So(string(packets[0]), ShouldEqual, "456")
			})

			Convey("when packets come out of order", func() {
				cm := core.MakeReliableOrderedChunkMerger(3)

				packets := cm.AddChunk(chunks[9])
				So(len(packets), ShouldEqual, 0)
				// So(string(packets[0]), ShouldEqual, "456")

				packets = cm.AddChunk(chunks[5])
				So(len(packets), ShouldEqual, 0)
				packets = cm.AddChunk(chunks[4])
				So(len(packets), ShouldEqual, 0)
				packets = cm.AddChunk(chunks[7])
				So(len(packets), ShouldEqual, 0)
				packets = cm.AddChunk(chunks[6])
				So(len(packets), ShouldEqual, 0)
				// So(string(packets[0]), ShouldEqual, "abcdefghk")

				packets = cm.AddChunk(chunks[0])
				So(len(packets), ShouldEqual, 0)
				packets = cm.AddChunk(chunks[1])
				So(len(packets), ShouldEqual, 0)
				packets = cm.AddChunk(chunks[2])
				So(len(packets), ShouldEqual, 0)

				packets = cm.AddChunk(chunks[8])
				So(len(packets), ShouldEqual, 0)

				packets = cm.AddChunk(chunks[3])
				So(len(packets), ShouldEqual, 4)
				So(string(packets[0]), ShouldEqual, "ABCDEFGHIJ")
				So(string(packets[1]), ShouldEqual, "abcdefghk")
				So(string(packets[2]), ShouldEqual, "123")
				So(string(packets[3]), ShouldEqual, "456")
			})

			Convey("when duplicate chunks show up", func() {
				cm := core.MakeReliableOrderedChunkMerger(3)
				packets := cm.AddChunk(chunks[0])
				So(len(packets), ShouldEqual, 0)
				packets = cm.AddChunk(chunks[1])
				So(len(packets), ShouldEqual, 0)
				packets = cm.AddChunk(chunks[2])
				So(len(packets), ShouldEqual, 0)
				packets = cm.AddChunk(chunks[3])
				So(len(packets), ShouldEqual, 1)
				So(string(packets[0]), ShouldEqual, "ABCDEFGHIJ")

				// Resend every chunk in that packet, shouldn't get anything back.
				packets = cm.AddChunk(chunks[0])
				So(len(packets), ShouldEqual, 0)
				packets = cm.AddChunk(chunks[1])
				So(len(packets), ShouldEqual, 0)
				packets = cm.AddChunk(chunks[2])
				So(len(packets), ShouldEqual, 0)
				packets = cm.AddChunk(chunks[3])
				So(len(packets), ShouldEqual, 0)

				packets = cm.AddChunk(chunks[5])
				So(len(packets), ShouldEqual, 0)
				packets = cm.AddChunk(chunks[5])
				So(len(packets), ShouldEqual, 0)
				packets = cm.AddChunk(chunks[4])
				So(len(packets), ShouldEqual, 0)
				packets = cm.AddChunk(chunks[4])
				So(len(packets), ShouldEqual, 0)
				packets = cm.AddChunk(chunks[7])
				So(len(packets), ShouldEqual, 0)
				packets = cm.AddChunk(chunks[6])
				So(len(packets), ShouldEqual, 1)
				So(string(packets[0]), ShouldEqual, "abcdefghk")
				packets = cm.AddChunk(chunks[6])
				So(len(packets), ShouldEqual, 0)

				packets = cm.AddChunk(chunks[8])
				So(len(packets), ShouldEqual, 1)
				So(string(packets[0]), ShouldEqual, "123")
				packets = cm.AddChunk(chunks[8])
				So(len(packets), ShouldEqual, 0)

				packets = cm.AddChunk(chunks[9])
				So(len(packets), ShouldEqual, 1)
				So(string(packets[0]), ShouldEqual, "456")
				packets = cm.AddChunk(chunks[9])
				So(len(packets), ShouldEqual, 0)
			})

			Convey("when old chunks show up", func() {
				cm := core.MakeReliableOrderedChunkMerger(3)
				packets := cm.AddChunk(chunks[10])
				So(len(packets), ShouldEqual, 0)
				packets = cm.AddChunk(chunks[11])
				So(len(packets), ShouldEqual, 0)
				packets = cm.AddChunk(chunks[12])
				So(len(packets), ShouldEqual, 0)

				// Now send some super-old packets that we haven't gotten yet.
				packets = cm.AddChunk(chunks[0])
				So(len(packets), ShouldEqual, 0)
				packets = cm.AddChunk(chunks[1])
				So(len(packets), ShouldEqual, 0)
				packets = cm.AddChunk(chunks[2])
				So(len(packets), ShouldEqual, 0)
				packets = cm.AddChunk(chunks[3])
				So(len(packets), ShouldEqual, 1)
				So(string(packets[0]), ShouldEqual, "ABCDEFGHIJ")

				packets = cm.AddChunk(chunks[4])
				So(len(packets), ShouldEqual, 0)
				packets = cm.AddChunk(chunks[5])
				So(len(packets), ShouldEqual, 0)
				packets = cm.AddChunk(chunks[6])
				So(len(packets), ShouldEqual, 0)
				packets = cm.AddChunk(chunks[7])
				So(len(packets), ShouldEqual, 1)
				So(string(packets[0]), ShouldEqual, "abcdefghk")

				packets = cm.AddChunk(chunks[8])
				So(len(packets), ShouldEqual, 1)
				So(string(packets[0]), ShouldEqual, "123")

				packets = cm.AddChunk(chunks[9])
				So(len(packets), ShouldEqual, 1)
				So(string(packets[0]), ShouldEqual, "456")

				// Didn't get "FUTURE" because it is at sequence 1000, far ahead of these.
			})
		})
	})
}
Example #2
0
func BenchmarkUnreliableUnorderedChunkMergerWithOutOfOrderChunks(b *testing.B) {
	benchmarkChunkMergerWithOutOfOrderChunks(b, core.MakeUnreliableUnorderedChunkMerger(10))
}
Example #3
0
func TestWriterRoutine(t *testing.T) {
	Convey("WriterRoutine", t, func() {
		packets := []string{
			"I am a short packet.",
			"",
			`Lorem ipsum dolor sit amet, consecmetur adipiscing elit, sed do eiusmod tempor
			incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud
			exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure
			dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.
			Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt
			mollit anim id est laborum.`,
		}

		streamConfig := core.StreamConfig{
			Broadcast: false,
			Id:        10,
			Mode:      core.ModeUnreliableUnordered,
			Name:      "testConfig",
		}

		// Want to test packets that are evenly divisible by maxChunkDataSize, so we'll set it to
		// whatever half of the first packet is, but we need to make sure the first packet has even
		// length first.
		So(len(packets[0])%2, ShouldEqual, 0)
		maxChunkDataSize := len(packets[0]) / 2
		packetsIn := make(chan []byte)
		chunksOut := make(chan core.Chunk)
		go func() {
			core.WriterRoutine(streamConfig, 123, maxChunkDataSize, packetsIn, chunksOut)
			close(chunksOut)
		}()
		go func() {
			for _, packet := range packets {
				packetsIn <- []byte(packet)
			}
			close(packetsIn)
		}()
		var chunks []core.Chunk
		for chunk := range chunksOut {
			chunks = append(chunks, chunk)
		}
		Convey("Chunkifies packets into the appropriate size.", func() {
			for _, chunk := range chunks {
				So(len(chunk.Data), ShouldBeLessThanOrEqualTo, maxChunkDataSize)
			}
		})
		Convey("Output is properly reassembled by a ChunkMerger.", func() {
			cm := core.MakeUnreliableUnorderedChunkMerger(1)
			var reassembled []string
			for _, chunk := range chunks {
				dechunked := cm.AddChunk(chunk)
				for _, packet := range dechunked {
					reassembled = append(reassembled, string(packet))
				}
			}
			So(len(reassembled), ShouldEqual, len(packets))
			for i := range reassembled {
				So(reassembled[i], ShouldEqual, packets[i])
			}
		})
	})
}