github.com/Comcast/plax@v0.8.32/dsl/mock.go (about)

     1  /*
     2   * Copyright 2021 Comcast Cable Communications Management, LLC
     3   *
     4   * Licensed under the Apache License, Version 2.0 (the "License");
     5   * you may not use this file except in compliance with the License.
     6   * You may obtain a copy of the License at
     7   *
     8   * http://www.apache.org/licenses/LICENSE-2.0
     9   *
    10   * Unless required by applicable law or agreed to in writing, software
    11   * distributed under the License is distributed on an "AS IS" BASIS,
    12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13   * See the License for the specific language governing permissions and
    14   * limitations under the License.
    15   *
    16   * SPDX-License-Identifier: Apache-2.0
    17   */
    18  
    19  package dsl
    20  
    21  import (
    22  	"bufio"
    23  	"io"
    24  	"strings"
    25  	"time"
    26  )
    27  
    28  func init() {
    29  	TheChanRegistry.Register(NewCtx(nil), "mock", NewMockChan)
    30  }
    31  
    32  // MockChan is a channel type that just emits what it receives.
    33  //
    34  // This channel type is mostly used for testing.  A message published
    35  // to a mock channel is simply emitted as is (for test to receive).
    36  type MockChan struct {
    37  	c chan Msg
    38  }
    39  
    40  func NewMockChan(ctx *Ctx, _ interface{}) (Chan, error) {
    41  	return &MockChan{
    42  		c: make(chan Msg, 1024),
    43  	}, nil
    44  }
    45  
    46  func (c *MockChan) DocSpec() *DocSpec {
    47  	return &DocSpec{
    48  		Chan: &MockChan{},
    49  	}
    50  }
    51  
    52  func (c *MockChan) Kind() ChanKind {
    53  	return "mock"
    54  }
    55  
    56  func (c *MockChan) Open(ctx *Ctx) error {
    57  	return nil
    58  }
    59  
    60  func (c *MockChan) Close(ctx *Ctx) error {
    61  	return nil
    62  }
    63  
    64  func (c *MockChan) Sub(ctx *Ctx, topic string) error {
    65  	ctx.Logf("MockChan Sub %s", topic)
    66  	return nil
    67  }
    68  
    69  func (c *MockChan) Pub(ctx *Ctx, m Msg) error {
    70  	ctx.Logf("MockChan Pub topic %s", m.Topic)
    71  	ctx.Logdf("             payload %s", m.Payload)
    72  	return c.To(ctx, m)
    73  }
    74  
    75  func (c *MockChan) Recv(ctx *Ctx) chan Msg {
    76  	ctx.Logf("MockChan Recv")
    77  	return c.c
    78  }
    79  
    80  func (c *MockChan) Kill(ctx *Ctx) error {
    81  	return Brokenf("Kill is not supported by a %T", c)
    82  }
    83  
    84  func (c *MockChan) To(ctx *Ctx, m Msg) error {
    85  	ctx.Logf("MockChan To topic %s", m.Topic)
    86  	ctx.Logdf("            payload %s", m.Payload)
    87  	m.ReceivedAt = time.Now().UTC()
    88  	select {
    89  	case <-ctx.Done():
    90  	case c.c <- m:
    91  	default:
    92  		panic("Warning: MockChan channel full")
    93  	}
    94  	return nil
    95  }
    96  
    97  // Read is a utility function to read input for a MockChan.
    98  //
    99  // Does not close the reader.
   100  func (c *MockChan) Read(ctx *Ctx, in *bufio.Reader) error {
   101  	ctx.Logf("MockChan reading input")
   102  	for {
   103  		line, err := in.ReadBytes('\n')
   104  		if err != nil && err != io.EOF {
   105  			return err
   106  		}
   107  		if len(line) == 0 && err == io.EOF {
   108  			return nil
   109  		}
   110  
   111  		parts := strings.SplitN(string(line), " ", 2)
   112  		if len(parts) != 2 {
   113  			ctx.Logf("error: MockChan.Read need topic payload")
   114  			continue
   115  		}
   116  		m := Msg{
   117  			Topic:   parts[0],
   118  			Payload: parts[1],
   119  		}
   120  		if err = c.To(ctx, m); err != nil {
   121  			return err
   122  		}
   123  	}
   124  
   125  	return nil
   126  }