func TestTupleSpaceProcessNewEntriesAlwaysRespondsToReaders(t *testing.T) { rts := tuplespace.NewRawTupleSpace(store.NewMemoryStore()) take := rts.ReadOperation(tuplespace.MustMatch("cmd"), 0, tuplespace.ActionOne|tuplespace.ActionTake) read := rts.ReadOperation(tuplespace.MustMatch("cmd"), 0, tuplespace.ActionOne) go func() { time.Sleep(time.Second * 1) take.Cancel() read.Cancel() }() tuples := []tuplespace.Tuple{tuplespace.Tuple{"cmd": "uname -a"}} expected := []tuplespace.Tuple{tuplespace.Tuple{"cmd": "uname -a"}} assert.NoError(t, rts.ProcessNewEntries(tuples, time.Now())) assert.Equal(t, <-take.Get(), expected) assert.Equal(t, <-read.Get(), expected) }
func TestTupleSpaceTake(t *testing.T) { ts := tuplespace.NewTupleSpace(store.NewMemoryStore()) defer ts.Shutdown() ts.Send(tuplespace.Tuple{"cmd": "uname -a"}, 0) ts.Send(tuplespace.Tuple{"cmd": "uptime"}, 0) _, err := ts.Take(tuplespace.MustMatch(`cmd != nil`), time.Second) assert.NoError(t, err) assert.Equal(t, ts.Stats().Tuples, 1) }
func benchmarkTupleSpaceReadAll1000(b *testing.B, builder TupleStoreBuilder) { ts := tuplespace.NewTupleSpace(NewTemporaryDiskStore(builder)) defer ts.Shutdown() sendN(ts, 1000, 0) b.ResetTimer() match := tuplespace.MustMatch(`cmd != nil`) for i := 0; i < b.N; i++ { ts.ReadAll(match, 0) } }
func benchmarkTupleSpaceTake(b *testing.B, builder TupleStoreBuilder) { ts := tuplespace.NewTupleSpace(NewTemporaryDiskStore(builder)) defer ts.Shutdown() sendN(ts, b.N, 0) b.ResetTimer() for i := 0; i < b.N; i++ { match := tuplespace.MustMatch(`cmd == %d`, i) ts.Take(match, 0) } }
func TestTupleSpaceReadAll(t *testing.T) { ts := tuplespace.NewTupleSpace(store.NewMemoryStore()) defer ts.Shutdown() ts.Send(tuplespace.Tuple{"cmd": "uname -a"}, 0) ts.Send(tuplespace.Tuple{"cmd": "uptime"}, 0) time.Sleep(time.Millisecond * 100) tuples, err := ts.ReadAll(tuplespace.MustMatch(`cmd != nil`), time.Second) assert.NoError(t, err) assert.Equal(t, tuples, []tuplespace.Tuple{tuplespace.Tuple{"cmd": "uname -a"}, tuplespace.Tuple{"cmd": "uptime"}}) assert.Equal(t, ts.Stats().Tuples, 2) }
func benchmarkTupleSpaceRead(b *testing.B, builder TupleStoreBuilder) { ts := tuplespace.NewTupleSpace(NewTemporaryDiskStore(builder)) defer ts.Shutdown() sendN(ts, b.N, 0) sendN(ts, b.N, 0) b.ResetTimer() for i := 0; i < b.N; i++ { match := tuplespace.MustMatch(`cmd == %d`, int64(i)) _, err := ts.Read(match, 0) if err != nil { panic(err.Error()) } } }
func benchmarkTupleSpaceStressTestConcurrency32(b *testing.B, builder TupleStoreBuilder) { ts := tuplespace.NewTupleSpace(NewTemporaryDiskStore(builder)) defer ts.Shutdown() threads := 32 messages := b.N var sent int32 var read int32 readWait := sync.WaitGroup{} for i := 0; i < threads; i++ { readWait.Add(1) go func(i int) { for n := 0; n < messages; n++ { match := tuplespace.MustMatch(`"a" == "reader" && "b" == %d && "c" == %d`, i, n) _, err := ts.Take(match, time.Minute) if err != nil { fmt.Errorf("failed to take: %s", err) } else { atomic.AddInt32(&read, 1) } } readWait.Done() }(i) } writeWait := sync.WaitGroup{} for i := 0; i < threads; i++ { writeWait.Add(1) go func(i int) { for n := 0; n < messages; n++ { tuple := tuplespace.Tuple{"a": "reader", "b": int64(i), "c": int64(n)} err := ts.Send(tuple, 0) if err != nil { fmt.Errorf("failed to take: %s", err) } else { atomic.AddInt32(&sent, 1) } } writeWait.Done() }(i) } writeWait.Wait() if int(sent) != threads*messages { panic("consistency check failed") } readWait.Wait() if sent != read { panic("consistency check failed") } // assert.Equal(t, ts.Stats(), tuplespace.TupleSpaceStats{ // TuplesSeen: int64(threads * messages), // WaitersSeen: int64(threads * messages), // TuplesTaken: int64(threads * messages), // TuplesRead: 0, // }) }