github.com/martinohmann/rfoutlet@v1.2.1-0.20220707195255-8a66aa411105/pkg/gpio/receiver_test.go (about)

     1  package gpio
     2  
     3  import (
     4  	"context"
     5  	"fmt"
     6  	"sync"
     7  	"testing"
     8  	"time"
     9  
    10  	"github.com/jonboulle/clockwork"
    11  	"github.com/stretchr/testify/assert"
    12  	"github.com/warthog618/gpiod"
    13  )
    14  
    15  type pinWatcherPipe struct {
    16  	*FakeWatcher
    17  	clock clockwork.Clock
    18  	once  sync.Once
    19  }
    20  
    21  func newPinWatcherPipe(clock clockwork.Clock) *pinWatcherPipe {
    22  	return &pinWatcherPipe{
    23  		FakeWatcher: NewFakeWatcher(),
    24  		clock:       clock,
    25  	}
    26  }
    27  
    28  func (p *pinWatcherPipe) SetValue(value int) error {
    29  	var eventType gpiod.LineEventType
    30  	switch value {
    31  	case 0:
    32  		eventType = gpiod.LineEventFallingEdge
    33  	case 1:
    34  		eventType = gpiod.LineEventRisingEdge
    35  	default:
    36  		panic(fmt.Sprintf("invalid value: %d", value))
    37  	}
    38  
    39  	p.Events <- gpiod.LineEvent{
    40  		Type:      eventType,
    41  		Timestamp: time.Duration(p.clock.Now().UnixNano()),
    42  	}
    43  
    44  	return nil
    45  }
    46  
    47  func (p *pinWatcherPipe) Close() (err error) {
    48  	p.once.Do(func() {
    49  		err = p.FakeWatcher.Close()
    50  	})
    51  	return
    52  }
    53  
    54  func TestReceiverReceive(t *testing.T) {
    55  	fakeClock := clockwork.NewFakeClockAt(time.Now())
    56  
    57  	pipe := newPinWatcherPipe(fakeClock)
    58  
    59  	tx := NewPinTransmitter(pipe, TransmissionCount(10))
    60  	tx.delay = fakeClock.Advance
    61  	defer tx.Close()
    62  
    63  	rx := NewWatcherReceiver(pipe, ReceiverProtocols(DefaultProtocols))
    64  	defer rx.Close()
    65  
    66  	transmissions := []struct {
    67  		code        uint64
    68  		protocol    int
    69  		pulseLength uint
    70  	}{
    71  		{5510451, 1, 184},
    72  		{83281, 1, 305},
    73  		{86356, 1, 305},
    74  		{5510604, 1, 184},
    75  		{5591317, 1, 330},
    76  	}
    77  
    78  	ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
    79  	defer cancel()
    80  
    81  	go func() {
    82  		defer cancel()
    83  
    84  		var i int
    85  		var lastCode uint64
    86  
    87  		for i < len(transmissions) {
    88  			result, ok := <-rx.Receive()
    89  			if !ok {
    90  				return
    91  			}
    92  			if result.Code == lastCode {
    93  				continue
    94  			}
    95  
    96  			tm := transmissions[i]
    97  
    98  			assert.Equalf(t, tm.code, result.Code,
    99  				"received code %d != expected %d", result.Code, tm.code)
   100  
   101  			lastCode = result.Code
   102  			i++
   103  		}
   104  	}()
   105  
   106  	for _, tm := range transmissions {
   107  		<-tx.Transmit(tm.code, DefaultProtocols[tm.protocol-1], tm.pulseLength)
   108  	}
   109  
   110  	<-ctx.Done()
   111  
   112  	if err := ctx.Err(); err == context.DeadlineExceeded {
   113  		t.Fatal(err)
   114  	}
   115  }
   116  
   117  func TestReceiverClose(t *testing.T) {
   118  	w := NewFakeWatcher()
   119  
   120  	receiver := NewWatcherReceiver(w)
   121  	assert.Nil(t, receiver.Close())
   122  
   123  	assert.True(t, w.Closed)
   124  }