github.com/mvdan/u-root-coreutils@v0.0.0-20230122170626-c2eef2898555/cmds/contrib/spidev/spidev_test.go (about)

     1  // Copyright 2021 the u-root Authors. All rights reserved
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package main
     6  
     7  import (
     8  	"bytes"
     9  	"errors"
    10  	"fmt"
    11  	"reflect"
    12  	"regexp"
    13  	"testing"
    14  
    15  	"github.com/mvdan/u-root-coreutils/pkg/flash/spimock"
    16  	"github.com/mvdan/u-root-coreutils/pkg/spidev"
    17  )
    18  
    19  func TestRun(t *testing.T) {
    20  	for _, tt := range []struct {
    21  		name               string
    22  		args               []string
    23  		input              []byte
    24  		ForceOpenErr       error
    25  		ForceTransferErr   error
    26  		ForceSetSpeedHzErr error
    27  		wantTransfers      []spidev.Transfer
    28  		wantSpeed          uint32
    29  		wantOutput         string
    30  		wantOutputRegex    *regexp.Regexp
    31  		wantErr            error
    32  	}{
    33  		{
    34  			name:    "invalid arguments",
    35  			args:    []string{"--invalid", "raw"},
    36  			wantErr: errors.New("unknown flag: --invalid"),
    37  		},
    38  		{
    39  			name:    "invalid subcommand",
    40  			args:    []string{"potato"},
    41  			wantErr: errors.New("unknown subcommand"),
    42  		},
    43  		{
    44  			name:    "too many arguments",
    45  			args:    []string{"raw", "potato"},
    46  			wantErr: errors.New("expected one subcommand"),
    47  		},
    48  		{
    49  			name:         "open error",
    50  			args:         []string{"raw"},
    51  			ForceOpenErr: errors.New("fake open error"),
    52  			wantErr:      errors.New("fake open error"),
    53  		},
    54  		{
    55  			name:             "transfer error",
    56  			args:             []string{"raw"},
    57  			input:            []byte("abcd"),
    58  			ForceTransferErr: errors.New("fake transfer error"),
    59  			wantErr:          errors.New("fake transfer error"),
    60  		},
    61  		{
    62  			name:               "setspeedhz error",
    63  			args:               []string{"raw"},
    64  			input:              []byte("abcd"),
    65  			ForceSetSpeedHzErr: errors.New("fake setspeedhz error"),
    66  			wantErr:            errors.New("fake setspeedhz error"),
    67  		},
    68  		{
    69  			name: "empty transfer",
    70  			args: []string{"raw"},
    71  			// Note wantTransfers is an empty slice. There is no
    72  			// need to even perform an ioctl.
    73  			wantSpeed: 5000000,
    74  		},
    75  		{
    76  			name: "single transfer",
    77  			args: []string{"raw"},
    78  			// This test sends a raw sfdp read command.
    79  			input: []byte{0x5a, 0, 0, 0, 0xff, 0, 0, 0, 0},
    80  			wantTransfers: []spidev.Transfer{
    81  				{
    82  					Tx: []byte{0x5a, 0, 0, 0, 0xff, 0, 0, 0, 0},
    83  					Rx: []byte{0, 0, 0, 0, 0, 'S', 'F', 'D', 'P'},
    84  				},
    85  			},
    86  			wantSpeed:  5000000,
    87  			wantOutput: "\x00\x00\x00\x00\x00SFDP",
    88  		},
    89  		{
    90  			name:            "sfdp",
    91  			args:            []string{"sfdp"},
    92  			wantSpeed:       5000000,
    93  			wantOutputRegex: regexp.MustCompile("FlashMemoryDensity *0x1fffffff"),
    94  		},
    95  	} {
    96  		t.Run(tt.name, func(t *testing.T) {
    97  			s := spimock.New()
    98  			s.ForceTransferErr = tt.ForceTransferErr
    99  			s.ForceSetSpeedHzErr = tt.ForceSetSpeedHzErr
   100  			openFakeSpi := func(dev string) (spi, error) {
   101  				if tt.ForceOpenErr != nil {
   102  					return nil, tt.ForceOpenErr
   103  				}
   104  				return s, nil
   105  			}
   106  
   107  			output := &bytes.Buffer{}
   108  			gotErr := run(tt.args, openFakeSpi, bytes.NewBuffer(tt.input), output)
   109  
   110  			if gotErrString, wantErrString := fmt.Sprint(gotErr), fmt.Sprint(tt.wantErr); gotErrString != wantErrString {
   111  				t.Errorf("run() got err %q; want err %q", gotErrString, wantErrString)
   112  			}
   113  
   114  			gotOutputString := output.String()
   115  			if tt.wantOutputRegex != nil {
   116  				if !tt.wantOutputRegex.MatchString(gotOutputString) {
   117  					t.Errorf("run() got output %q; want output regex %q", gotOutputString, tt.wantOutputRegex)
   118  				}
   119  			} else if gotOutputString != tt.wantOutput {
   120  				t.Errorf("run() got output %q; want output %q", gotOutputString, tt.wantOutput)
   121  			}
   122  
   123  			if tt.wantTransfers != nil && !reflect.DeepEqual(s.Transfers, tt.wantTransfers) {
   124  				t.Errorf("run() got transfers %#v; want transfers %#v", s.Transfers, tt.wantTransfers)
   125  			}
   126  		})
   127  	}
   128  }