<commit_before>// Copyright 2013 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package ssh

import (
	"context"
	"io"
	"sync"
	"testing"
)

// An in-memory packetConn. It is safe to call Close and writePacket
// from different goroutines.
type memTransport struct {
	eof     bool
	pending [][]byte
	write   *memTransport
	sync.Mutex
	*sync.Cond

	//idle *idleTimer
}

func (t *memTransport) timeout() {
	t.Signal()
}

func (t *memTransport) readPacket(ctx context.Context) ([]byte, error) {
	t.Lock()
	defer t.Unlock()
	for {
		if len(t.pending) > 0 {
			r := t.pending[0]
			t.pending = t.pending[1:]
			return r, nil
		}
		if t.eof {
			return nil, io.EOF
		}
		/*
			select {
			case timedOut := <-t.idle.TimedOut:
				if timedOut {
					return nil, ErrTimeout
				}
			case <-t.idle.halt.ReqStop.Chan:
				return nil, io.EOF
			}
		*/
		t.Cond.Wait()
	}
}

func (t *memTransport) closeSelf() error {
	t.Lock()
	defer t.Unlock()
	if t.eof {
		return io.EOF
	}
	t.eof = true
	t.Cond.Broadcast()
	return nil
}

func (t *memTransport) Close() error {
	err := t.write.closeSelf()
	t.closeSelf()
	return err
}

func (t *memTransport) writePacket(p []byte) error {
	t.write.Lock()
	defer t.write.Unlock()
	if t.write.eof {
		return io.EOF
	}
	c := make([]byte, len(p))
	copy(c, p)
	t.write.pending = append(t.write.pending, c)
	t.write.Cond.Signal()
	return nil
}

func memPipe() (a, b packetConn) {
	t1 := memTransport{}
	t2 := memTransport{}
	//t1.idle = newIdleTimer(t1.timeout, 0)
	//t2.idle = newIdleTimer(t2.timeout, 0)
	t1.write = &t2
	t2.write = &t1
	t1.Cond = sync.NewCond(&t1.Mutex)
	t2.Cond = sync.NewCond(&t2.Mutex)
	return &t1, &t2
}

func TestMemPipe(t *testing.T) {
	a, b := memPipe()
	if err := a.writePacket([]byte{42}); err != nil {
		t.Fatalf("writePacket: %v", err)
	}
	if err := a.Close(); err != nil {<commit_msg>atg. restore mempipe_test use of idleTimer so it doesn't deadlock<commit_after>// Copyright 2013 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package ssh

import (
	"context"
	"io"
	"sync"
	"testing"
)

// An in-memory packetConn. It is safe to call Close and writePacket
// from different goroutines.
type memTransport struct {
	eof     bool
	pending [][]byte
	write   *memTransport
	sync.Mutex
	*sync.Cond

	idle *idleTimer
}

func (t *memTransport) timeout() {
	t.Signal()
}

func (t *memTransport) readPacket(ctx context.Context) ([]byte, error) {
	t.Lock()
	defer t.Unlock()
	for {
		if len(t.pending) > 0 {
			r := t.pending[0]
			t.pending = t.pending[1:]
			return r, nil
		}
		if t.eof {
			return nil, io.EOF
		}

		select {
		case timedOut := <-t.idle.TimedOut:
			if timedOut {
				return nil, ErrTimeout
			}
		case <-t.idle.halt.ReqStop.Chan:
			return nil, io.EOF
		}

		t.Cond.Wait()
	}
}

func (t *memTransport) closeSelf() error {
	t.Lock()
	defer t.Unlock()
	if t.eof {
		return io.EOF
	}
	t.eof = true
	t.Cond.Broadcast()
	return nil
}

func (t *memTransport) Close() error {
	err := t.write.closeSelf()
	t.closeSelf()
	return err
}

func (t *memTransport) writePacket(p []byte) error {
	t.write.Lock()
	defer t.write.Unlock()
	if t.write.eof {
		return io.EOF
	}
	c := make([]byte, len(p))
	copy(c, p)
	t.write.pending = append(t.write.pending, c)
	t.write.Cond.Signal()
	return nil
}

func memPipe() (a, b packetConn) {
	t1 := memTransport{}
	t2 := memTransport{}
	t1.idle = newIdleTimer(t1.timeout, 0)
	t2.idle = newIdleTimer(t2.timeout, 0)
	t1.write = &t2
	t2.write = &t1
	t1.Cond = sync.NewCond(&t1.Mutex)
	t2.Cond = sync.NewCond(&t2.Mutex)
	return &t1, &t2
}

func TestMemPipe(t *testing.T) {
	a, b := memPipe()
	if err := a.writePacket([]byte{42}); err != nil {
		t.Fatalf("writePacket: %v", err)
	}
	if err := a.Close(); err != nil {
{'fraction_non_alphanumeric': 0.1559444158517756, 'fraction_numerical': 0.013896037056098817, 'mean_word_length': 3.113227513227513, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4935844', 'n_tokens_mistral': 1658, 'n_tokens_neox': 1572, 'n_words': 417}