Commit 363d8a6f authored by Eric Paris's avatar Eric Paris

Remove all _test.go files in Godep

parent 407f9b9e

Too many changes to show.

To preserve performance only 1000 of 1000+ files are displayed.

// Copyright (c) 2013 Phillip Bond
// Licensed under the MIT License
// see file LICENSE
package systemstat_test
import (
"bitbucket.org/bertimus9/systemstat"
"fmt"
)
var sample systemstat.MemSample
// This example shows how easy it is to get memory information
func Example_simple() {
sample = systemstat.GetMemSample()
fmt.Println("Total available RAM in kb:", sample.MemTotal, "k total")
fmt.Println("Used RAM in kb:", sample.MemUsed, "k used")
fmt.Println("Free RAM in kb:", sample.MemFree, "k free")
fmt.Printf("The output is similar to, but somewhat different than:\n\ttop -n1 | grep Mem:\n")
}
// Copyright (c) 2013 Phillip Bond
// Licensed under the MIT License
// see file LICENSE
package systemstat
import (
"fmt"
"testing"
)
var (
msgFail = "%v method fails. Expects %v, returns %v"
)
func TestGetUptime(t *testing.T) {
s := getUptime("testdata/uptime")
if s.Uptime != 18667.53 {
t.Errorf(msgFail, "getUptime", "18667.53", s.Uptime)
}
}
func TestGetLoadAvgSample(t *testing.T) {
s := getLoadAvgSample("testdata/loadavg")
fmt.Printf("%#v\n", s)
if s.One != 0.1 {
t.Errorf(msgFail, "getUptime", "0.1", s.One)
}
if s.Five != 0.15 {
t.Errorf(msgFail, "getUptime", "0.15", s.Five)
}
if s.Fifteen != 0.14 {
t.Errorf(msgFail, "getUptime", "0.14", s.Fifteen)
}
}
MemTotal: 3768292 kB
MemFree: 831872 kB
Buffers: 153268 kB
Cached: 1622412 kB
SwapCached: 0 kB
Active: 1287508 kB
Inactive: 1297924 kB
Active(anon): 811384 kB
Inactive(anon): 227652 kB
Active(file): 476124 kB
Inactive(file): 1070272 kB
Unevictable: 196 kB
Mlocked: 196 kB
SwapTotal: 7907324 kB
SwapFree: 7907324 kB
Dirty: 228 kB
Writeback: 0 kB
AnonPages: 809948 kB
Mapped: 226452 kB
Shmem: 229284 kB
Slab: 210268 kB
SReclaimable: 148028 kB
SUnreclaim: 62240 kB
KernelStack: 4344 kB
PageTables: 37932 kB
NFS_Unstable: 0 kB
Bounce: 0 kB
WritebackTmp: 0 kB
CommitLimit: 9791468 kB
Committed_AS: 4513904 kB
VmallocTotal: 34359738367 kB
VmallocUsed: 368496 kB
VmallocChunk: 34359365956 kB
HardwareCorrupted: 0 kB
AnonHugePages: 0 kB
HugePages_Total: 0
HugePages_Free: 0
HugePages_Rsvd: 0
HugePages_Surp: 0
Hugepagesize: 2048 kB
DirectMap4k: 126592 kB
DirectMap2M: 3786752 kB
28267 (go-top) S 28256 28256 27864 34816 28256 4202496 736 0 0 0 17470 14 0 0 20 0 7 0 1882735 274173952 571 18446744073709551615 4194368 5592552 140737466979680 139798064197344 4333379 0 0 0 2143420159 18446744073709551615 0 0 17 1 0 0 0 0 0
28267 (go-top) R 28256 28256 27864 34816 28256 4202496 736 0 0 0 18773 16 0 0 20 0 7 0 1882735 274173952 571 18446744073709551615 4194368 5592552 140737466979680 139798065368712 4457862 0 0 0 2143420159 18446744073709551615 0 0 17 3 0 0 0 0 0
28267 (go-top) R 28256 28256 27864 34816 28256 4202496 738 0 0 0 20618 18 0 0 20 0 7 0 1882735 274239488 571 18446744073709551615 4194368 5592552 140737466979680 140737466979424 4203351 0 0 0 2143420159 18446744073709551615 0 0 17 0 0 0 0 0 0
28267 (go-top) R 28256 28256 27864 34816 28256 4202496 738 0 0 0 21641 19 0 0 20 0 7 0 1882735 274239488 571 18446744073709551615 4194368 5592552 140737466979680 139798065356424 4333379 0 0 0 2143420159 18446744073709551615 0 0 17 0 0 0 0 0 0
28267 (go-top) R 28256 28256 27864 34816 28256 4202496 738 0 0 0 23722 21 0 0 20 0 7 0 1882735 274239488 571 18446744073709551615 4194368 5592552 140737466979680 139798065368712 4203351 0 0 0 2143420159 18446744073709551615 0 0 17 1 0 0 0 0 0
28267 (go-top) S 28256 28256 27864 34816 28256 4202496 741 0 0 0 25512 22 0 0 20 0 7 0 1882735 274305024 571 18446744073709551615 4194368 5592552 140737466979680 140737466979424 4333379 0 0 0 2143420159 18446744073709551615 0 0 17 2 0 0 0 0 0
cpu 17313 714 8241 717906 1456 0 364 0 0 0
cpu0 6642 289 3526 173411 1162 0 355 0 0 0
cpu1 2193 88 1066 183608 86 0 2 0 0 0
cpu2 6463 217 2578 177186 141 0 4 0 0 0
cpu3 2014 118 1070 183699 65 0 2 0 0 0
intr 2312829 54 5540 0 0 0 0 0 0 1 24723 0 0 262321 0 0 0 733 0 0 34 0 0 0 141 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 124099 1226 121928 26 141511 145 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
ctxt 3689186
btime 1374442803
processes 27752
procs_running 1
procs_blocked 0
softirq 923034 6 201522 63 2716 129127 6 168304 89194 629 331467
cpu 17328 714 8254 725156 1457 0 366 0 0 0
cpu0 6648 289 3531 175213 1164 0 356 0 0 0
cpu1 2198 88 1066 185425 86 0 2 0 0 0
cpu2 6466 217 2584 178996 141 0 4 0 0 0
cpu3 2015 118 1071 185521 65 0 2 0 0 0
intr 2316896 54 5562 0 0 0 0 0 0 1 24939 0 0 262321 0 0 0 733 0 0 34 0 0 0 141 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 124124 1226 123058 26 142249 145 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
ctxt 3694091
btime 1374442803
processes 27777
procs_running 1
procs_blocked 0
softirq 925673 6 202044 63 2716 129146 6 169061 89550 633 332448
cpu 18661 714 8322 736828 1463 0 367 0 0 0
cpu0 6715 289 3555 178374 1170 0 358 0 0 0
cpu1 3134 88 1080 187754 86 0 2 0 0 0
cpu2 6769 217 2603 181942 141 0 4 0 0 0
cpu3 2042 118 1082 188756 65 0 2 0 0 0
intr 2346985 54 5673 0 0 0 0 0 0 1 25358 0 0 269347 0 0 0 733 0 0 34 0 0 0 141 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 124230 1226 125412 26 143648 145 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
ctxt 3722386
btime 1374442803
processes 27939
procs_running 2
procs_blocked 0
softirq 939514 6 208124 63 2720 129245 6 170565 91355 637 336793
cpu 24106 714 8436 758512 1472 0 372 0 0 0
cpu0 7831 289 3602 183989 1177 0 361 0 0 0
cpu1 5075 88 1096 192627 86 0 3 0 0 0
cpu2 7667 217 2640 187814 142 0 5 0 0 0
cpu3 3531 118 1096 194081 66 0 2 0 0 0
intr 2425351 54 5880 0 0 0 0 0 0 1 26243 0 0 282247 0 0 0 733 0 0 34 0 0 0 141 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 124425 1226 130129 26 146647 145 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
ctxt 3788723
btime 1374442803
processes 28152
procs_running 1
procs_blocked 0
softirq 975972 6 226788 63 2738 129419 6 173753 98111 659 344429
cpu 25797 714 8461 761860 1472 0 375 0 0 0
cpu0 8406 289 3611 184664 1177 0 364 0 0 0
cpu1 5391 88 1102 193577 86 0 3 0 0 0
cpu2 8115 217 2646 188622 142 0 5 0 0 0
cpu3 3884 118 1100 194996 66 0 2 0 0 0
intr 2446830 54 5896 0 0 0 0 0 0 1 26399 0 0 286933 0 0 0 733 0 0 34 0 0 0 141 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 124455 1226 131103 26 147182 145 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
ctxt 3804378
btime 1374442803
processes 28177
procs_running 3
procs_blocked 0
softirq 985047 6 231802 63 2740 129448 6 174303 100182 665 345832
cpu 31643 714 8507 766175 1477 0 377 0 0 0
cpu0 9865 289 3628 185726 1182 0 366 0 0 0
cpu1 6867 88 1110 194656 86 0 3 0 0 0
cpu2 9658 217 2661 189610 142 0 5 0 0 0
cpu3 5252 118 1108 196181 66 0 2 0 0 0
intr 2492898 54 5942 0 0 0 0 0 0 1 26734 0 0 291667 0 0 0 733 0 0 34 0 0 0 141 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 124574 1226 133046 26 148246 145 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
ctxt 3836141
btime 1374442803
processes 28244
procs_running 5
procs_blocked 0
softirq 1009821 6 247713 63 2748 129565 6 175417 104452 670 349181
cpu 32813 714 8513 766223 1477 0 377 0 0 0
cpu0 10159 289 3628 185737 1182 0 367 0 0 0
cpu1 7162 88 1110 194668 86 0 3 0 0 0
cpu2 9945 217 2664 189623 142 0 5 0 0 0
cpu3 5546 118 1109 196193 66 0 2 0 0 0
intr 2498999 54 5954 0 0 0 0 0 0 1 26770 0 0 291667 0 0 0 733 0 0 34 0 0 0 141 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 124585 1226 133246 26 148377 145 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
ctxt 3839591
btime 1374442803
processes 28269
procs_running 5
procs_blocked 0
softirq 1014220 6 250668 63 2748 129576 6 175558 105038 670 349887
package goautoneg
import (
"testing"
)
var chrome = "application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5"
func TestParseAccept(t *testing.T) {
alternatives := []string{"text/html", "image/png"}
content_type := Negotiate(chrome, alternatives)
if content_type != "image/png" {
t.Errorf("got %s expected image/png", content_type)
}
alternatives = []string{"text/html", "text/plain", "text/n3"}
content_type = Negotiate(chrome, alternatives)
if content_type != "text/html" {
t.Errorf("got %s expected text/html", content_type)
}
alternatives = []string{"text/n3", "text/plain"}
content_type = Negotiate(chrome, alternatives)
if content_type != "text/plain" {
t.Errorf("got %s expected text/plain", content_type)
}
alternatives = []string{"text/n3", "application/rdf+xml"}
content_type = Negotiate(chrome, alternatives)
if content_type != "text/n3" {
t.Errorf("got %s expected text/n3", content_type)
}
}
package flocker
import (
"bytes"
"encoding/json"
"fmt"
"io/ioutil"
"net/http"
"net/http/httptest"
"net/url"
"strconv"
"strings"
"testing"
"time"
"k8s.io/kubernetes/pkg/volume"
"github.com/stretchr/testify/assert"
)
func TestMaximumSizeIs1024Multiple(t *testing.T) {
assert := assert.New(t)
n, err := strconv.Atoi(string(defaultVolumeSize))
assert.NoError(err)
assert.Equal(0, n%1024)
}
func TestPost(t *testing.T) {
const (
expectedPayload = "foobar"
expectedStatusCode = 418
)
assert := assert.New(t)
type payload struct {
Test string `json:"test"`
}
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
var result payload
err := json.NewDecoder(r.Body).Decode(&result)
assert.NoError(err)
assert.Equal(expectedPayload, result.Test)
w.WriteHeader(expectedStatusCode)
}))
defer ts.Close()
c := Client{Client: &http.Client{}}
resp, err := c.post(ts.URL, payload{expectedPayload})
assert.NoError(err)
assert.Equal(expectedStatusCode, resp.StatusCode)
}
func TestGet(t *testing.T) {
const (
expectedStatusCode = 418
)
assert := assert.New(t)
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(expectedStatusCode)
}))
defer ts.Close()
c := Client{Client: &http.Client{}}
resp, err := c.get(ts.URL)
assert.NoError(err)
assert.Equal(expectedStatusCode, resp.StatusCode)
}
func TestFindIDInConfigurationsPayload(t *testing.T) {
const (
searchedName = "search-for-this-name"
expected = "The-42-id"
)
assert := assert.New(t)
c := Client{}
payload := fmt.Sprintf(
`[{"dataset_id": "1-2-3", "metadata": {"name": "test"}}, {"dataset_id": "The-42-id", "metadata": {"name": "%s"}}]`,
searchedName,
)
id, err := c.findIDInConfigurationsPayload(
ioutil.NopCloser(bytes.NewBufferString(payload)), searchedName,
)
assert.NoError(err)
assert.Equal(expected, id)
id, err = c.findIDInConfigurationsPayload(
ioutil.NopCloser(bytes.NewBufferString(payload)), "it will not be found",
)
assert.Equal(errConfigurationNotFound, err)
id, err = c.findIDInConfigurationsPayload(
ioutil.NopCloser(bytes.NewBufferString("invalid { json")), "",
)
assert.Error(err)
}
func TestFindPrimaryUUID(t *testing.T) {
const expectedPrimary = "primary-uuid"
assert := assert.New(t)
var (
mockedHost = "127.0.0.1"
mockedPrimary = expectedPrimary
)
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
assert.Equal("GET", r.Method)
assert.Equal("/v1/state/nodes", r.URL.Path)
w.Write([]byte(fmt.Sprintf(`[{"host": "%s", "uuid": "%s"}]`, mockedHost, mockedPrimary)))
}))
host, port, err := getHostAndPortFromTestServer(ts)
assert.NoError(err)
c := newFlockerTestClient(host, port)
assert.NoError(err)
mockedPrimary = expectedPrimary
primary, err := c.GetPrimaryUUID()
assert.NoError(err)
assert.Equal(expectedPrimary, primary)
c.clientIP = "not.found"
_, err = c.GetPrimaryUUID()
assert.Equal(errStateNotFound, err)
}
func TestGetURL(t *testing.T) {
const (
expectedHost = "host"
expectedPort = 42
)
assert := assert.New(t)
c := newFlockerTestClient(expectedHost, expectedPort)
var expectedURL = fmt.Sprintf("%s://%s:%d/v1/test", c.schema, expectedHost, expectedPort)
url := c.getURL("test")
assert.Equal(expectedURL, url)
}
func getHostAndPortFromTestServer(ts *httptest.Server) (string, int, error) {
tsURL, err := url.Parse(ts.URL)
if err != nil {
return "", 0, err
}
hostSplits := strings.Split(tsURL.Host, ":")
port, err := strconv.Atoi(hostSplits[1])
if err != nil {
return "", 0, nil
}
return hostSplits[0], port, nil
}
func getVolumeConfig(host string, port int) volume.VolumeConfig {
return volume.VolumeConfig{
OtherAttributes: map[string]string{
"CONTROL_SERVICE_HOST": host,
"CONTROL_SERVICE_PORT": strconv.Itoa(port),
},
}
}
func TestHappyPathCreateDatasetFromNonExistent(t *testing.T) {
const (
expectedDatasetName = "dir"
expectedPrimary = "A-B-C-D"
expectedDatasetID = "datasetID"
)
expectedPath := fmt.Sprintf("/flocker/%s", expectedDatasetID)
assert := assert.New(t)
var (
numCalls int
err error
)
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
numCalls++
switch numCalls {
case 1:
assert.Equal("GET", r.Method)
assert.Equal("/v1/state/nodes", r.URL.Path)
w.Write([]byte(fmt.Sprintf(`[{"host": "127.0.0.1", "uuid": "%s"}]`, expectedPrimary)))
case 2:
assert.Equal("POST", r.Method)
assert.Equal("/v1/configuration/datasets", r.URL.Path)
var c configurationPayload
err := json.NewDecoder(r.Body).Decode(&c)
assert.NoError(err)
assert.Equal(expectedPrimary, c.Primary)
assert.Equal(defaultVolumeSize, c.MaximumSize)
assert.Equal(expectedDatasetName, c.Metadata.Name)
w.Write([]byte(fmt.Sprintf(`{"dataset_id": "%s"}`, expectedDatasetID)))
case 3:
assert.Equal("GET", r.Method)
assert.Equal("/v1/state/datasets", r.URL.Path)
w.Write([]byte(`[]`))
case 4:
assert.Equal("GET", r.Method)
assert.Equal("/v1/state/datasets", r.URL.Path)
w.Write([]byte(fmt.Sprintf(`[{"dataset_id": "%s", "path": "/flocker/%s"}]`, expectedDatasetID, expectedDatasetID)))
}
}))
host, port, err := getHostAndPortFromTestServer(ts)
assert.NoError(err)
c := newFlockerTestClient(host, port)
assert.NoError(err)
tickerWaitingForVolume = 1 * time.Millisecond // TODO: this is overriding globally
s, err := c.CreateDataset(expectedDatasetName)
assert.NoError(err)
assert.Equal(expectedPath, s.Path)
}
func TestCreateDatasetThatAlreadyExists(t *testing.T) {
const (
datasetName = "dir"
expectedPrimary = "A-B-C-D"
)
assert := assert.New(t)
var numCalls int
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
numCalls++
switch numCalls {
case 1:
assert.Equal("GET", r.Method)
assert.Equal("/v1/state/nodes", r.URL.Path)
w.Write([]byte(fmt.Sprintf(`[{"host": "127.0.0.1", "uuid": "%s"}]`, expectedPrimary)))
case 2:
assert.Equal("POST", r.Method)
assert.Equal("/v1/configuration/datasets", r.URL.Path)
w.WriteHeader(http.StatusConflict)
}
}))
host, port, err := getHostAndPortFromTestServer(ts)
assert.NoError(err)
c := newFlockerTestClient(host, port)
assert.NoError(err)
_, err = c.CreateDataset(datasetName)
assert.Equal(errVolumeAlreadyExists, err)
}
func TestUpdatePrimaryForDataset(t *testing.T) {
const (
dir = "dir"
expectedPrimary = "the-new-primary"
expectedDatasetID = "datasetID"
)
expectedURL := fmt.Sprintf("/v1/configuration/datasets/%s", expectedDatasetID)
assert := assert.New(t)
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
assert.Equal("POST", r.Method)
assert.Equal(expectedURL, r.URL.Path)
var c configurationPayload
err := json.NewDecoder(r.Body).Decode(&c)
assert.NoError(err)
assert.Equal(expectedPrimary, c.Primary)
w.Write([]byte(fmt.Sprintf(`{"dataset_id": "%s", "path": "just-to-double-check"}`, expectedDatasetID)))
}))
host, port, err := getHostAndPortFromTestServer(ts)
assert.NoError(err)
c := newFlockerTestClient(host, port)
assert.NoError(err)
s, err := c.UpdatePrimaryForDataset(expectedPrimary, expectedDatasetID)
assert.NoError(err)
assert.Equal(expectedDatasetID, s.DatasetID)
assert.NotEqual("", s.Path)
}
func TestInterfaceIsImplemented(t *testing.T) {
assert.Implements(t, (*Clientable)(nil), Client{})
}
func newFlockerTestClient(host string, port int) *Client {
return &Client{
Client: &http.Client{},
host: host,
port: port,
version: "v1",
schema: "http",
maximumSize: defaultVolumeSize,
clientIP: "127.0.0.1",
}
}
package logrus
import (
"bytes"
"fmt"
"testing"
"github.com/stretchr/testify/assert"
)
func TestEntryPanicln(t *testing.T) {
errBoom := fmt.Errorf("boom time")
defer func() {
p := recover()
assert.NotNil(t, p)
switch pVal := p.(type) {
case *Entry:
assert.Equal(t, "kaboom", pVal.Message)
assert.Equal(t, errBoom, pVal.Data["err"])
default:
t.Fatalf("want type *Entry, got %T: %#v", pVal, pVal)
}
}()
logger := New()
logger.Out = &bytes.Buffer{}
entry := NewEntry(logger)
entry.WithField("err", errBoom).Panicln("kaboom")
}
func TestEntryPanicf(t *testing.T) {
errBoom := fmt.Errorf("boom again")
defer func() {
p := recover()
assert.NotNil(t, p)
switch pVal := p.(type) {
case *Entry:
assert.Equal(t, "kaboom true", pVal.Message)
assert.Equal(t, errBoom, pVal.Data["err"])
default:
t.Fatalf("want type *Entry, got %T: %#v", pVal, pVal)
}
}()
logger := New()
logger.Out = &bytes.Buffer{}
entry := NewEntry(logger)
entry.WithField("err", errBoom).Panicf("kaboom %v", true)
}
package logrus
import (
"testing"
"time"
)
// smallFields is a small size data set for benchmarking
var smallFields = Fields{
"foo": "bar",
"baz": "qux",
"one": "two",
"three": "four",
}
// largeFields is a large size data set for benchmarking
var largeFields = Fields{
"foo": "bar",
"baz": "qux",
"one": "two",
"three": "four",
"five": "six",
"seven": "eight",
"nine": "ten",
"eleven": "twelve",
"thirteen": "fourteen",
"fifteen": "sixteen",
"seventeen": "eighteen",
"nineteen": "twenty",
"a": "b",
"c": "d",
"e": "f",
"g": "h",
"i": "j",
"k": "l",
"m": "n",
"o": "p",
"q": "r",
"s": "t",
"u": "v",
"w": "x",
"y": "z",
"this": "will",
"make": "thirty",
"entries": "yeah",
}
func BenchmarkSmallTextFormatter(b *testing.B) {
doBenchmark(b, &TextFormatter{DisableColors: true}, smallFields)
}
func BenchmarkLargeTextFormatter(b *testing.B) {
doBenchmark(b, &TextFormatter{DisableColors: true}, largeFields)
}
func BenchmarkSmallColoredTextFormatter(b *testing.B) {
doBenchmark(b, &TextFormatter{ForceColors: true}, smallFields)
}
func BenchmarkLargeColoredTextFormatter(b *testing.B) {
doBenchmark(b, &TextFormatter{ForceColors: true}, largeFields)
}
func BenchmarkSmallJSONFormatter(b *testing.B) {
doBenchmark(b, &JSONFormatter{}, smallFields)
}
func BenchmarkLargeJSONFormatter(b *testing.B) {
doBenchmark(b, &JSONFormatter{}, largeFields)
}
func doBenchmark(b *testing.B, formatter Formatter, fields Fields) {
entry := &Entry{
Time: time.Time{},
Level: InfoLevel,
Message: "message",
Data: fields,
}
var d []byte
var err error
for i := 0; i < b.N; i++ {
d, err = formatter.Format(entry)
if err != nil {
b.Fatal(err)
}
b.SetBytes(int64(len(d)))
}
}
package logrus
import (
"testing"
"github.com/stretchr/testify/assert"
)
type TestHook struct {
Fired bool
}
func (hook *TestHook) Fire(entry *Entry) error {
hook.Fired = true
return nil
}
func (hook *TestHook) Levels() []Level {
return []Level{
DebugLevel,
InfoLevel,
WarnLevel,
ErrorLevel,
FatalLevel,
PanicLevel,
}
}
func TestHookFires(t *testing.T) {
hook := new(TestHook)
LogAndAssertJSON(t, func(log *Logger) {
log.Hooks.Add(hook)
assert.Equal(t, hook.Fired, false)
log.Print("test")
}, func(fields Fields) {
assert.Equal(t, hook.Fired, true)
})
}
type ModifyHook struct {
}
func (hook *ModifyHook) Fire(entry *Entry) error {
entry.Data["wow"] = "whale"
return nil
}
func (hook *ModifyHook) Levels() []Level {
return []Level{
DebugLevel,
InfoLevel,
WarnLevel,
ErrorLevel,
FatalLevel,
PanicLevel,
}
}
func TestHookCanModifyEntry(t *testing.T) {
hook := new(ModifyHook)
LogAndAssertJSON(t, func(log *Logger) {
log.Hooks.Add(hook)
log.WithField("wow", "elephant").Print("test")
}, func(fields Fields) {
assert.Equal(t, fields["wow"], "whale")
})
}
func TestCanFireMultipleHooks(t *testing.T) {
hook1 := new(ModifyHook)
hook2 := new(TestHook)
LogAndAssertJSON(t, func(log *Logger) {
log.Hooks.Add(hook1)
log.Hooks.Add(hook2)
log.WithField("wow", "elephant").Print("test")
}, func(fields Fields) {
assert.Equal(t, fields["wow"], "whale")
assert.Equal(t, hook2.Fired, true)
})
}
type ErrorHook struct {
Fired bool
}
func (hook *ErrorHook) Fire(entry *Entry) error {
hook.Fired = true
return nil
}
func (hook *ErrorHook) Levels() []Level {
return []Level{
ErrorLevel,
}
}
func TestErrorHookShouldntFireOnInfo(t *testing.T) {
hook := new(ErrorHook)
LogAndAssertJSON(t, func(log *Logger) {
log.Hooks.Add(hook)
log.Info("test")
}, func(fields Fields) {
assert.Equal(t, hook.Fired, false)
})
}
func TestErrorHookShouldFireOnError(t *testing.T) {
hook := new(ErrorHook)
LogAndAssertJSON(t, func(log *Logger) {
log.Hooks.Add(hook)
log.Error("test")
}, func(fields Fields) {
assert.Equal(t, hook.Fired, true)
})
}
package logrus_papertrail
import (
"fmt"
"testing"
"github.com/Sirupsen/logrus"
"github.com/stvp/go-udp-testing"
)
func TestWritingToUDP(t *testing.T) {
port := 16661
udp.SetAddr(fmt.Sprintf(":%d", port))
hook, err := NewPapertrailHook("localhost", port, "test")
if err != nil {
t.Errorf("Unable to connect to local UDP server.")
}
log := logrus.New()
log.Hooks.Add(hook)
udp.ShouldReceive(t, "foo", func() {
log.Info("foo")
})
}
package logrus_sentry
import (
"encoding/json"
"fmt"
"io/ioutil"
"net/http"
"net/http/httptest"
"strings"
"testing"
"github.com/Sirupsen/logrus"
"github.com/getsentry/raven-go"
)
const (
message = "error message"
server_name = "testserver.internal"
logger_name = "test.logger"
)
func getTestLogger() *logrus.Logger {
l := logrus.New()
l.Out = ioutil.Discard
return l
}
func WithTestDSN(t *testing.T, tf func(string, <-chan *raven.Packet)) {
pch := make(chan *raven.Packet, 1)
s := httptest.NewServer(http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
defer req.Body.Close()
d := json.NewDecoder(req.Body)
p := &raven.Packet{}
err := d.Decode(p)
if err != nil {
t.Fatal(err.Error())
}
pch <- p
}))
defer s.Close()
fragments := strings.SplitN(s.URL, "://", 2)
dsn := fmt.Sprintf(
"%s://public:secret@%s/sentry/project-id",
fragments[0],
fragments[1],
)
tf(dsn, pch)
}
func TestSpecialFields(t *testing.T) {
WithTestDSN(t, func(dsn string, pch <-chan *raven.Packet) {
logger := getTestLogger()
hook, err := NewSentryHook(dsn, []logrus.Level{
logrus.ErrorLevel,
})
if err != nil {
t.Fatal(err.Error())
}
logger.Hooks.Add(hook)
logger.WithFields(logrus.Fields{
"server_name": server_name,
"logger": logger_name,
}).Error(message)
packet := <-pch
if packet.Logger != logger_name {
t.Errorf("logger should have been %s, was %s", logger_name, packet.Logger)
}
if packet.ServerName != server_name {
t.Errorf("server_name should have been %s, was %s", server_name, packet.ServerName)
}
})
}
func TestSentryHandler(t *testing.T) {
WithTestDSN(t, func(dsn string, pch <-chan *raven.Packet) {
logger := getTestLogger()
hook, err := NewSentryHook(dsn, []logrus.Level{
logrus.ErrorLevel,
})
if err != nil {
t.Fatal(err.Error())
}
logger.Hooks.Add(hook)
logger.Error(message)
packet := <-pch
if packet.Message != message {
t.Errorf("message should have been %s, was %s", message, packet.Message)
}
})
}
package logrus_syslog
import (
"github.com/Sirupsen/logrus"
"log/syslog"
"testing"
)
func TestLocalhostAddAndPrint(t *testing.T) {
log := logrus.New()
hook, err := NewSyslogHook("udp", "localhost:514", syslog.LOG_INFO, "")
if err != nil {
t.Errorf("Unable to connect to local syslog.")
}
log.Hooks.Add(hook)
for _, level := range hook.Levels() {
if len(log.Hooks[level]) != 1 {
t.Errorf("SyslogHook was not added. The length of log.Hooks[%v]: %v", level, len(log.Hooks[level]))
}
}
log.Info("Congratulations!")
}
package logrus
import (
"bytes"
"encoding/json"
"strconv"
"strings"
"testing"
"github.com/stretchr/testify/assert"
)
func LogAndAssertJSON(t *testing.T, log func(*Logger), assertions func(fields Fields)) {
var buffer bytes.Buffer
var fields Fields
logger := New()
logger.Out = &buffer
logger.Formatter = new(JSONFormatter)
log(logger)
err := json.Unmarshal(buffer.Bytes(), &fields)
assert.Nil(t, err)
assertions(fields)
}
func LogAndAssertText(t *testing.T, log func(*Logger), assertions func(fields map[string]string)) {
var buffer bytes.Buffer
logger := New()
logger.Out = &buffer
logger.Formatter = &TextFormatter{
DisableColors: true,
}
log(logger)
fields := make(map[string]string)
for _, kv := range strings.Split(buffer.String(), " ") {
if !strings.Contains(kv, "=") {
continue
}
kvArr := strings.Split(kv, "=")
key := strings.TrimSpace(kvArr[0])
val := kvArr[1]
if kvArr[1][0] == '"' {
var err error
val, err = strconv.Unquote(val)
assert.NoError(t, err)
}
fields[key] = val
}
assertions(fields)
}
func TestPrint(t *testing.T) {
LogAndAssertJSON(t, func(log *Logger) {
log.Print("test")
}, func(fields Fields) {
assert.Equal(t, fields["msg"], "test")
assert.Equal(t, fields["level"], "info")
})
}
func TestInfo(t *testing.T) {
LogAndAssertJSON(t, func(log *Logger) {
log.Info("test")
}, func(fields Fields) {
assert.Equal(t, fields["msg"], "test")
assert.Equal(t, fields["level"], "info")
})
}
func TestWarn(t *testing.T) {
LogAndAssertJSON(t, func(log *Logger) {
log.Warn("test")
}, func(fields Fields) {
assert.Equal(t, fields["msg"], "test")
assert.Equal(t, fields["level"], "warning")
})
}
func TestInfolnShouldAddSpacesBetweenStrings(t *testing.T) {
LogAndAssertJSON(t, func(log *Logger) {
log.Infoln("test", "test")
}, func(fields Fields) {
assert.Equal(t, fields["msg"], "test test")
})
}
func TestInfolnShouldAddSpacesBetweenStringAndNonstring(t *testing.T) {
LogAndAssertJSON(t, func(log *Logger) {
log.Infoln("test", 10)
}, func(fields Fields) {
assert.Equal(t, fields["msg"], "test 10")
})
}
func TestInfolnShouldAddSpacesBetweenTwoNonStrings(t *testing.T) {
LogAndAssertJSON(t, func(log *Logger) {
log.Infoln(10, 10)
}, func(fields Fields) {
assert.Equal(t, fields["msg"], "10 10")
})
}
func TestInfoShouldAddSpacesBetweenTwoNonStrings(t *testing.T) {
LogAndAssertJSON(t, func(log *Logger) {
log.Infoln(10, 10)
}, func(fields Fields) {
assert.Equal(t, fields["msg"], "10 10")
})
}
func TestInfoShouldNotAddSpacesBetweenStringAndNonstring(t *testing.T) {
LogAndAssertJSON(t, func(log *Logger) {
log.Info("test", 10)
}, func(fields Fields) {
assert.Equal(t, fields["msg"], "test10")
})
}
func TestInfoShouldNotAddSpacesBetweenStrings(t *testing.T) {
LogAndAssertJSON(t, func(log *Logger) {
log.Info("test", "test")
}, func(fields Fields) {
assert.Equal(t, fields["msg"], "testtest")
})
}
func TestWithFieldsShouldAllowAssignments(t *testing.T) {
var buffer bytes.Buffer
var fields Fields
logger := New()
logger.Out = &buffer
logger.Formatter = new(JSONFormatter)
localLog := logger.WithFields(Fields{
"key1": "value1",
})
localLog.WithField("key2", "value2").Info("test")
err := json.Unmarshal(buffer.Bytes(), &fields)
assert.Nil(t, err)
assert.Equal(t, "value2", fields["key2"])
assert.Equal(t, "value1", fields["key1"])
buffer = bytes.Buffer{}
fields = Fields{}
localLog.Info("test")
err = json.Unmarshal(buffer.Bytes(), &fields)
assert.Nil(t, err)
_, ok := fields["key2"]
assert.Equal(t, false, ok)
assert.Equal(t, "value1", fields["key1"])
}
func TestUserSuppliedFieldDoesNotOverwriteDefaults(t *testing.T) {
LogAndAssertJSON(t, func(log *Logger) {
log.WithField("msg", "hello").Info("test")
}, func(fields Fields) {
assert.Equal(t, fields["msg"], "test")
})
}
func TestUserSuppliedMsgFieldHasPrefix(t *testing.T) {
LogAndAssertJSON(t, func(log *Logger) {
log.WithField("msg", "hello").Info("test")
}, func(fields Fields) {
assert.Equal(t, fields["msg"], "test")
assert.Equal(t, fields["fields.msg"], "hello")
})
}
func TestUserSuppliedTimeFieldHasPrefix(t *testing.T) {
LogAndAssertJSON(t, func(log *Logger) {
log.WithField("time", "hello").Info("test")
}, func(fields Fields) {
assert.Equal(t, fields["fields.time"], "hello")
})
}
func TestUserSuppliedLevelFieldHasPrefix(t *testing.T) {
LogAndAssertJSON(t, func(log *Logger) {
log.WithField("level", 1).Info("test")
}, func(fields Fields) {
assert.Equal(t, fields["level"], "info")
assert.Equal(t, fields["fields.level"], 1)
})
}
func TestDefaultFieldsAreNotPrefixed(t *testing.T) {
LogAndAssertText(t, func(log *Logger) {
ll := log.WithField("herp", "derp")
ll.Info("hello")
ll.Info("bye")
}, func(fields map[string]string) {
for _, fieldName := range []string{"fields.level", "fields.time", "fields.msg"} {
if _, ok := fields[fieldName]; ok {
t.Fatalf("should not have prefixed %q: %v", fieldName, fields)
}
}
})
}
func TestDoubleLoggingDoesntPrefixPreviousFields(t *testing.T) {
var buffer bytes.Buffer
var fields Fields
logger := New()
logger.Out = &buffer
logger.Formatter = new(JSONFormatter)
llog := logger.WithField("context", "eating raw fish")
llog.Info("looks delicious")
err := json.Unmarshal(buffer.Bytes(), &fields)
assert.NoError(t, err, "should have decoded first message")
assert.Len(t, fields, 4, "should only have msg/time/level/context fields")
assert.Equal(t, fields["msg"], "looks delicious")
assert.Equal(t, fields["context"], "eating raw fish")
buffer.Reset()
llog.Warn("omg it is!")
err = json.Unmarshal(buffer.Bytes(), &fields)
assert.NoError(t, err, "should have decoded second message")
assert.Len(t, fields, 4, "should only have msg/time/level/context fields")
assert.Equal(t, fields["msg"], "omg it is!")
assert.Equal(t, fields["context"], "eating raw fish")
assert.Nil(t, fields["fields.msg"], "should not have prefixed previous `msg` entry")
}
func TestConvertLevelToString(t *testing.T) {
assert.Equal(t, "debug", DebugLevel.String())
assert.Equal(t, "info", InfoLevel.String())
assert.Equal(t, "warning", WarnLevel.String())
assert.Equal(t, "error", ErrorLevel.String())
assert.Equal(t, "fatal", FatalLevel.String())
assert.Equal(t, "panic", PanicLevel.String())
}
func TestParseLevel(t *testing.T) {
l, err := ParseLevel("panic")
assert.Nil(t, err)
assert.Equal(t, PanicLevel, l)
l, err = ParseLevel("fatal")
assert.Nil(t, err)
assert.Equal(t, FatalLevel, l)
l, err = ParseLevel("error")
assert.Nil(t, err)
assert.Equal(t, ErrorLevel, l)
l, err = ParseLevel("warn")
assert.Nil(t, err)
assert.Equal(t, WarnLevel, l)
l, err = ParseLevel("warning")
assert.Nil(t, err)
assert.Equal(t, WarnLevel, l)
l, err = ParseLevel("info")
assert.Nil(t, err)
assert.Equal(t, InfoLevel, l)
l, err = ParseLevel("debug")
assert.Nil(t, err)
assert.Equal(t, DebugLevel, l)
l, err = ParseLevel("invalid")
assert.Equal(t, "not a valid logrus Level: \"invalid\"", err.Error())
}
package logrus
import (
"bytes"
"errors"
"testing"
)
func TestQuoting(t *testing.T) {
tf := &TextFormatter{DisableColors: true}
checkQuoting := func(q bool, value interface{}) {
b, _ := tf.Format(WithField("test", value))
idx := bytes.Index(b, ([]byte)("test="))
cont := bytes.Contains(b[idx+5:], []byte{'"'})
if cont != q {
if q {
t.Errorf("quoting expected for: %#v", value)
} else {
t.Errorf("quoting not expected for: %#v", value)
}
}
}
checkQuoting(false, "abcd")
checkQuoting(false, "v1.0")
checkQuoting(true, "/foobar")
checkQuoting(true, "x y")
checkQuoting(true, "x,y")
checkQuoting(false, errors.New("invalid"))
checkQuoting(true, errors.New("invalid argument"))
}
package auth
import (
"encoding/base64"
"net/http"
"testing"
)
func TestAuthBasic(t *testing.T) {
secrets := HtpasswdFileProvider("test.htpasswd")
a := &BasicAuth{Realm: "example.com", Secrets: secrets}
r := &http.Request{}
r.Method = "GET"
if a.CheckAuth(r) != "" {
t.Fatal("CheckAuth passed on empty headers")
}
r.Header = http.Header(make(map[string][]string))
r.Header.Set("Authorization", "Digest blabla ololo")
if a.CheckAuth(r) != "" {
t.Fatal("CheckAuth passed on bad headers")
}
r.Header.Set("Authorization", "Basic !@#")
if a.CheckAuth(r) != "" {
t.Fatal("CheckAuth passed on bad base64 data")
}
data := [][]string{
{"test", "hello"},
{"test2", "hello2"},
}
for _, tc := range data {
auth := base64.StdEncoding.EncodeToString([]byte(tc[0] + ":" + tc[1]))
r.Header.Set("Authorization", "Basic "+auth)
if a.CheckAuth(r) != tc[0] {
t.Fatalf("CheckAuth failed for user '%s'", tc[0])
}
}
}
package auth
import (
"net/http"
"net/url"
"testing"
"time"
)
func TestAuthDigest(t *testing.T) {
secrets := HtdigestFileProvider("test.htdigest")
da := &DigestAuth{Opaque: "U7H+ier3Ae8Skd/g",
Realm: "example.com",
Secrets: secrets,
clients: map[string]*digest_client{}}
r := &http.Request{}
r.Method = "GET"
if u, _ := da.CheckAuth(r); u != "" {
t.Fatal("non-empty auth for empty request header")
}
r.Header = http.Header(make(map[string][]string))
r.Header.Set("Authorization", "Digest blabla")
if u, _ := da.CheckAuth(r); u != "" {
t.Fatal("non-empty auth for bad request header")
}
r.Header.Set("Authorization", `Digest username="test", realm="example.com", nonce="Vb9BP/h81n3GpTTB", uri="/t2", cnonce="NjE4MTM2", nc=00000001, qop="auth", response="ffc357c4eba74773c8687e0bc724c9a3", opaque="U7H+ier3Ae8Skd/g", algorithm="MD5"`)
if u, _ := da.CheckAuth(r); u != "" {
t.Fatal("non-empty auth for unknown client")
}
r.URL, _ = url.Parse("/t2")
da.clients["Vb9BP/h81n3GpTTB"] = &digest_client{nc: 0, last_seen: time.Now().UnixNano()}
if u, _ := da.CheckAuth(r); u != "test" {
t.Fatal("empty auth for legitimate client")
}
if u, _ := da.CheckAuth(r); u != "" {
t.Fatal("non-empty auth for outdated nc")
}
r.URL, _ = url.Parse("/")
da.clients["Vb9BP/h81n3GpTTB"] = &digest_client{nc: 0, last_seen: time.Now().UnixNano()}
if u, _ := da.CheckAuth(r); u != "" {
t.Fatal("non-empty auth for bad request path")
}
r.URL, _ = url.Parse("/t3")
da.clients["Vb9BP/h81n3GpTTB"] = &digest_client{nc: 0, last_seen: time.Now().UnixNano()}
if u, _ := da.CheckAuth(r); u != "" {
t.Fatal("non-empty auth for bad request path")
}
da.clients["+RbVXSbIoa1SaJk1"] = &digest_client{nc: 0, last_seen: time.Now().UnixNano()}
r.Header.Set("Authorization", `Digest username="test", realm="example.com", nonce="+RbVXSbIoa1SaJk1", uri="/", cnonce="NjE4NDkw", nc=00000001, qop="auth", response="c08918024d7faaabd5424654c4e3ad1c", opaque="U7H+ier3Ae8Skd/g", algorithm="MD5"`)
if u, _ := da.CheckAuth(r); u != "test" {
t.Fatal("empty auth for valid request in subpath")
}
}
package auth
import "testing"
func Test_MD5Crypt(t *testing.T) {
test_cases := [][]string{
{"apache", "$apr1$J.w5a/..$IW9y6DR0oO/ADuhlMF5/X1"},
{"pass", "$1$YeNsbWdH$wvOF8JdqsoiLix754LTW90"},
}
for _, tc := range test_cases {
e := NewMD5Entry(tc[1])
result := MD5Crypt([]byte(tc[0]), e.Salt, e.Magic)
if string(result) != tc[1] {
t.Fatalf("MD5Crypt returned '%s' instead of '%s'", string(result), tc[1])
}
t.Logf("MD5Crypt: '%s' (%s%s$) -> %s", tc[0], e.Magic, e.Salt, result)
}
}
package auth
import "testing"
func TestH(t *testing.T) {
const hello = "Hello, world!"
const hello_md5 = "6cd3556deb0da54bca060b4c39479839"
h := H(hello)
if h != hello_md5 {
t.Fatal("Incorrect digest for test string:", h, "instead of", hello_md5)
}
}
package auth
import (
"testing"
)
func TestHtdigestFile(t *testing.T) {
secrets := HtdigestFileProvider("test.htdigest")
digest := secrets("test", "example.com")
if digest != "aa78524fceb0e50fd8ca96dd818b8cf9" {
t.Fatal("Incorrect digest for test user:", digest)
}
digest = secrets("test", "example1.com")
if digest != "" {
t.Fatal("Got digest for user in non-existant realm:", digest)
}
digest = secrets("test1", "example.com")
if digest != "" {
t.Fatal("Got digest for non-existant user:", digest)
}
}
func TestHtpasswdFile(t *testing.T) {
secrets := HtpasswdFileProvider("test.htpasswd")
passwd := secrets("test", "blah")
if passwd != "{SHA}qvTGHdzF6KLavt4PO0gs2a6pQ00=" {
t.Fatal("Incorrect passwd for test user:", passwd)
}
passwd = secrets("test3", "blah")
if passwd != "" {
t.Fatal("Got passwd for non-existant user:", passwd)
}
}
// Copyright 2015 The appc Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package schema
import "testing"
func TestEmptyApp(t *testing.T) {
imj := `
{
"acKind": "ImageManifest",
"acVersion": "0.6.1",
"name": "example.com/test"
}
`
var im ImageManifest
err := im.UnmarshalJSON([]byte(imj))
if err != nil {
t.Errorf("unexpected error: %v", err)
}
// Marshal and Unmarshal to verify that no "app": {} is generated on
// Marshal and converted to empty struct on Unmarshal
buf, err := im.MarshalJSON()
if err != nil {
t.Errorf("unexpected error: %v", err)
}
err = im.UnmarshalJSON(buf)
if err != nil {
t.Errorf("unexpected error: %v", err)
}
}
func TestImageManifestMerge(t *testing.T) {
imj := `{"name": "example.com/test"}`
im := &ImageManifest{}
if im.UnmarshalJSON([]byte(imj)) == nil {
t.Fatal("Manifest JSON without acKind and acVersion unmarshalled successfully")
}
im = BlankImageManifest()
err := im.UnmarshalJSON([]byte(imj))
if err != nil {
t.Errorf("unexpected error: %v", err)
}
}
// Copyright 2015 The appc Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package schema
import (
"testing"
"github.com/appc/spec/schema/types"
)
func TestPodManifestMerge(t *testing.T) {
pmj := `{}`
pm := &PodManifest{}
if pm.UnmarshalJSON([]byte(pmj)) == nil {
t.Fatal("Manifest JSON without acKind and acVersion unmarshalled successfully")
}
pm = BlankPodManifest()
err := pm.UnmarshalJSON([]byte(pmj))
if err != nil {
t.Errorf("unexpected error: %v", err)
}
}
func TestAppList(t *testing.T) {
ri := RuntimeImage{
ID: *types.NewHashSHA512([]byte{}),
}
al := AppList{
RuntimeApp{
Name: "foo",
Image: ri,
},
RuntimeApp{
Name: "bar",
Image: ri,
},
}
if _, err := al.MarshalJSON(); err != nil {
t.Errorf("want err=nil, got %v", err)
}
dal := AppList{
RuntimeApp{
Name: "foo",
Image: ri,
},
RuntimeApp{
Name: "bar",
Image: ri,
},
RuntimeApp{
Name: "foo",
Image: ri,
},
}
if _, err := dal.MarshalJSON(); err == nil {
t.Errorf("want err, got nil")
}
}
// Copyright 2015 The appc Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package types
import (
"encoding/json"
"reflect"
"testing"
)
var (
goodIdentifiers = []string{
"asdf",
"foo-bar-baz",
"zab_rab_oof",
"database",
"my~database",
"example.com/database",
"example.com/~bob/database",
"example.com/ourapp-1.0.0",
"sub-domain.example.com/org/product/release-1.0.0",
"sub-domain.example.com/org/product/~alice/release-1.0.0",
}
badIdentifiers = []string{
"",
"BAR",
"foo#",
"EXAMPLE.com",
"foo.com/BAR",
"/app",
"app/",
"-app",
"app-",
".app",
"app.",
"_app",
"app_",
"~app",
"app~",
}
)
func TestNewACIdentifier(t *testing.T) {
for i, in := range goodIdentifiers {
l, err := NewACIdentifier(in)
if err != nil {
t.Errorf("#%d: got err=%v, want nil", i, err)
}
if l == nil {
t.Errorf("#%d: got l=nil, want non-nil", i)
}
}
}
func TestNewACIdentifierBad(t *testing.T) {
for i, in := range badIdentifiers {
l, err := NewACIdentifier(in)
if l != nil {
t.Errorf("#%d: got l=%v, want nil", i, l)
}
if err == nil {
t.Errorf("#%d: got err=nil, want non-nil", i)
}
}
}
func TestMustACIdentifier(t *testing.T) {
for i, in := range goodIdentifiers {
l := MustACIdentifier(in)
if l == nil {
t.Errorf("#%d: got l=nil, want non-nil", i)
}
}
}
func expectPanicMustACIdentifier(i int, in string, t *testing.T) {
defer func() {
recover()
}()
_ = MustACIdentifier(in)
t.Errorf("#%d: panic expected", i)
}
func TestMustACIdentifierBad(t *testing.T) {
for i, in := range badIdentifiers {
expectPanicMustACIdentifier(i, in, t)
}
}
func TestSanitizeACIdentifier(t *testing.T) {
tests := map[string]string{
"foo#": "foo",
"FOO": "foo",
"EXAMPLE.com": "example.com",
"foo.com/BAR": "foo.com/bar",
"/app": "app",
"app/": "app",
"-app": "app",
"app-": "app",
".app": "app",
"app.": "app",
"_app": "app",
"app_": "app",
"~app": "app",
"app~": "app",
"app///": "app",
"-/.app..": "app",
"-/app.name-test/-/": "app.name-test",
"sub-domain.example.com/org/product/~alice/release-1.0.0": "sub-domain.example.com/org/product/~alice/release-1.0.0",
}
for in, ex := range tests {
o, err := SanitizeACIdentifier(in)
if err != nil {
t.Errorf("got err=%v, want nil", err)
}
if o != ex {
t.Errorf("got l=%s, want %s", o, ex)
}
}
}
func TestACIdentifierSetGood(t *testing.T) {
tests := map[string]ACIdentifier{
"blargh": ACIdentifier("blargh"),
"example-ourapp-1-0-0": ACIdentifier("example-ourapp-1-0-0"),
}
for in, w := range tests {
// Ensure an empty name is set appropriately
var a ACIdentifier
err := a.Set(in)
if err != nil {
t.Errorf("%v: got err=%v, want nil", in, err)
continue
}
if !reflect.DeepEqual(a, w) {
t.Errorf("%v: a=%v, want %v", in, a, w)
}
// Ensure an existing name is overwritten
var b ACIdentifier = ACIdentifier("orig")
err = b.Set(in)
if err != nil {
t.Errorf("%v: got err=%v, want nil", in, err)
continue
}
if !reflect.DeepEqual(b, w) {
t.Errorf("%v: b=%v, want %v", in, b, w)
}
}
}
func TestACIdentifierSetBad(t *testing.T) {
for i, in := range badIdentifiers {
// Ensure an empty name stays empty
var a ACIdentifier
err := a.Set(in)
if err == nil {
t.Errorf("#%d: err=%v, want nil", i, err)
continue
}
if w := ACIdentifier(""); !reflect.DeepEqual(a, w) {
t.Errorf("%d: a=%v, want %v", i, a, w)
}
// Ensure an existing name is not overwritten
var b ACIdentifier = ACIdentifier("orig")
err = b.Set(in)
if err == nil {
t.Errorf("#%d: err=%v, want nil", i, err)
continue
}
if w := ACIdentifier("orig"); !reflect.DeepEqual(b, w) {
t.Errorf("%d: b=%v, want %v", i, b, w)
}
}
}
func TestSanitizeACIdentifierBad(t *testing.T) {
tests := []string{
"__",
"..",
"//",
"",
".//-"}
for i, in := range tests {
l, err := SanitizeACIdentifier(in)
if l != "" {
t.Errorf("#%d: got l=%v, want nil", i, l)
}
if err == nil {
t.Errorf("#%d: got err=nil, want non-nil", i)
}
}
}
func TestACIdentifierUnmarshalBad(t *testing.T) {
tests := []string{
"",
"garbage",
`""`,
`"EXAMPLE"`,
`"example.com/app#1"`,
`"~example.com/app1"`,
}
for i, in := range tests {
var a, b ACIdentifier
err := a.UnmarshalJSON([]byte(in))
if err == nil {
t.Errorf("#%d: err=nil, want non-nil", i)
} else if !reflect.DeepEqual(a, b) {
t.Errorf("#%d: a=%v, want empty", i, a)
}
}
}
func TestACIdentifierUnmarshalGood(t *testing.T) {
tests := map[string]ACIdentifier{
`"example"`: ACIdentifier("example"),
`"foo-bar"`: ACIdentifier("foo-bar"),
}
for in, w := range tests {
var a ACIdentifier
err := json.Unmarshal([]byte(in), &a)
if err != nil {
t.Errorf("%v: err=%v, want nil", in, err)
} else if !reflect.DeepEqual(a, w) {
t.Errorf("%v: a=%v, want %v", in, a, w)
}
}
}
func TestACIdentifierMarshalBad(t *testing.T) {
tests := map[string]error{
"Foo": ErrInvalidCharInACIdentifier,
"foo#": ErrInvalidCharInACIdentifier,
"-foo": ErrInvalidEdgeInACIdentifier,
"example-": ErrInvalidEdgeInACIdentifier,
"": ErrEmptyACIdentifier,
}
for in, werr := range tests {
a := ACIdentifier(in)
b, gerr := json.Marshal(a)
if b != nil {
t.Errorf("ACIdentifier(%q): want b=nil, got %v", in, b)
}
if jerr, ok := gerr.(*json.MarshalerError); !ok {
t.Errorf("expected JSONMarshalerError")
} else {
if e := jerr.Err; e != werr {
t.Errorf("err=%#v, want %#v", e, werr)
}
}
}
}
func TestACIdentifierMarshalGood(t *testing.T) {
for i, in := range goodIdentifiers {
a := ACIdentifier(in)
b, err := json.Marshal(a)
if !reflect.DeepEqual(b, []byte(`"`+in+`"`)) {
t.Errorf("#%d: marshalled=%v, want %v", i, b, []byte(in))
}
if err != nil {
t.Errorf("#%d: err=%v, want nil", i, err)
}
}
}
// Copyright 2015 The appc Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package types
import (
"encoding/json"
"reflect"
"testing"
)
func TestACKindMarshalBad(t *testing.T) {
tests := map[string]error{
"Foo": ACKindError("bad ACKind: Foo"),
"ApplicationManifest": ACKindError("bad ACKind: ApplicationManifest"),
"": ErrNoACKind,
}
for in, werr := range tests {
a := ACKind(in)
b, gerr := json.Marshal(a)
if b != nil {
t.Errorf("ACKind(%q): want b=nil, got %v", in, b)
}
if jerr, ok := gerr.(*json.MarshalerError); !ok {
t.Errorf("expected JSONMarshalerError")
} else {
if e := jerr.Err; e != werr {
t.Errorf("err=%#v, want %#v", e, werr)
}
}
}
}
func TestACKindMarshalGood(t *testing.T) {
for i, in := range []string{
"ImageManifest",
"PodManifest",
} {
a := ACKind(in)
b, err := json.Marshal(a)
if !reflect.DeepEqual(b, []byte(`"`+in+`"`)) {
t.Errorf("#%d: marshalled=%v, want %v", i, b, []byte(in))
}
if err != nil {
t.Errorf("#%d: err=%v, want nil", i, err)
}
}
}
func TestACKindUnmarshalBad(t *testing.T) {
tests := []string{
"ImageManifest", // Not a valid JSON-encoded string
`"garbage"`,
`"AppManifest"`,
`""`,
}
for i, in := range tests {
var a, b ACKind
err := a.UnmarshalJSON([]byte(in))
if err == nil {
t.Errorf("#%d: err=nil, want non-nil", i)
} else if !reflect.DeepEqual(a, b) {
t.Errorf("#%d: a=%v, want empty", i, a)
}
}
}
func TestACKindUnmarshalGood(t *testing.T) {
tests := map[string]ACKind{
`"PodManifest"`: ACKind("PodManifest"),
`"ImageManifest"`: ACKind("ImageManifest"),
}
for in, w := range tests {
var a ACKind
err := json.Unmarshal([]byte(in), &a)
if err != nil {
t.Errorf("%v: err=%v, want nil", in, err)
} else if !reflect.DeepEqual(a, w) {
t.Errorf("%v: a=%v, want %v", in, a, w)
}
}
}
// Copyright 2015 The appc Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package types
import (
"encoding/json"
"reflect"
"testing"
)
var (
goodNames = []string{
"asdf",
"foo-bar-baz",
"database",
}
badNames = []string{
"",
"foo#",
"example.com",
"EXAMPLE.com",
"example/database",
"example/database-1.0.0",
"foo.com/BAR",
"example.com/app_1",
"/app",
"app/",
"-app",
"app-",
".app",
"app.",
}
)
func TestNewACName(t *testing.T) {
for i, in := range goodNames {
l, err := NewACName(in)
if err != nil {
t.Errorf("#%d: got err=%v, want nil", i, err)
}
if l == nil {
t.Errorf("#%d: got l=nil, want non-nil", i)
}
}
}
func TestNewACNameBad(t *testing.T) {
for i, in := range badNames {
l, err := NewACName(in)
if l != nil {
t.Errorf("#%d: got l=%v, want nil", i, l)
}
if err == nil {
t.Errorf("#%d: got err=nil, want non-nil", i)
}
}
}
func TestMustACName(t *testing.T) {
for i, in := range goodNames {
l := MustACName(in)
if l == nil {
t.Errorf("#%d: got l=nil, want non-nil", i)
}
}
}
func expectPanicMustACName(i int, in string, t *testing.T) {
defer func() {
recover()
}()
_ = MustACName(in)
t.Errorf("#%d: panic expected", i)
}
func TestMustACNameBad(t *testing.T) {
for i, in := range badNames {
expectPanicMustACName(i, in, t)
}
}
func TestSanitizeACName(t *testing.T) {
tests := map[string]string{
"foo#": "foo",
"EXAMPLE.com": "example-com",
"foo.com/BAR": "foo-com-bar",
"example.com/app_1": "example-com-app-1",
"/app": "app",
"app/": "app",
"-app": "app",
"app-": "app",
".app": "app",
"app.": "app",
"app///": "app",
"-/.app..": "app",
"-/app.name-test/-/": "app-name-test",
"sub-domain.example.com/org/product/release-1.0.0": "sub-domain-example-com-org-product-release-1-0-0",
}
for in, ex := range tests {
o, err := SanitizeACName(in)
if err != nil {
t.Errorf("got err=%v, want nil", err)
}
if o != ex {
t.Errorf("got l=%s, want %s", o, ex)
}
}
}
func TestACNameSetGood(t *testing.T) {
tests := map[string]ACName{
"blargh": ACName("blargh"),
"example-ourapp-1-0-0": ACName("example-ourapp-1-0-0"),
}
for in, w := range tests {
// Ensure an empty name is set appropriately
var a ACName
err := a.Set(in)
if err != nil {
t.Errorf("%v: got err=%v, want nil", in, err)
continue
}
if !reflect.DeepEqual(a, w) {
t.Errorf("%v: a=%v, want %v", in, a, w)
}
// Ensure an existing name is overwritten
var b ACName = ACName("orig")
err = b.Set(in)
if err != nil {
t.Errorf("%v: got err=%v, want nil", in, err)
continue
}
if !reflect.DeepEqual(b, w) {
t.Errorf("%v: b=%v, want %v", in, b, w)
}
}
}
func TestACNameSetBad(t *testing.T) {
for i, in := range badNames {
// Ensure an empty name stays empty
var a ACName
err := a.Set(in)
if err == nil {
t.Errorf("#%d: err=%v, want nil", i, err)
continue
}
if w := ACName(""); !reflect.DeepEqual(a, w) {
t.Errorf("%d: a=%v, want %v", i, a, w)
}
// Ensure an existing name is not overwritten
var b ACName = ACName("orig")
err = b.Set(in)
if err == nil {
t.Errorf("#%d: err=%v, want nil", i, err)
continue
}
if w := ACName("orig"); !reflect.DeepEqual(b, w) {
t.Errorf("%d: b=%v, want %v", i, b, w)
}
}
}
func TestSanitizeACNameBad(t *testing.T) {
tests := []string{
"__",
"..",
"//",
"",
".//-"}
for i, in := range tests {
l, err := SanitizeACName(in)
if l != "" {
t.Errorf("#%d: got l=%v, want nil", i, l)
}
if err == nil {
t.Errorf("#%d: got err=nil, want non-nil", i)
}
}
}
func TestACNameUnmarshalBad(t *testing.T) {
tests := []string{
"",
"garbage",
`""`,
`"EXAMPLE"`,
`"example.com/app_1"`,
}
for i, in := range tests {
var a, b ACName
err := a.UnmarshalJSON([]byte(in))
if err == nil {
t.Errorf("#%d: err=nil, want non-nil", i)
} else if !reflect.DeepEqual(a, b) {
t.Errorf("#%d: a=%v, want empty", i, a)
}
}
}
func TestACNameUnmarshalGood(t *testing.T) {
tests := map[string]ACName{
`"example"`: ACName("example"),
`"foo-bar"`: ACName("foo-bar"),
}
for in, w := range tests {
var a ACName
err := json.Unmarshal([]byte(in), &a)
if err != nil {
t.Errorf("%v: err=%v, want nil", in, err)
} else if !reflect.DeepEqual(a, w) {
t.Errorf("%v: a=%v, want %v", in, a, w)
}
}
}
func TestACNameMarshalBad(t *testing.T) {
tests := map[string]error{
"Foo": ErrInvalidCharInACName,
"foo#": ErrInvalidCharInACName,
"-foo": ErrInvalidEdgeInACName,
"example-": ErrInvalidEdgeInACName,
"": ErrEmptyACName,
}
for in, werr := range tests {
a := ACName(in)
b, gerr := json.Marshal(a)
if b != nil {
t.Errorf("ACName(%q): want b=nil, got %v", in, b)
}
if jerr, ok := gerr.(*json.MarshalerError); !ok {
t.Errorf("expected JSONMarshalerError")
} else {
if e := jerr.Err; e != werr {
t.Errorf("err=%#v, want %#v", e, werr)
}
}
}
}
func TestACNameMarshalGood(t *testing.T) {
for i, in := range goodNames {
a := ACName(in)
b, err := json.Marshal(a)
if !reflect.DeepEqual(b, []byte(`"`+in+`"`)) {
t.Errorf("#%d: marshalled=%v, want %v", i, b, []byte(in))
}
if err != nil {
t.Errorf("#%d: err=%v, want nil", i, err)
}
}
}
// Copyright 2015 The appc Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package types
import (
"reflect"
"testing"
)
func makeAnno(n, v string) Annotation {
name, err := NewACIdentifier(n)
if err != nil {
panic(err)
}
return Annotation{
Name: *name,
Value: v,
}
}
func TestAnnotationsAssertValid(t *testing.T) {
tests := []struct {
in []Annotation
werr bool
}{
// duplicate names should fail
{
[]Annotation{
makeAnno("foo", "bar"),
makeAnno("foo", "baz"),
},
true,
},
// bad created should fail
{
[]Annotation{
makeAnno("created", "garbage"),
},
true,
},
// bad homepage should fail
{
[]Annotation{
makeAnno("homepage", "not-A$@#URL"),
},
true,
},
// bad documentation should fail
{
[]Annotation{
makeAnno("documentation", "ftp://isnotallowed.com"),
},
true,
},
// good cases
{
[]Annotation{
makeAnno("created", "2004-05-14T23:11:14+00:00"),
makeAnno("documentation", "http://example.com/docs"),
},
false,
},
{
[]Annotation{
makeAnno("foo", "bar"),
makeAnno("homepage", "https://homepage.com"),
},
false,
},
// empty is OK
{
[]Annotation{},
false,
},
}
for i, tt := range tests {
a := Annotations(tt.in)
err := a.assertValid()
if gerr := (err != nil); gerr != tt.werr {
t.Errorf("#%d: gerr=%t, want %t (err=%v)", i, gerr, tt.werr, err)
}
}
}
func TestAnnotationsMarshal(t *testing.T) {
for i, tt := range []struct {
in []Annotation
wb []byte
werr bool
}{
{
[]Annotation{
makeAnno("foo", "bar"),
makeAnno("foo", "baz"),
makeAnno("website", "http://example.com/anno"),
},
nil,
true,
},
{
[]Annotation{
makeAnno("a", "b"),
},
[]byte(`[{"name":"a","value":"b"}]`),
false,
},
{
[]Annotation{
makeAnno("foo", "bar"),
makeAnno("website", "http://example.com/anno"),
},
[]byte(`[{"name":"foo","value":"bar"},{"name":"website","value":"http://example.com/anno"}]`),
false,
},
} {
a := Annotations(tt.in)
b, err := a.MarshalJSON()
if !reflect.DeepEqual(b, tt.wb) {
t.Errorf("#%d: b=%s, want %s", i, b, tt.wb)
}
gerr := err != nil
if gerr != tt.werr {
t.Errorf("#%d: gerr=%t, want %t (err=%v)", i, gerr, tt.werr, err)
}
}
}
func TestAnnotationsUnmarshal(t *testing.T) {
tests := []struct {
in string
wann *Annotations
werr bool
}{
{
`garbage`,
&Annotations{},
true,
},
{
`[{"name":"a","value":"b"},{"name":"a","value":"b"}]`,
&Annotations{},
true,
},
{
`[{"name":"a","value":"b"}]`,
&Annotations{
makeAnno("a", "b"),
},
false,
},
}
for i, tt := range tests {
a := &Annotations{}
err := a.UnmarshalJSON([]byte(tt.in))
gerr := err != nil
if gerr != tt.werr {
t.Errorf("#%d: gerr=%t, want %t (err=%v)", i, gerr, tt.werr, err)
}
if !reflect.DeepEqual(a, tt.wann) {
t.Errorf("#%d: ann=%#v, want %#v", i, a, tt.wann)
}
}
}
func TestAnnotationsGet(t *testing.T) {
for i, tt := range []struct {
in string
wval string
wok bool
}{
{"foo", "bar", true},
{"website", "http://example.com/anno", true},
{"baz", "", false},
{"wuuf", "", false},
} {
a := Annotations{
makeAnno("foo", "bar"),
makeAnno("website", "http://example.com/anno"),
}
gval, gok := a.Get(tt.in)
if gval != tt.wval {
t.Errorf("#%d: val=%v, want %v", i, gval, tt.wval)
}
if gok != tt.wok {
t.Errorf("#%d: ok=%t, want %t", i, gok, tt.wok)
}
}
}
func TestAnnotationsSet(t *testing.T) {
a := Annotations{}
a.Set("foo", "bar")
w := Annotations{
Annotation{ACIdentifier("foo"), "bar"},
}
if !reflect.DeepEqual(w, a) {
t.Fatalf("want %v, got %v", w, a)
}
a.Set("dog", "woof")
w = Annotations{
Annotation{ACIdentifier("foo"), "bar"},
Annotation{ACIdentifier("dog"), "woof"},
}
if !reflect.DeepEqual(w, a) {
t.Fatalf("want %v, got %v", w, a)
}
a.Set("foo", "baz")
a.Set("example.com/foo_bar", "quux")
w = Annotations{
Annotation{ACIdentifier("foo"), "baz"},
Annotation{ACIdentifier("dog"), "woof"},
Annotation{ACIdentifier("example.com/foo_bar"), "quux"},
}
if !reflect.DeepEqual(w, a) {
t.Fatalf("want %v, got %v", w, a)
}
}
// Copyright 2015 The appc Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package types
import (
"reflect"
"testing"
)
func TestAppValid(t *testing.T) {
tests := []App{
App{
Exec: []string{"/bin/httpd"},
User: "0",
Group: "0",
WorkingDirectory: "/tmp",
},
App{
Exec: []string{"/app"},
User: "0",
Group: "0",
EventHandlers: []EventHandler{
{Name: "pre-start"},
{Name: "post-stop"},
},
Environment: []EnvironmentVariable{
{Name: "DEBUG", Value: "true"},
},
WorkingDirectory: "/tmp",
},
App{
Exec: []string{"/app", "arg1", "arg2"},
User: "0",
Group: "0",
WorkingDirectory: "/tmp",
},
}
for i, tt := range tests {
if err := tt.assertValid(); err != nil {
t.Errorf("#%d: err == %v, want nil", i, err)
}
}
}
func TestAppExecInvalid(t *testing.T) {
tests := []App{
App{
Exec: nil,
},
App{
Exec: []string{},
User: "0",
Group: "0",
},
App{
Exec: []string{"app"},
User: "0",
Group: "0",
},
App{
Exec: []string{"bin/app", "arg1"},
User: "0",
Group: "0",
},
}
for i, tt := range tests {
if err := tt.assertValid(); err == nil {
t.Errorf("#%d: err == nil, want non-nil", i)
}
}
}
func TestAppEventHandlersInvalid(t *testing.T) {
tests := []App{
App{
Exec: []string{"/bin/httpd"},
User: "0",
Group: "0",
EventHandlers: []EventHandler{
EventHandler{
Name: "pre-start",
},
EventHandler{
Name: "pre-start",
},
},
},
App{
Exec: []string{"/bin/httpd"},
User: "0",
Group: "0",
EventHandlers: []EventHandler{
EventHandler{
Name: "post-stop",
},
EventHandler{
Name: "pre-start",
},
EventHandler{
Name: "post-stop",
},
},
},
}
for i, tt := range tests {
if err := tt.assertValid(); err == nil {
t.Errorf("#%d: err == nil, want non-nil", i)
}
}
}
func TestUserGroupInvalid(t *testing.T) {
tests := []App{
App{
Exec: []string{"/app"},
},
App{
Exec: []string{"/app"},
User: "0",
},
App{
Exec: []string{"app"},
Group: "0",
},
}
for i, tt := range tests {
if err := tt.assertValid(); err == nil {
t.Errorf("#%d: err == nil, want non-nil", i)
}
}
}
func TestAppWorkingDirectoryInvalid(t *testing.T) {
tests := []App{
App{
Exec: []string{"/app"},
User: "foo",
Group: "bar",
WorkingDirectory: "stuff",
},
App{
Exec: []string{"/app"},
User: "foo",
Group: "bar",
WorkingDirectory: "../home/fred",
},
}
for i, tt := range tests {
if err := tt.assertValid(); err == nil {
t.Errorf("#%d: err == nil, want non-nil", i)
}
}
}
func TestAppEnvironmentInvalid(t *testing.T) {
tests := []App{
App{
Exec: []string{"/app"},
User: "foo",
Group: "bar",
Environment: Environment{
EnvironmentVariable{"0DEBUG", "true"},
},
},
}
for i, tt := range tests {
if err := tt.assertValid(); err == nil {
t.Errorf("#%d: err == nil, want non-nil", i)
}
}
}
func TestAppUnmarshal(t *testing.T) {
tests := []struct {
in string
wann *App
werr bool
}{
{
`garbage`,
&App{},
true,
},
{
`{"Exec":"not a list"}`,
&App{},
true,
},
{
`{"Exec":["notfullyqualified"]}`,
&App{},
true,
},
{
`{"Exec":["/a"],"User":"0","Group":"0"}`,
&App{
Exec: Exec{
"/a",
},
User: "0",
Group: "0",
Environment: make(Environment, 0),
},
false,
},
}
for i, tt := range tests {
a := &App{}
err := a.UnmarshalJSON([]byte(tt.in))
gerr := err != nil
if gerr != tt.werr {
t.Errorf("#%d: gerr=%t, want %t (err=%v)", i, gerr, tt.werr, err)
}
if !reflect.DeepEqual(a, tt.wann) {
t.Errorf("#%d: ann=%#v, want %#v", i, a, tt.wann)
}
}
}
// Copyright 2015 The appc Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package types
import (
"encoding/json"
"testing"
"time"
)
var (
pst = time.FixedZone("Pacific", -8*60*60)
)
func TestUnmarshalDate(t *testing.T) {
tests := []struct {
in string
wt time.Time
}{
{
`"2004-05-14T23:11:14+00:00"`,
time.Date(2004, 05, 14, 23, 11, 14, 0, time.UTC),
},
{
`"2001-02-03T04:05:06Z"`,
time.Date(2001, 02, 03, 04, 05, 06, 0, time.UTC),
},
{
`"2014-11-14T17:36:54-08:00"`,
time.Date(2014, 11, 14, 17, 36, 54, 0, pst),
},
{
`"2004-05-14T23:11:14+00:00"`,
time.Date(2004, 05, 14, 23, 11, 14, 0, time.UTC),
},
}
for i, tt := range tests {
var d Date
if err := json.Unmarshal([]byte(tt.in), &d); err != nil {
t.Errorf("#%d: got err=%v, want nil", i, err)
}
if gt := time.Time(d); !gt.Equal(tt.wt) {
t.Errorf("#%d: got time=%v, want %v", i, gt, tt.wt)
}
}
}
func TestUnmarshalDateBad(t *testing.T) {
tests := []string{
`not a json string`,
`2014-11-14T17:36:54-08:00`,
`"garbage"`,
`"1416015188"`,
`"Fri Nov 14 17:53:02 PST 2014"`,
`"2014-11-1417:36:54"`,
}
for i, tt := range tests {
var d Date
if err := json.Unmarshal([]byte(tt), &d); err == nil {
t.Errorf("#%d: unexpected nil err", i)
}
}
}
// Copyright 2015 The appc Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package types
import "testing"
func TestEmptyHash(t *testing.T) {
dj := `{"imageName": "example.com/reduce-worker-base"}`
var d Dependency
err := d.UnmarshalJSON([]byte(dj))
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
// Marshal to verify that marshalling works without validation errors
buf, err := d.MarshalJSON()
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
// Unmarshal to verify that the generated json will not create wrong empty hash
err = d.UnmarshalJSON(buf)
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
}
// Copyright 2015 The appc Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package types
import (
"testing"
)
func TestEnvironmentAssertValid(t *testing.T) {
tests := []struct {
env Environment
werr bool
}{
// duplicate names should fail
{
Environment{
EnvironmentVariable{"DEBUG", "true"},
EnvironmentVariable{"DEBUG", "true"},
},
true,
},
// empty name should fail
{
Environment{
EnvironmentVariable{"", "value"},
},
true,
},
// name beginning with digit should fail
{
Environment{
EnvironmentVariable{"0DEBUG", "true"},
},
true,
},
// name with non [A-Za-z0-9_] should fail
{
Environment{
EnvironmentVariable{"VERBOSE-DEBUG", "true"},
},
true,
},
// accepted environment variable forms
{
Environment{
EnvironmentVariable{"DEBUG", "true"},
},
false,
},
{
Environment{
EnvironmentVariable{"_0_DEBUG_0_", "true"},
},
false,
},
}
for i, test := range tests {
env := Environment(test.env)
err := env.assertValid()
if gerr := (err != nil); gerr != test.werr {
t.Errorf("#%d: gerr=%t, want %t (err=%v)", i, gerr, test.werr, err)
}
}
}
// Copyright 2015 The appc Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package types
import "testing"
func TestExecValid(t *testing.T) {
tests := []Exec{
Exec{"/bin/httpd"},
Exec{"/app"},
Exec{"/app", "arg1", "arg2"},
}
for i, tt := range tests {
if err := tt.assertValid(); err != nil {
t.Errorf("#%d: err == %v, want nil", i, err)
}
}
}
func TestExecInvalid(t *testing.T) {
tests := []Exec{
Exec{},
Exec{"app"},
}
for i, tt := range tests {
if err := tt.assertValid(); err == nil {
t.Errorf("#%d: err == nil, want non-nil", i)
}
}
}
// Copyright 2015 The appc Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package types
import (
"encoding/json"
"testing"
)
func TestMarshalHash(t *testing.T) {
tests := []struct {
typ string
val string
wout string
}{
{
"sha512",
"abcdefghi",
`"sha512-abcdefghi"`,
},
{
"sha512",
"06c733b1838136838e6d2d3e8fa5aea4c7905e92",
`"sha512-06c733b1838136838e6d2d3e8fa5aea4c7905e92"`,
},
}
for i, tt := range tests {
h := Hash{
typ: tt.typ,
Val: tt.val,
}
b, err := json.Marshal(h)
if err != nil {
t.Errorf("#%d: unexpected err=%v", i, err)
}
if g := string(b); g != tt.wout {
t.Errorf("#%d: got string=%v, want %v", i, g, tt.wout)
}
}
}
func TestMarshalHashBad(t *testing.T) {
tests := []struct {
typ string
val string
}{
{
// empty value
"sha512",
"",
},
{
// bad type
"sha1",
"abcdef",
},
{
// empty type
"",
"abcdef",
},
{
// empty empty
"",
"",
},
}
for i, tt := range tests {
h := Hash{
typ: tt.typ,
Val: tt.val,
}
g, err := json.Marshal(h)
if err == nil {
t.Errorf("#%d: unexpected nil err", i)
}
if g != nil {
t.Errorf("#%d: unexpected non-nil bytes: %v", i, g)
}
}
}
// Copyright 2015 The appc Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package types
import (
"encoding/json"
"reflect"
"testing"
)
func TestIsolatorUnmarshal(t *testing.T) {
tests := []struct {
msg string
werr bool
}{
{
`{
"name": "os/linux/capabilities-retain-set",
"value": {"set": ["CAP_KILL"]}
}`,
false,
},
{
`{
"name": "os/linux/capabilities-retain-set",
"value": {"set": ["CAP_PONIES"]}
}`,
false,
},
{
`{
"name": "os/linux/capabilities-retain-set",
"value": {"set": []}
}`,
true,
},
{
`{
"name": "os/linux/capabilities-retain-set",
"value": {"set": "CAP_PONIES"}
}`,
true,
},
{
`{
"name": "resource/block-bandwidth",
"value": {"default": true, "limit": "1G"}
}`,
false,
},
{
`{
"name": "resource/block-bandwidth",
"value": {"default": false, "limit": "1G"}
}`,
true,
},
{
`{
"name": "resource/block-bandwidth",
"value": {"request": "30G", "limit": "1G"}
}`,
true,
},
{
`{
"name": "resource/block-iops",
"value": {"default": true, "limit": "1G"}
}`,
false,
},
{
`{
"name": "resource/block-iops",
"value": {"default": false, "limit": "1G"}
}`,
true,
},
{
`{
"name": "resource/block-iops",
"value": {"request": "30G", "limit": "1G"}
}`,
true,
},
{
`{
"name": "resource/cpu",
"value": {"request": "30m", "limit": "1m"}
}`,
false,
},
{
`{
"name": "resource/memory",
"value": {"request": "1G", "limit": "2Gi"}
}`,
false,
},
{
`{
"name": "resource/memory",
"value": {"default": true, "request": "1G", "limit": "2G"}
}`,
true,
},
{
`{
"name": "resource/network-bandwidth",
"value": {"default": true, "limit": "1G"}
}`,
false,
},
{
`{
"name": "resource/network-bandwidth",
"value": {"default": false, "limit": "1G"}
}`,
true,
},
{
`{
"name": "resource/network-bandwidth",
"value": {"request": "30G", "limit": "1G"}
}`,
true,
},
}
for i, tt := range tests {
var ii Isolator
err := ii.UnmarshalJSON([]byte(tt.msg))
if gerr := (err != nil); gerr != tt.werr {
t.Errorf("#%d: gerr=%t, want %t (err=%v)", i, gerr, tt.werr, err)
}
}
}
func TestIsolatorsGetByName(t *testing.T) {
ex := `
[
{
"name": "resource/cpu",
"value": {"request": "30m", "limit": "1m"}
},
{
"name": "resource/memory",
"value": {"request": "1G", "limit": "2Gi"}
},
{
"name": "os/linux/capabilities-retain-set",
"value": {"set": ["CAP_KILL"]}
},
{
"name": "os/linux/capabilities-remove-set",
"value": {"set": ["CAP_KILL"]}
}
]
`
tests := []struct {
name ACIdentifier
wlimit int64
wrequest int64
wset []LinuxCapability
}{
{"resource/cpu", 1, 30, nil},
{"resource/memory", 2147483648, 1000000000, nil},
{"os/linux/capabilities-retain-set", 0, 0, []LinuxCapability{"CAP_KILL"}},
{"os/linux/capabilities-remove-set", 0, 0, []LinuxCapability{"CAP_KILL"}},
}
var is Isolators
err := json.Unmarshal([]byte(ex), &is)
if err != nil {
panic(err)
}
if len(is) < 2 {
t.Fatalf("too few items %v", len(is))
}
for i, tt := range tests {
c := is.GetByName(tt.name)
if c == nil {
t.Fatalf("can't find item %v in %v items", tt.name, len(is))
}
switch v := c.Value().(type) {
case Resource:
var r Resource = v
glimit := r.Limit()
grequest := r.Request()
var vlimit, vrequest int64
if tt.name == "resource/cpu" {
vlimit, vrequest = glimit.MilliValue(), grequest.MilliValue()
} else {
vlimit, vrequest = glimit.Value(), grequest.Value()
}
if vlimit != tt.wlimit {
t.Errorf("#%d: glimit=%v, want %v", i, vlimit, tt.wlimit)
}
if vrequest != tt.wrequest {
t.Errorf("#%d: grequest=%v, want %v", i, vrequest, tt.wrequest)
}
case LinuxCapabilitiesSet:
var s LinuxCapabilitiesSet = v
if !reflect.DeepEqual(s.Set(), tt.wset) {
t.Errorf("#%d: gset=%v, want %v", i, s.Set(), tt.wset)
}
default:
panic("unexecpected type")
}
}
}
func TestIsolatorUnrecognized(t *testing.T) {
msg := `
[{
"name": "resource/network-bandwidth",
"value": {"default": true, "limit": "1G"}
},
{
"name": "resource/network-ponies",
"value": 0
}]`
ex := Isolators{
{Name: "resource/network-ponies"},
}
is := Isolators{}
if err := json.Unmarshal([]byte(msg), &is); err != nil {
t.Fatalf("failed to unmarshal isolators: %v", err)
}
u := is.Unrecognized()
if len(u) != len(ex) {
t.Errorf("unrecognized isolator list is wrong len: want %v, got %v", len(ex), len(u))
}
for i, e := range ex {
if e.Name != u[i].Name {
t.Errorf("unrecognized isolator list mismatch: want %v, got %v", e.Name, u[i].Name)
}
}
}
// Copyright 2015 The appc Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package types
import (
"encoding/json"
"strings"
"testing"
)
func TestLabels(t *testing.T) {
tests := []struct {
in string
errPrefix string
}{
{
`[{"name": "os", "value": "linux"}, {"name": "arch", "value": "amd64"}]`,
"",
},
{
`[{"name": "os", "value": "linux"}, {"name": "arch", "value": "aarch64"}]`,
"",
},
{
`[{"name": "os", "value": "linux"}, {"name": "arch", "value": "arm64"}]`,
`bad arch "arm64" for linux`,
},
{
`[{"name": "os", "value": "linux"}, {"name": "arch", "value": "aarch64_be"}]`,
"",
},
{
`[{"name": "os", "value": "linux"}, {"name": "arch", "value": "arm64_be"}]`,
`bad arch "arm64_be" for linux`,
},
{
`[{"name": "os", "value": "linux"}, {"name": "arch", "value": "arm"}]`,
`bad arch "arm" for linux`,
},
{
`[{"name": "os", "value": "linux"}, {"name": "arch", "value": "armv6l"}]`,
"",
},
{
`[{"name": "os", "value": "linux"}, {"name": "arch", "value": "armv7l"}]`,
"",
},
{
`[{"name": "os", "value": "linux"}, {"name": "arch", "value": "armv7b"}]`,
"",
},
{
`[{"name": "os", "value": "freebsd"}, {"name": "arch", "value": "amd64"}]`,
"",
},
{
`[{"name": "os", "value": "OS/360"}, {"name": "arch", "value": "S/360"}]`,
`bad os "OS/360"`,
},
{
`[{"name": "os", "value": "freebsd"}, {"name": "arch", "value": "armv7b"}]`,
`bad arch "armv7b" for freebsd`,
},
{
`[{"name": "name"}]`,
`invalid label name: "name"`,
},
{
`[{"name": "os", "value": "linux"}, {"name": "os", "value": "freebsd"}]`,
`duplicate labels of name "os"`,
},
{
`[{"name": "arch", "value": "amd64"}, {"name": "os", "value": "freebsd"}, {"name": "arch", "value": "x86_64"}]`,
`duplicate labels of name "arch"`,
},
{
`[]`,
"",
},
}
for i, tt := range tests {
var l Labels
if err := json.Unmarshal([]byte(tt.in), &l); err != nil {
if tt.errPrefix == "" {
t.Errorf("#%d: got err=%v, expected no error", i, err)
} else if !strings.HasPrefix(err.Error(), tt.errPrefix) {
t.Errorf("#%d: got err=%v, expected prefix %#v", i, err, tt.errPrefix)
}
} else {
t.Log(l)
if tt.errPrefix != "" {
t.Errorf("#%d: got no err, expected prefix %#v", i, tt.errPrefix)
}
}
}
}
// Copyright 2015 The appc Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package types
import (
"reflect"
"testing"
)
func TestMountPointFromString(t *testing.T) {
tests := []struct {
s string
mount MountPoint
}{
{
"foobar,path=/tmp",
MountPoint{
Name: "foobar",
Path: "/tmp",
ReadOnly: false,
},
},
{
"foobar,path=/tmp,readOnly=false",
MountPoint{
Name: "foobar",
Path: "/tmp",
ReadOnly: false,
},
},
{
"foobar,path=/tmp,readOnly=true",
MountPoint{
Name: "foobar",
Path: "/tmp",
ReadOnly: true,
},
},
}
for i, tt := range tests {
mount, err := MountPointFromString(tt.s)
if err != nil {
t.Errorf("#%d: got err=%v, want nil", i, err)
}
if !reflect.DeepEqual(*mount, tt.mount) {
t.Errorf("#%d: mount=%v, want %v", i, *mount, tt.mount)
}
}
}
func TestMountPointFromStringBad(t *testing.T) {
tests := []string{
"#foobar,path=/tmp",
"foobar,path=/tmp,readOnly=true,asdf=asdf",
"foobar,path=/tmp,readOnly=maybe",
"foobar,path=/tmp,readOnly=",
"foobar,path=",
"foobar",
"",
",path=/",
}
for i, in := range tests {
l, err := MountPointFromString(in)
if l != nil {
t.Errorf("#%d: got l=%v, want nil", i, l)
}
if err == nil {
t.Errorf("#%d: got err=nil, want non-nil", i)
}
}
}
// Copyright 2015 The appc Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package types
import (
"testing"
)
func TestGoodPort(t *testing.T) {
p := Port{
Port: 32456,
Count: 100,
}
if err := p.assertValid(); err != nil {
t.Errorf("good port assertion failed: %v", err)
}
}
func TestBadPort(t *testing.T) {
p := Port{
Port: 88888,
}
if p.assertValid() == nil {
t.Errorf("bad port asserted valid")
}
}
func TestBadRange(t *testing.T) {
p := Port{
Port: 32456,
Count: 45678,
}
if p.assertValid() == nil {
t.Errorf("bad port range asserted valid")
}
}
// Copyright 2015 The appc Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package types
import (
"encoding/json"
"reflect"
"testing"
"github.com/coreos/go-semver/semver"
)
func TestMarshalSemver(t *testing.T) {
tests := []struct {
sv SemVer
wd []byte
}{
{
SemVer(semver.Version{Major: 1}),
[]byte(`"1.0.0"`),
},
{
SemVer(semver.Version{Major: 3, Minor: 2, Patch: 1}),
[]byte(`"3.2.1"`),
},
{
SemVer(semver.Version{Major: 3, Minor: 2, Patch: 1, PreRelease: "foo"}),
[]byte(`"3.2.1-foo"`),
},
{
SemVer(semver.Version{Major: 1, Minor: 2, Patch: 3, PreRelease: "alpha", Metadata: "git"}),
[]byte(`"1.2.3-alpha+git"`),
},
}
for i, tt := range tests {
d, err := json.Marshal(tt.sv)
if !reflect.DeepEqual(d, tt.wd) {
t.Errorf("#%d: d=%v, want %v", i, string(d), string(tt.wd))
}
if err != nil {
t.Errorf("#%d: err=%v, want nil", i, err)
}
}
}
func TestUnmarshalSemver(t *testing.T) {
tests := []struct {
d []byte
wsv SemVer
werr bool
}{
{
[]byte(`"1.0.0"`),
SemVer(semver.Version{Major: 1}),
false,
},
{
[]byte(`"3.2.1"`),
SemVer(semver.Version{Major: 3, Minor: 2, Patch: 1}),
false,
},
{
[]byte(`"3.2.1-foo"`),
SemVer(semver.Version{Major: 3, Minor: 2, Patch: 1, PreRelease: "foo"}),
false,
},
{
[]byte(`"1.2.3-alpha+git"`),
SemVer(semver.Version{Major: 1, Minor: 2, Patch: 3, PreRelease: "alpha", Metadata: "git"}),
false,
},
{
[]byte(`"1"`),
SemVer{},
true,
},
{
[]byte(`"1.2.3.4"`),
SemVer{},
true,
},
{
[]byte(`1.2.3`),
SemVer{},
true,
},
{
[]byte(`"v1.2.3"`),
SemVer{},
true,
},
}
for i, tt := range tests {
var sv SemVer
err := json.Unmarshal(tt.d, &sv)
if !reflect.DeepEqual(sv, tt.wsv) {
t.Errorf("#%d: semver=%#v, want %#v", i, sv, tt.wsv)
}
if gerr := (err != nil); gerr != tt.werr {
t.Errorf("#%d: err==%v, want errstate %t", i, err, tt.werr)
}
}
}
// Copyright 2015 The appc Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package types
import (
"encoding/json"
"net/url"
"reflect"
"testing"
)
func mustParseURL(t *testing.T, s string) url.URL {
u, err := url.Parse(s)
if err != nil {
t.Fatalf("error parsing URL: %v", err)
}
return *u
}
func TestMarshalURL(t *testing.T) {
tests := []struct {
u url.URL
w string
}{
{
mustParseURL(t, "http://foo.com"),
`"http://foo.com"`,
},
{
mustParseURL(t, "http://foo.com/huh/what?is=this"),
`"http://foo.com/huh/what?is=this"`,
},
{
mustParseURL(t, "https://example.com/bar"),
`"https://example.com/bar"`,
},
}
for i, tt := range tests {
u := URL(tt.u)
b, err := json.Marshal(u)
if g := string(b); g != tt.w {
t.Errorf("#%d: got %q, want %q", i, g, tt.w)
}
if err != nil {
t.Errorf("#%d: err=%v, want nil", i, err)
}
}
}
func TestMarshalURLBad(t *testing.T) {
tests := []url.URL{
mustParseURL(t, "ftp://foo.com"),
mustParseURL(t, "unix:///hello"),
}
for i, tt := range tests {
u := URL(tt)
b, err := json.Marshal(u)
if b != nil {
t.Errorf("#%d: got %v, want nil", i, b)
}
if err == nil {
t.Errorf("#%d: got unexpected err=nil", i)
}
}
}
func TestUnmarshalURL(t *testing.T) {
tests := []struct {
in string
w URL
}{
{
`"http://foo.com"`,
URL(mustParseURL(t, "http://foo.com")),
},
{
`"http://yis.com/hello?goodbye=yes"`,
URL(mustParseURL(t, "http://yis.com/hello?goodbye=yes")),
},
{
`"https://ohai.net"`,
URL(mustParseURL(t, "https://ohai.net")),
},
}
for i, tt := range tests {
var g URL
err := json.Unmarshal([]byte(tt.in), &g)
if err != nil {
t.Errorf("#%d: want err=nil, got %v", i, err)
}
if !reflect.DeepEqual(g, tt.w) {
t.Errorf("#%d: got url=%v, want %v", i, g, tt.w)
}
}
}
func TestUnmarshalURLBad(t *testing.T) {
var empty = URL{}
tests := []string{
"badjson",
"http://google.com",
`"ftp://example.com"`,
`"unix://file.net"`,
`"not a url"`,
}
for i, tt := range tests {
var g URL
err := json.Unmarshal([]byte(tt), &g)
if err == nil {
t.Errorf("#%d: want err, got nil", i)
}
if !reflect.DeepEqual(g, empty) {
t.Errorf("#%d: got %v, want %v", i, g, empty)
}
}
}
// Copyright 2015 The appc Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package types
import "testing"
func TestNewUUID(t *testing.T) {
tests := []struct {
in string
ws string
}{
{
"6733C088-A507-4694-AABF-EDBE4FC5266F",
"6733c088-a507-4694-aabf-edbe4fc5266f",
},
{
"6733C088A5074694AABFEDBE4FC5266F",
"6733c088-a507-4694-aabf-edbe4fc5266f",
},
{
"0aaf0a79-1a39-4d59-abbf-1bebca8209d2",
"0aaf0a79-1a39-4d59-abbf-1bebca8209d2",
},
{
"0aaf0a791a394d59abbf1bebca8209d2",
"0aaf0a79-1a39-4d59-abbf-1bebca8209d2",
},
}
for i, tt := range tests {
gu, err := NewUUID(tt.in)
if err != nil {
t.Errorf("#%d: err=%v, want %v", i, err, nil)
}
if gs := gu.String(); gs != tt.ws {
t.Errorf("#%d: String()=%v, want %v", i, gs, tt.ws)
}
}
}
func TestNewUUIDBad(t *testing.T) {
tests := []string{
"asdf",
"0AAF0A79-1A39-4D59-ABBF-1BEBCA8209D2ABC",
"",
}
for i, tt := range tests {
g, err := NewUUID(tt)
if err == nil {
t.Errorf("#%d: err=nil, want non-nil", i)
}
if g != nil {
t.Errorf("#%d: err=%v, want %v", i, g, nil)
}
}
}
// Copyright 2015 The appc Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package types
import (
"reflect"
"testing"
)
func TestVolumeFromString(t *testing.T) {
trueVar := true
falseVar := false
tests := []struct {
s string
v Volume
}{
{
"foobar,kind=host,source=/tmp",
Volume{
Name: "foobar",
Kind: "host",
Source: "/tmp",
ReadOnly: nil,
},
},
{
"foobar,kind=host,source=/tmp,readOnly=false",
Volume{
Name: "foobar",
Kind: "host",
Source: "/tmp",
ReadOnly: &falseVar,
},
},
{
"foobar,kind=host,source=/tmp,readOnly=true",
Volume{
Name: "foobar",
Kind: "host",
Source: "/tmp",
ReadOnly: &trueVar,
},
},
{
"foobar,kind=empty",
Volume{
Name: "foobar",
Kind: "empty",
ReadOnly: nil,
},
},
{
"foobar,kind=empty,readOnly=true",
Volume{
Name: "foobar",
Kind: "empty",
ReadOnly: &trueVar,
},
},
}
for i, tt := range tests {
v, err := VolumeFromString(tt.s)
if err != nil {
t.Errorf("#%d: got err=%v, want nil", i, err)
}
if !reflect.DeepEqual(*v, tt.v) {
t.Errorf("#%d: v=%v, want %v", i, *v, tt.v)
}
}
}
func TestVolumeFromStringBad(t *testing.T) {
tests := []string{
"#foobar,kind=host,source=/tmp",
"foobar,kind=host,source=/tmp,readOnly=true,asdf=asdf",
"foobar,kind=empty,source=/tmp",
}
for i, in := range tests {
l, err := VolumeFromString(in)
if l != nil {
t.Errorf("#%d: got l=%v, want nil", i, l)
}
if err == nil {
t.Errorf("#%d: got err=nil, want non-nil", i)
}
}
}
package awsutil_test
import (
"bytes"
"fmt"
"io"
"io/ioutil"
"testing"
"github.com/aws/aws-sdk-go/aws/awsutil"
"github.com/stretchr/testify/assert"
)
func ExampleCopy() {
type Foo struct {
A int
B []*string
}
// Create the initial value
str1 := "hello"
str2 := "bye bye"
f1 := &Foo{A: 1, B: []*string{&str1, &str2}}
// Do the copy
var f2 Foo
awsutil.Copy(&f2, f1)
// Print the result
fmt.Println(awsutil.Prettify(f2))
// Output:
// {
// A: 1,
// B: ["hello","bye bye"]
// }
}
func TestCopy(t *testing.T) {
type Foo struct {
A int
B []*string
C map[string]*int
}
// Create the initial value
str1 := "hello"
str2 := "bye bye"
int1 := 1
int2 := 2
f1 := &Foo{
A: 1,
B: []*string{&str1, &str2},
C: map[string]*int{
"A": &int1,
"B": &int2,
},
}
// Do the copy
var f2 Foo
awsutil.Copy(&f2, f1)
// Values are equal
assert.Equal(t, f2.A, f1.A)
assert.Equal(t, f2.B, f1.B)
assert.Equal(t, f2.C, f1.C)
// But pointers are not!
str3 := "nothello"
int3 := 57
f2.A = 100
f2.B[0] = &str3
f2.C["B"] = &int3
assert.NotEqual(t, f2.A, f1.A)
assert.NotEqual(t, f2.B, f1.B)
assert.NotEqual(t, f2.C, f1.C)
}
func TestCopyIgnoreNilMembers(t *testing.T) {
type Foo struct {
A *string
B []string
C map[string]string
}
f := &Foo{}
assert.Nil(t, f.A)
assert.Nil(t, f.B)
assert.Nil(t, f.C)
var f2 Foo
awsutil.Copy(&f2, f)
assert.Nil(t, f2.A)
assert.Nil(t, f2.B)
assert.Nil(t, f2.C)
fcopy := awsutil.CopyOf(f)
f3 := fcopy.(*Foo)
assert.Nil(t, f3.A)
assert.Nil(t, f3.B)
assert.Nil(t, f3.C)
}
func TestCopyPrimitive(t *testing.T) {
str := "hello"
var s string
awsutil.Copy(&s, &str)
assert.Equal(t, "hello", s)
}
func TestCopyNil(t *testing.T) {
var s string
awsutil.Copy(&s, nil)
assert.Equal(t, "", s)
}
func TestCopyReader(t *testing.T) {
var buf io.Reader = bytes.NewReader([]byte("hello world"))
var r io.Reader
awsutil.Copy(&r, buf)
b, err := ioutil.ReadAll(r)
assert.NoError(t, err)
assert.Equal(t, []byte("hello world"), b)
// empty bytes because this is not a deep copy
b, err = ioutil.ReadAll(buf)
assert.NoError(t, err)
assert.Equal(t, []byte(""), b)
}
func TestCopyDifferentStructs(t *testing.T) {
type SrcFoo struct {
A int
B []*string
C map[string]*int
SrcUnique string
SameNameDiffType int
}
type DstFoo struct {
A int
B []*string
C map[string]*int
DstUnique int
SameNameDiffType string
}
// Create the initial value
str1 := "hello"
str2 := "bye bye"
int1 := 1
int2 := 2
f1 := &SrcFoo{
A: 1,
B: []*string{&str1, &str2},
C: map[string]*int{
"A": &int1,
"B": &int2,
},
SrcUnique: "unique",
SameNameDiffType: 1,
}
// Do the copy
var f2 DstFoo
awsutil.Copy(&f2, f1)
// Values are equal
assert.Equal(t, f2.A, f1.A)
assert.Equal(t, f2.B, f1.B)
assert.Equal(t, f2.C, f1.C)
assert.Equal(t, "unique", f1.SrcUnique)
assert.Equal(t, 1, f1.SameNameDiffType)
assert.Equal(t, 0, f2.DstUnique)
assert.Equal(t, "", f2.SameNameDiffType)
}
func ExampleCopyOf() {
type Foo struct {
A int
B []*string
}
// Create the initial value
str1 := "hello"
str2 := "bye bye"
f1 := &Foo{A: 1, B: []*string{&str1, &str2}}
// Do the copy
v := awsutil.CopyOf(f1)
var f2 *Foo = v.(*Foo)
// Print the result
fmt.Println(awsutil.Prettify(f2))
// Output:
// {
// A: 1,
// B: ["hello","bye bye"]
// }
}
package awsutil_test
import (
"testing"
"github.com/aws/aws-sdk-go/aws/awsutil"
"github.com/stretchr/testify/assert"
)
type Struct struct {
A []Struct
z []Struct
B *Struct
D *Struct
C string
}
var data = Struct{
A: []Struct{{C: "value1"}, {C: "value2"}, {C: "value3"}},
z: []Struct{{C: "value1"}, {C: "value2"}, {C: "value3"}},
B: &Struct{B: &Struct{C: "terminal"}, D: &Struct{C: "terminal2"}},
C: "initial",
}
func TestValueAtPathSuccess(t *testing.T) {
assert.Equal(t, []interface{}{"initial"}, awsutil.ValuesAtPath(data, "C"))
assert.Equal(t, []interface{}{"value1"}, awsutil.ValuesAtPath(data, "A[0].C"))
assert.Equal(t, []interface{}{"value2"}, awsutil.ValuesAtPath(data, "A[1].C"))
assert.Equal(t, []interface{}{"value3"}, awsutil.ValuesAtPath(data, "A[2].C"))
assert.Equal(t, []interface{}{"value3"}, awsutil.ValuesAtAnyPath(data, "a[2].c"))
assert.Equal(t, []interface{}{"value3"}, awsutil.ValuesAtPath(data, "A[-1].C"))
assert.Equal(t, []interface{}{"value1", "value2", "value3"}, awsutil.ValuesAtPath(data, "A[].C"))
assert.Equal(t, []interface{}{"terminal"}, awsutil.ValuesAtPath(data, "B . B . C"))
assert.Equal(t, []interface{}{"terminal", "terminal2"}, awsutil.ValuesAtPath(data, "B.*.C"))
assert.Equal(t, []interface{}{"initial"}, awsutil.ValuesAtPath(data, "A.D.X || C"))
}
func TestValueAtPathFailure(t *testing.T) {
assert.Equal(t, []interface{}(nil), awsutil.ValuesAtPath(data, "C.x"))
assert.Equal(t, []interface{}(nil), awsutil.ValuesAtPath(data, ".x"))
assert.Equal(t, []interface{}{}, awsutil.ValuesAtPath(data, "X.Y.Z"))
assert.Equal(t, []interface{}{}, awsutil.ValuesAtPath(data, "A[100].C"))
assert.Equal(t, []interface{}{}, awsutil.ValuesAtPath(data, "A[3].C"))
assert.Equal(t, []interface{}{}, awsutil.ValuesAtPath(data, "B.B.C.Z"))
assert.Equal(t, []interface{}(nil), awsutil.ValuesAtPath(data, "z[-1].C"))
assert.Equal(t, []interface{}{}, awsutil.ValuesAtPath(nil, "A.B.C"))
assert.Equal(t, []interface{}{}, awsutil.ValuesAtPath(Struct{}, "A"))
}
func TestSetValueAtPathSuccess(t *testing.T) {
var s Struct
awsutil.SetValueAtPath(&s, "C", "test1")
awsutil.SetValueAtPath(&s, "B.B.C", "test2")
awsutil.SetValueAtPath(&s, "B.D.C", "test3")
assert.Equal(t, "test1", s.C)
assert.Equal(t, "test2", s.B.B.C)
assert.Equal(t, "test3", s.B.D.C)
awsutil.SetValueAtPath(&s, "B.*.C", "test0")
assert.Equal(t, "test0", s.B.B.C)
assert.Equal(t, "test0", s.B.D.C)
var s2 Struct
awsutil.SetValueAtAnyPath(&s2, "b.b.c", "test0")
assert.Equal(t, "test0", s2.B.B.C)
awsutil.SetValueAtAnyPath(&s2, "A", []Struct{{}})
assert.Equal(t, []Struct{{}}, s2.A)
}
package aws
import (
"net/http"
"reflect"
"testing"
"github.com/aws/aws-sdk-go/aws/credentials"
)
var testCredentials = credentials.NewStaticCredentials("AKID", "SECRET", "SESSION")
var copyTestConfig = Config{
Credentials: testCredentials,
Endpoint: String("CopyTestEndpoint"),
Region: String("COPY_TEST_AWS_REGION"),
DisableSSL: Bool(true),
HTTPClient: http.DefaultClient,
LogLevel: LogLevel(LogDebug),
Logger: NewDefaultLogger(),
MaxRetries: Int(DefaultRetries),
DisableParamValidation: Bool(true),
DisableComputeChecksums: Bool(true),
S3ForcePathStyle: Bool(true),
}
func TestCopy(t *testing.T) {
want := copyTestConfig
got := copyTestConfig.Copy()
if !reflect.DeepEqual(*got, want) {
t.Errorf("Copy() = %+v", got)
t.Errorf(" want %+v", want)
}
}
func TestCopyReturnsNewInstance(t *testing.T) {
want := copyTestConfig
got := copyTestConfig.Copy()
if got == &want {
t.Errorf("Copy() = %p; want different instance as source %p", got, &want)
}
}
var mergeTestZeroValueConfig = Config{}
var mergeTestConfig = Config{
Credentials: testCredentials,
Endpoint: String("MergeTestEndpoint"),
Region: String("MERGE_TEST_AWS_REGION"),
DisableSSL: Bool(true),
HTTPClient: http.DefaultClient,
LogLevel: LogLevel(LogDebug),
Logger: NewDefaultLogger(),
MaxRetries: Int(10),
DisableParamValidation: Bool(true),
DisableComputeChecksums: Bool(true),
S3ForcePathStyle: Bool(true),
}
var mergeTests = []struct {
cfg *Config
in *Config
want *Config
}{
{&Config{}, nil, &Config{}},
{&Config{}, &mergeTestZeroValueConfig, &Config{}},
{&Config{}, &mergeTestConfig, &mergeTestConfig},
}
func TestMerge(t *testing.T) {
for i, tt := range mergeTests {
got := tt.cfg.Merge(tt.in)
if !reflect.DeepEqual(got, tt.want) {
t.Errorf("Config %d %+v", i, tt.cfg)
t.Errorf(" Merge(%+v)", tt.in)
t.Errorf(" got %+v", got)
t.Errorf(" want %+v", tt.want)
}
}
}
package corehandlers_test
import (
"fmt"
"net/http"
"os"
"testing"
"github.com/stretchr/testify/assert"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/awserr"
"github.com/aws/aws-sdk-go/aws/corehandlers"
"github.com/aws/aws-sdk-go/aws/credentials"
"github.com/aws/aws-sdk-go/aws/request"
"github.com/aws/aws-sdk-go/aws/service"
)
func TestValidateEndpointHandler(t *testing.T) {
os.Clearenv()
svc := service.New(aws.NewConfig().WithRegion("us-west-2"))
svc.Handlers.Clear()
svc.Handlers.Validate.PushBackNamed(corehandlers.ValidateEndpointHandler)
req := svc.NewRequest(&request.Operation{Name: "Operation"}, nil, nil)
err := req.Build()
assert.NoError(t, err)
}
func TestValidateEndpointHandlerErrorRegion(t *testing.T) {
os.Clearenv()
svc := service.New(nil)
svc.Handlers.Clear()
svc.Handlers.Validate.PushBackNamed(corehandlers.ValidateEndpointHandler)
req := svc.NewRequest(&request.Operation{Name: "Operation"}, nil, nil)
err := req.Build()
assert.Error(t, err)
assert.Equal(t, aws.ErrMissingRegion, err)
}
type mockCredsProvider struct {
expired bool
retrieveCalled bool
}
func (m *mockCredsProvider) Retrieve() (credentials.Value, error) {
m.retrieveCalled = true
return credentials.Value{}, nil
}
func (m *mockCredsProvider) IsExpired() bool {
return m.expired
}
func TestAfterRetryRefreshCreds(t *testing.T) {
os.Clearenv()
credProvider := &mockCredsProvider{}
svc := service.New(&aws.Config{Credentials: credentials.NewCredentials(credProvider), MaxRetries: aws.Int(1)})
svc.Handlers.Clear()
svc.Handlers.ValidateResponse.PushBack(func(r *request.Request) {
r.Error = awserr.New("UnknownError", "", nil)
r.HTTPResponse = &http.Response{StatusCode: 400}
})
svc.Handlers.UnmarshalError.PushBack(func(r *request.Request) {
r.Error = awserr.New("ExpiredTokenException", "", nil)
})
svc.Handlers.AfterRetry.PushBackNamed(corehandlers.AfterRetryHandler)
assert.True(t, svc.Config.Credentials.IsExpired(), "Expect to start out expired")
assert.False(t, credProvider.retrieveCalled)
req := svc.NewRequest(&request.Operation{Name: "Operation"}, nil, nil)
req.Send()
assert.True(t, svc.Config.Credentials.IsExpired())
assert.False(t, credProvider.retrieveCalled)
_, err := svc.Config.Credentials.Get()
assert.NoError(t, err)
assert.True(t, credProvider.retrieveCalled)
}
type testSendHandlerTransport struct{}
func (t *testSendHandlerTransport) RoundTrip(r *http.Request) (*http.Response, error) {
return nil, fmt.Errorf("mock error")
}
func TestSendHandlerError(t *testing.T) {
svc := service.New(&aws.Config{
HTTPClient: &http.Client{
Transport: &testSendHandlerTransport{},
},
})
svc.Handlers.Clear()
svc.Handlers.Send.PushBackNamed(corehandlers.SendHandler)
r := svc.NewRequest(&request.Operation{Name: "Operation"}, nil, nil)
r.Send()
assert.Error(t, r.Error)
assert.NotNil(t, r.HTTPResponse)
}
package corehandlers_test
import (
"testing"
"github.com/stretchr/testify/assert"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/awserr"
"github.com/aws/aws-sdk-go/aws/corehandlers"
"github.com/aws/aws-sdk-go/aws/request"
"github.com/aws/aws-sdk-go/aws/service"
"github.com/aws/aws-sdk-go/aws/service/serviceinfo"
"github.com/stretchr/testify/require"
)
var testSvc = func() *service.Service {
s := &service.Service{
ServiceInfo: serviceinfo.ServiceInfo{
Config: &aws.Config{},
ServiceName: "mock-service",
APIVersion: "2015-01-01",
},
}
return s
}()
type StructShape struct {
RequiredList []*ConditionalStructShape `required:"true"`
RequiredMap map[string]*ConditionalStructShape `required:"true"`
RequiredBool *bool `required:"true"`
OptionalStruct *ConditionalStructShape
hiddenParameter *string
metadataStructureShape
}
type metadataStructureShape struct {
SDKShapeTraits bool
}
type ConditionalStructShape struct {
Name *string `required:"true"`
SDKShapeTraits bool
}
func TestNoErrors(t *testing.T) {
input := &StructShape{
RequiredList: []*ConditionalStructShape{},
RequiredMap: map[string]*ConditionalStructShape{
"key1": {Name: aws.String("Name")},
"key2": {Name: aws.String("Name")},
},
RequiredBool: aws.Bool(true),
OptionalStruct: &ConditionalStructShape{Name: aws.String("Name")},
}
req := testSvc.NewRequest(&request.Operation{}, input, nil)
corehandlers.ValidateParametersHandler.Fn(req)
require.NoError(t, req.Error)
}
func TestMissingRequiredParameters(t *testing.T) {
input := &StructShape{}
req := testSvc.NewRequest(&request.Operation{}, input, nil)
corehandlers.ValidateParametersHandler.Fn(req)
require.Error(t, req.Error)
assert.Equal(t, "InvalidParameter", req.Error.(awserr.Error).Code())
assert.Equal(t, "3 validation errors:\n- missing required parameter: RequiredList\n- missing required parameter: RequiredMap\n- missing required parameter: RequiredBool", req.Error.(awserr.Error).Message())
}
func TestNestedMissingRequiredParameters(t *testing.T) {
input := &StructShape{
RequiredList: []*ConditionalStructShape{{}},
RequiredMap: map[string]*ConditionalStructShape{
"key1": {Name: aws.String("Name")},
"key2": {},
},
RequiredBool: aws.Bool(true),
OptionalStruct: &ConditionalStructShape{},
}
req := testSvc.NewRequest(&request.Operation{}, input, nil)
corehandlers.ValidateParametersHandler.Fn(req)
require.Error(t, req.Error)
assert.Equal(t, "InvalidParameter", req.Error.(awserr.Error).Code())
assert.Equal(t, "3 validation errors:\n- missing required parameter: RequiredList[0].Name\n- missing required parameter: RequiredMap[\"key2\"].Name\n- missing required parameter: OptionalStruct.Name", req.Error.(awserr.Error).Message())
}
type testInput struct {
StringField string `min:"5"`
PtrStrField *string `min:"2"`
ListField []string `min:"3"`
MapField map[string]string `min:"4"`
}
var testsFieldMin = []struct {
err awserr.Error
in testInput
}{
{
err: awserr.New("InvalidParameter", "1 validation errors:\n- field too short, minimum length 5: StringField", nil),
in: testInput{StringField: "abcd"},
},
{
err: awserr.New("InvalidParameter", "2 validation errors:\n- field too short, minimum length 5: StringField\n- field too short, minimum length 3: ListField", nil),
in: testInput{StringField: "abcd", ListField: []string{"a", "b"}},
},
{
err: awserr.New("InvalidParameter", "3 validation errors:\n- field too short, minimum length 5: StringField\n- field too short, minimum length 3: ListField\n- field too short, minimum length 4: MapField", nil),
in: testInput{StringField: "abcd", ListField: []string{"a", "b"}, MapField: map[string]string{"a": "a", "b": "b"}},
},
{
err: awserr.New("InvalidParameter", "1 validation errors:\n- field too short, minimum length 2: PtrStrField", nil),
in: testInput{StringField: "abcde", PtrStrField: aws.String("v")},
},
{
err: nil,
in: testInput{StringField: "abcde", PtrStrField: aws.String("value"),
ListField: []string{"a", "b", "c"}, MapField: map[string]string{"a": "a", "b": "b", "c": "c", "d": "d"}},
},
}
func TestValidateFieldMinParameter(t *testing.T) {
for i, c := range testsFieldMin {
req := testSvc.NewRequest(&request.Operation{}, &c.in, nil)
corehandlers.ValidateParametersHandler.Fn(req)
require.Equal(t, c.err, req.Error, "%d case failed", i)
}
}
package credentials
import (
"testing"
"github.com/aws/aws-sdk-go/aws/awserr"
"github.com/stretchr/testify/assert"
)
func TestChainProviderGet(t *testing.T) {
p := &ChainProvider{
Providers: []Provider{
&stubProvider{err: awserr.New("FirstError", "first provider error", nil)},
&stubProvider{err: awserr.New("SecondError", "second provider error", nil)},
&stubProvider{
creds: Value{
AccessKeyID: "AKID",
SecretAccessKey: "SECRET",
SessionToken: "",
},
},
},
}
creds, err := p.Retrieve()
assert.Nil(t, err, "Expect no error")
assert.Equal(t, "AKID", creds.AccessKeyID, "Expect access key ID to match")
assert.Equal(t, "SECRET", creds.SecretAccessKey, "Expect secret access key to match")
assert.Empty(t, creds.SessionToken, "Expect session token to be empty")
}
func TestChainProviderIsExpired(t *testing.T) {
stubProvider := &stubProvider{expired: true}
p := &ChainProvider{
Providers: []Provider{
stubProvider,
},
}
assert.True(t, p.IsExpired(), "Expect expired to be true before any Retrieve")
_, err := p.Retrieve()
assert.Nil(t, err, "Expect no error")
assert.False(t, p.IsExpired(), "Expect not expired after retrieve")
stubProvider.expired = true
assert.True(t, p.IsExpired(), "Expect return of expired provider")
_, err = p.Retrieve()
assert.False(t, p.IsExpired(), "Expect not expired after retrieve")
}
func TestChainProviderWithNoProvider(t *testing.T) {
p := &ChainProvider{
Providers: []Provider{},
}
assert.True(t, p.IsExpired(), "Expect expired with no providers")
_, err := p.Retrieve()
assert.Equal(t, ErrNoValidProvidersFoundInChain, err, "Expect no providers error returned")
}
func TestChainProviderWithNoValidProvider(t *testing.T) {
p := &ChainProvider{
Providers: []Provider{
&stubProvider{err: awserr.New("FirstError", "first provider error", nil)},
&stubProvider{err: awserr.New("SecondError", "second provider error", nil)},
},
}
assert.True(t, p.IsExpired(), "Expect expired with no providers")
_, err := p.Retrieve()
assert.Equal(t, ErrNoValidProvidersFoundInChain, err, "Expect no providers error returned")
}
package credentials
import (
"testing"
"github.com/aws/aws-sdk-go/aws/awserr"
"github.com/stretchr/testify/assert"
)
type stubProvider struct {
creds Value
expired bool
err error
}
func (s *stubProvider) Retrieve() (Value, error) {
s.expired = false
return s.creds, s.err
}
func (s *stubProvider) IsExpired() bool {
return s.expired
}
func TestCredentialsGet(t *testing.T) {
c := NewCredentials(&stubProvider{
creds: Value{
AccessKeyID: "AKID",
SecretAccessKey: "SECRET",
SessionToken: "",
},
expired: true,
})
creds, err := c.Get()
assert.Nil(t, err, "Expected no error")
assert.Equal(t, "AKID", creds.AccessKeyID, "Expect access key ID to match")
assert.Equal(t, "SECRET", creds.SecretAccessKey, "Expect secret access key to match")
assert.Empty(t, creds.SessionToken, "Expect session token to be empty")
}
func TestCredentialsGetWithError(t *testing.T) {
c := NewCredentials(&stubProvider{err: awserr.New("provider error", "", nil), expired: true})
_, err := c.Get()
assert.Equal(t, "provider error", err.(awserr.Error).Code(), "Expected provider error")
}
func TestCredentialsExpire(t *testing.T) {
stub := &stubProvider{}
c := NewCredentials(stub)
stub.expired = false
assert.True(t, c.IsExpired(), "Expected to start out expired")
c.Expire()
assert.True(t, c.IsExpired(), "Expected to be expired")
c.forceRefresh = false
assert.False(t, c.IsExpired(), "Expected not to be expired")
stub.expired = true
assert.True(t, c.IsExpired(), "Expected to be expired")
}
package ec2rolecreds_test
import (
"fmt"
"net/http"
"net/http/httptest"
"testing"
"time"
"github.com/stretchr/testify/assert"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/awserr"
"github.com/aws/aws-sdk-go/aws/credentials/ec2rolecreds"
"github.com/aws/aws-sdk-go/aws/ec2metadata"
)
const credsRespTmpl = `{
"Code": "Success",
"Type": "AWS-HMAC",
"AccessKeyId" : "accessKey",
"SecretAccessKey" : "secret",
"Token" : "token",
"Expiration" : "%s",
"LastUpdated" : "2009-11-23T0:00:00Z"
}`
const credsFailRespTmpl = `{
"Code": "ErrorCode",
"Message": "ErrorMsg",
"LastUpdated": "2009-11-23T0:00:00Z"
}`
func initTestServer(expireOn string, failAssume bool) *httptest.Server {
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if r.URL.Path == "/latest/meta-data/iam/security-credentials" {
fmt.Fprintln(w, "RoleName")
} else if r.URL.Path == "/latest/meta-data/iam/security-credentials/RoleName" {
if failAssume {
fmt.Fprintf(w, credsFailRespTmpl)
} else {
fmt.Fprintf(w, credsRespTmpl, expireOn)
}
} else {
http.Error(w, "bad request", http.StatusBadRequest)
}
}))
return server
}
func TestEC2RoleProvider(t *testing.T) {
server := initTestServer("2014-12-16T01:51:37Z", false)
defer server.Close()
p := &ec2rolecreds.EC2RoleProvider{
Client: ec2metadata.New(&ec2metadata.Config{Endpoint: aws.String(server.URL + "/latest")}),
}
creds, err := p.Retrieve()
assert.Nil(t, err, "Expect no error")
assert.Equal(t, "accessKey", creds.AccessKeyID, "Expect access key ID to match")
assert.Equal(t, "secret", creds.SecretAccessKey, "Expect secret access key to match")
assert.Equal(t, "token", creds.SessionToken, "Expect session token to match")
}
func TestEC2RoleProviderFailAssume(t *testing.T) {
server := initTestServer("2014-12-16T01:51:37Z", true)
defer server.Close()
p := &ec2rolecreds.EC2RoleProvider{
Client: ec2metadata.New(&ec2metadata.Config{Endpoint: aws.String(server.URL + "/latest")}),
}
creds, err := p.Retrieve()
assert.Error(t, err, "Expect error")
e := err.(awserr.Error)
assert.Equal(t, "ErrorCode", e.Code())
assert.Equal(t, "ErrorMsg", e.Message())
assert.Nil(t, e.OrigErr())
assert.Equal(t, "", creds.AccessKeyID, "Expect access key ID to match")
assert.Equal(t, "", creds.SecretAccessKey, "Expect secret access key to match")
assert.Equal(t, "", creds.SessionToken, "Expect session token to match")
}
func TestEC2RoleProviderIsExpired(t *testing.T) {
server := initTestServer("2014-12-16T01:51:37Z", false)
defer server.Close()
p := &ec2rolecreds.EC2RoleProvider{
Client: ec2metadata.New(&ec2metadata.Config{Endpoint: aws.String(server.URL + "/latest")}),
}
p.CurrentTime = func() time.Time {
return time.Date(2014, 12, 15, 21, 26, 0, 0, time.UTC)
}
assert.True(t, p.IsExpired(), "Expect creds to be expired before retrieve.")
_, err := p.Retrieve()
assert.Nil(t, err, "Expect no error")
assert.False(t, p.IsExpired(), "Expect creds to not be expired after retrieve.")
p.CurrentTime = func() time.Time {
return time.Date(3014, 12, 15, 21, 26, 0, 0, time.UTC)
}
assert.True(t, p.IsExpired(), "Expect creds to be expired.")
}
func TestEC2RoleProviderExpiryWindowIsExpired(t *testing.T) {
server := initTestServer("2014-12-16T01:51:37Z", false)
defer server.Close()
p := &ec2rolecreds.EC2RoleProvider{
Client: ec2metadata.New(&ec2metadata.Config{Endpoint: aws.String(server.URL + "/latest")}),
ExpiryWindow: time.Hour * 1,
}
p.CurrentTime = func() time.Time {
return time.Date(2014, 12, 15, 0, 51, 37, 0, time.UTC)
}
assert.True(t, p.IsExpired(), "Expect creds to be expired before retrieve.")
_, err := p.Retrieve()
assert.Nil(t, err, "Expect no error")
assert.False(t, p.IsExpired(), "Expect creds to not be expired after retrieve.")
p.CurrentTime = func() time.Time {
return time.Date(2014, 12, 16, 0, 55, 37, 0, time.UTC)
}
assert.True(t, p.IsExpired(), "Expect creds to be expired.")
}
func BenchmarkEC2RoleProvider(b *testing.B) {
server := initTestServer("2014-12-16T01:51:37Z", false)
defer server.Close()
p := &ec2rolecreds.EC2RoleProvider{
Client: ec2metadata.New(&ec2metadata.Config{Endpoint: aws.String(server.URL + "/latest")}),
}
_, err := p.Retrieve()
if err != nil {
b.Fatal(err)
}
b.ResetTimer()
b.RunParallel(func(pb *testing.PB) {
for pb.Next() {
_, err := p.Retrieve()
if err != nil {
b.Fatal(err)
}
}
})
}
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment