aboutsummaryrefslogtreecommitdiff
path: root/hotline/server_blackbox_test.go
blob: bfd9e9c49ddad18b291f763b8f1d4bed7e1149e9 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
package hotline

import (
	"cmp"
	"encoding/binary"
	"encoding/hex"
	"log/slog"
	"os"
	"slices"
	"testing"

	"github.com/stretchr/testify/assert"
)

func NewTestLogger() *slog.Logger {
	return slog.New(slog.NewTextHandler(os.Stdout, nil))
}

// flatFileTimestampOffset is the byte offset of the information fork's CreateDate within a
// flattened file object stream: FlatFileHeader (24) + INFO FlatFileForkHeader (16) + the info
// fork's fixed fields up to CreateDate (Platform+TypeSignature+CreatorSignature+Flags+
// PlatformFlags = 20, then RSVD = 32). CreateDate and ModifyDate are 8 bytes each and adjacent.
const (
	flatFileTimestampOffset = 24 + 16 + 20 + 32
	flatFileTimestampLen    = 16 // CreateDate (8) + ModifyDate (8)
)

// assertTransferBytesEqual takes a string with a hexdump in the same format that `hexdump -C`
// produces and compares with a hexdump for the bytes in got, after zeroing the info fork's
// create/modify timestamps. Git does not preserve file create/modify times, so those bytes vary
// between checkouts; the offset is derived structurally from the flattened file object layout
// rather than hardcoded (see flatFileTimestampOffset).
func assertTransferBytesEqual(t *testing.T, wantHexDump string, got []byte) bool {
	if wantHexDump == "" {
		return true
	}

	clean := slices.Clone(got)
	if len(clean) >= flatFileTimestampOffset+flatFileTimestampLen {
		for i := flatFileTimestampOffset; i < flatFileTimestampOffset+flatFileTimestampLen; i++ {
			clean[i] = 0
		}
	}
	return assert.Equal(t, wantHexDump, hex.Dump(clean))
}

var tranSortFunc = func(a, b Transaction) int {
	return cmp.Compare(
		binary.BigEndian.Uint16(a.ClientID[:]),
		binary.BigEndian.Uint16(b.ClientID[:]),
	)
}

// TranAssertEqual compares equality of transactions slices after stripping out the random transaction Type
func TranAssertEqual(t *testing.T, tran1, tran2 []Transaction) bool {
	var newT1 []Transaction
	var newT2 []Transaction

	for _, trans := range tran1 {
		trans.ID = [4]byte{0, 0, 0, 0}
		var fs []Field
		for _, field := range trans.Fields {
			if field.Type == FieldRefNum { // FieldRefNum
				continue
			}
			if field.Type == FieldChatID { // FieldChatID
				continue
			}

			fs = append(fs, field)
		}
		trans.Fields = fs
		newT1 = append(newT1, trans)
	}

	for _, trans := range tran2 {
		trans.ID = [4]byte{0, 0, 0, 0}
		var fs []Field
		for _, field := range trans.Fields {
			if field.Type == FieldRefNum { // FieldRefNum
				continue
			}
			if field.Type == FieldChatID { // FieldChatID
				continue
			}

			fs = append(fs, field)
		}
		trans.Fields = fs
		newT2 = append(newT2, trans)
	}

	slices.SortFunc(newT1, tranSortFunc)
	slices.SortFunc(newT2, tranSortFunc)

	return assert.Equal(t, newT1, newT2)
}