blob: 16ede0d270aec87eada4acbefb6dc51285f6df35 [file] [log] [blame]
Dan Willemsen34cc69e2015-09-23 15:26:20 -07001// Copyright 2015 Google Inc. All rights reserved.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15package common
16
17import (
18 "errors"
19 "fmt"
20 "reflect"
21 "strings"
22 "testing"
23)
24
25type strsTestCase struct {
26 in []string
27 out string
28 err []error
29}
30
31var commonValidatePathTestCases = []strsTestCase{
32 {
33 in: []string{""},
34 out: "",
35 },
36 {
37 in: []string{"a/b"},
38 out: "a/b",
39 },
40 {
41 in: []string{"a/b", "c"},
42 out: "a/b/c",
43 },
44 {
45 in: []string{"a/.."},
46 out: ".",
47 },
48 {
49 in: []string{"."},
50 out: ".",
51 },
52 {
53 in: []string{".."},
54 out: "",
55 err: []error{errors.New("Path is outside directory: ..")},
56 },
57 {
58 in: []string{"../a"},
59 out: "",
60 err: []error{errors.New("Path is outside directory: ../a")},
61 },
62 {
63 in: []string{"b/../../a"},
64 out: "",
65 err: []error{errors.New("Path is outside directory: ../a")},
66 },
67 {
68 in: []string{"/a"},
69 out: "",
70 err: []error{errors.New("Path is outside directory: /a")},
71 },
72}
73
74var validateSafePathTestCases = append(commonValidatePathTestCases, []strsTestCase{
75 {
76 in: []string{"$host/../$a"},
77 out: "$a",
78 },
79}...)
80
81var validatePathTestCases = append(commonValidatePathTestCases, []strsTestCase{
82 {
83 in: []string{"$host/../$a"},
84 out: "",
85 err: []error{errors.New("Path contains invalid character($): $host/../$a")},
86 },
87 {
88 in: []string{"$host/.."},
89 out: "",
90 err: []error{errors.New("Path contains invalid character($): $host/..")},
91 },
92}...)
93
94func TestValidateSafePath(t *testing.T) {
95 for _, testCase := range validateSafePathTestCases {
96 ctx := &configErrorWrapper{}
97 out := validateSafePath(ctx, testCase.in...)
98 check(t, "validateSafePath", p(testCase.in), out, ctx.errors, testCase.out, testCase.err)
99 }
100}
101
102func TestValidatePath(t *testing.T) {
103 for _, testCase := range validatePathTestCases {
104 ctx := &configErrorWrapper{}
105 out := validatePath(ctx, testCase.in...)
106 check(t, "validatePath", p(testCase.in), out, ctx.errors, testCase.out, testCase.err)
107 }
108}
109
110func TestOptionalPath(t *testing.T) {
111 var path OptionalPath
112 checkInvalidOptionalPath(t, path)
113
114 path = OptionalPathForPath(nil)
115 checkInvalidOptionalPath(t, path)
116}
117
118func checkInvalidOptionalPath(t *testing.T, path OptionalPath) {
119 if path.Valid() {
120 t.Errorf("Uninitialized OptionalPath should not be valid")
121 }
122 if path.String() != "" {
123 t.Errorf("Uninitialized OptionalPath String() should return \"\", not %q", path.String())
124 }
125 defer func() {
126 if r := recover(); r == nil {
127 t.Errorf("Expected a panic when calling Path() on an uninitialized OptionalPath")
128 }
129 }()
130 path.Path()
131}
132
133func check(t *testing.T, testType, testString string,
134 got interface{}, err []error,
135 expected interface{}, expectedErr []error) {
136
137 printedTestCase := false
138 e := func(s string, expected, got interface{}) {
139 if !printedTestCase {
140 t.Errorf("test case %s: %s", testType, testString)
141 printedTestCase = true
142 }
143 t.Errorf("incorrect %s", s)
144 t.Errorf(" expected: %s", p(expected))
145 t.Errorf(" got: %s", p(got))
146 }
147
148 if !reflect.DeepEqual(expectedErr, err) {
149 e("errors:", expectedErr, err)
150 }
151
152 if !reflect.DeepEqual(expected, got) {
153 e("output:", expected, got)
154 }
155}
156
157func p(in interface{}) string {
158 if v, ok := in.([]interface{}); ok {
159 s := make([]string, len(v))
160 for i := range v {
161 s[i] = fmt.Sprintf("%#v", v[i])
162 }
163 return "[" + strings.Join(s, ", ") + "]"
164 } else {
165 return fmt.Sprintf("%#v", in)
166 }
167}