github.com/linuxboot/fiano@v1.2.0/pkg/amd/apcb/apcb_test.go (about)

     1  // Copyright 2023 the LinuxBoot 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 apcb
     6  
     7  import (
     8  	"bytes"
     9  	"encoding/binary"
    10  	"fmt"
    11  	"io/ioutil"
    12  	"path"
    13  	"testing"
    14  
    15  	"github.com/stretchr/testify/require"
    16  	"github.com/ulikunitz/xz"
    17  )
    18  
    19  func TestParsingTokens(t *testing.T) {
    20  	apcbBinary, err := getFile("apcb_binary.xz")
    21  	require.NoError(t, err)
    22  	require.NotEmpty(t, apcbBinary)
    23  
    24  	tokens, err := ParseAPCBBinaryTokens(apcbBinary)
    25  	require.NoError(t, err)
    26  	require.Len(t, tokens, 40)
    27  
    28  	token := findToken(0x3E7D5274, tokens)
    29  	require.NotNil(t, token)
    30  	require.Equal(t, CreatePriorityMask(PriorityLevelMedium), token.PriorityMask)
    31  	require.Equal(t, uint16(0xFFFF), token.BoardMask)
    32  	require.Equal(t, uint32(2044), token.Value)
    33  	require.Equal(t, uint32(2044), token.NumValue())
    34  
    35  	token = findToken(0xE1CC135E, tokens)
    36  	require.NotNil(t, token)
    37  	require.Equal(t, CreatePriorityMask(PriorityLevelMedium), token.PriorityMask)
    38  	require.Equal(t, uint16(0xFFFF), token.BoardMask)
    39  	require.Equal(t, false, token.Value)
    40  	require.Equal(t, uint32(0), token.NumValue())
    41  }
    42  
    43  func TestUpsertToken(t *testing.T) {
    44  	t.Run("update_existing_token", func(t *testing.T) {
    45  		apcbBinary, err := getFile("apcb_binary.xz")
    46  		require.NoError(t, err)
    47  		require.NotEmpty(t, apcbBinary)
    48  
    49  		require.NoError(t, UpsertToken(0x3E7D5274, 0xff, 0xffff, uint32(0xffffffff), apcbBinary))
    50  
    51  		tokens, err := ParseAPCBBinaryTokens(apcbBinary)
    52  		require.NoError(t, err)
    53  		require.Len(t, tokens, 40)
    54  
    55  		token := findToken(0x3E7D5274, tokens)
    56  		require.NotNil(t, token)
    57  		require.Equal(t, uint32(0xffffffff), token.NumValue())
    58  	})
    59  
    60  	t.Run("insert_new_token", func(t *testing.T) {
    61  		apcbBinary, err := getFile("apcb_binary.xz")
    62  		require.NoError(t, err)
    63  		require.NotEmpty(t, apcbBinary)
    64  
    65  		require.NoError(t, UpsertToken(0xFFFFAAAA, 0xff, 0xffff, uint32(0xffffffff), apcbBinary))
    66  
    67  		tokens, err := ParseAPCBBinaryTokens(apcbBinary)
    68  		require.NoError(t, err)
    69  		require.Len(t, tokens, 41)
    70  
    71  		token := findToken(0xFFFFAAAA, tokens)
    72  		require.NotNil(t, token)
    73  		require.Equal(t, uint32(0xffffffff), token.NumValue())
    74  	})
    75  
    76  	t.Run("insert_new_token_no_type", func(t *testing.T) {
    77  		apcbBinary, err := getFile("apcb_binary.xz")
    78  		require.NoError(t, err)
    79  		require.NotEmpty(t, apcbBinary)
    80  
    81  		h, _, err := parseAPCBHeader(apcbBinary)
    82  		require.NoError(t, err)
    83  		h.V2Header.SizeOfAPCB = uint32(binary.Size(h))
    84  
    85  		resultBuffer := make([]byte, binary.Size(h)+1000)
    86  		require.NoError(t, writeFixedBuffer(resultBuffer, h))
    87  		tokens, err := ParseAPCBBinaryTokens(resultBuffer)
    88  		require.NoError(t, err)
    89  		require.Empty(t, tokens)
    90  
    91  		require.NoError(t, UpsertToken(0xFFFFAAAA, 0xff, 0xffff, uint32(0xffffffff), resultBuffer))
    92  
    93  		tokens, err = ParseAPCBBinaryTokens(resultBuffer)
    94  		require.NoError(t, err)
    95  		require.Len(t, tokens, 1)
    96  
    97  		require.NoError(t, UpsertToken(0xFFFFBBBB, 0xff, 0xffff, bool(true), resultBuffer))
    98  		tokens, err = ParseAPCBBinaryTokens(resultBuffer)
    99  		require.NoError(t, err)
   100  		require.Len(t, tokens, 2)
   101  	})
   102  }
   103  
   104  func findToken(tokenID TokenID, tokens []Token) *Token {
   105  	for _, token := range tokens {
   106  		if token.ID == tokenID {
   107  			return &token
   108  		}
   109  	}
   110  	return nil
   111  }
   112  
   113  func getFile(filename string) ([]byte, error) {
   114  	compressedImage, err := ioutil.ReadFile(path.Join("testdata", filename))
   115  	if err != nil {
   116  		return nil, fmt.Errorf("failed to read firmware image: %w", err)
   117  	}
   118  
   119  	r, err := xz.NewReader(bytes.NewReader(compressedImage))
   120  	if err != nil {
   121  		return nil, fmt.Errorf("unable to create an xz reader for a cached image: %w", err)
   122  	}
   123  
   124  	decompressedImage, err := ioutil.ReadAll(r)
   125  	if err != nil {
   126  		return nil, fmt.Errorf("unable to decompress the image: %w", err)
   127  	}
   128  
   129  	return decompressedImage, nil
   130  }