1package handlers
2
3import "testing"
4
5var blobUploadStates = []blobUploadState{
6	{
7		Name:   "hello",
8		UUID:   "abcd-1234-qwer-0987",
9		Offset: 0,
10	},
11	{
12		Name:   "hello-world",
13		UUID:   "abcd-1234-qwer-0987",
14		Offset: 0,
15	},
16	{
17		Name:   "h3ll0_w0rld",
18		UUID:   "abcd-1234-qwer-0987",
19		Offset: 1337,
20	},
21	{
22		Name:   "ABCDEFG",
23		UUID:   "ABCD-1234-QWER-0987",
24		Offset: 1234567890,
25	},
26	{
27		Name:   "this-is-A-sort-of-Long-name-for-Testing",
28		UUID:   "dead-1234-beef-0987",
29		Offset: 8675309,
30	},
31}
32
33var secrets = []string{
34	"supersecret",
35	"12345",
36	"a",
37	"SuperSecret",
38	"Sup3r... S3cr3t!",
39	"This is a reasonably long secret key that is used for the purpose of testing.",
40	"\u2603+\u2744", // snowman+snowflake
41}
42
43// TestLayerUploadTokens constructs stateTokens from LayerUploadStates and
44// validates that the tokens can be used to reconstruct the proper upload state.
45func TestLayerUploadTokens(t *testing.T) {
46	secret := hmacKey("supersecret")
47
48	for _, testcase := range blobUploadStates {
49		token, err := secret.packUploadState(testcase)
50		if err != nil {
51			t.Fatal(err)
52		}
53
54		lus, err := secret.unpackUploadState(token)
55		if err != nil {
56			t.Fatal(err)
57		}
58
59		assertBlobUploadStateEquals(t, testcase, lus)
60	}
61}
62
63// TestHMACValidate ensures that any HMAC token providers are compatible if and
64// only if they share the same secret.
65func TestHMACValidation(t *testing.T) {
66	for _, secret := range secrets {
67		secret1 := hmacKey(secret)
68		secret2 := hmacKey(secret)
69		badSecret := hmacKey("DifferentSecret")
70
71		for _, testcase := range blobUploadStates {
72			token, err := secret1.packUploadState(testcase)
73			if err != nil {
74				t.Fatal(err)
75			}
76
77			lus, err := secret2.unpackUploadState(token)
78			if err != nil {
79				t.Fatal(err)
80			}
81
82			assertBlobUploadStateEquals(t, testcase, lus)
83
84			_, err = badSecret.unpackUploadState(token)
85			if err == nil {
86				t.Fatalf("Expected token provider to fail at retrieving state from token: %s", token)
87			}
88
89			badToken, err := badSecret.packUploadState(lus)
90			if err != nil {
91				t.Fatal(err)
92			}
93
94			_, err = secret1.unpackUploadState(badToken)
95			if err == nil {
96				t.Fatalf("Expected token provider to fail at retrieving state from token: %s", badToken)
97			}
98
99			_, err = secret2.unpackUploadState(badToken)
100			if err == nil {
101				t.Fatalf("Expected token provider to fail at retrieving state from token: %s", badToken)
102			}
103		}
104	}
105}
106
107func assertBlobUploadStateEquals(t *testing.T, expected blobUploadState, received blobUploadState) {
108	if expected.Name != received.Name {
109		t.Fatalf("Expected Name=%q, Received Name=%q", expected.Name, received.Name)
110	}
111	if expected.UUID != received.UUID {
112		t.Fatalf("Expected UUID=%q, Received UUID=%q", expected.UUID, received.UUID)
113	}
114	if expected.Offset != received.Offset {
115		t.Fatalf("Expected Offset=%d, Received Offset=%d", expected.Offset, received.Offset)
116	}
117}
118