github.com/jbking/gohan@v0.0.0-20151217002006-b41ccf1c2a96/extension/otto/donburi_test.go (about) 1 // Copyright (C) 2015 NTT Innovation Institute, Inc. 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 12 // implied. 13 // See the License for the specific language governing permissions and 14 // limitations under the License. 15 16 package otto 17 18 import ( 19 "os" 20 "testing" 21 22 "github.com/cloudwan/gohan/db" 23 "github.com/cloudwan/gohan/schema" 24 "github.com/cloudwan/gohan/server/middleware" 25 . "github.com/onsi/gomega" 26 ) 27 28 var ( 29 dataStore db.DB 30 ) 31 32 const ( 33 dbtype = "yaml" 34 conn = "./test_extension.yaml" 35 ) 36 37 func beforeEach() { 38 os.Remove(conn) 39 dataStore, _ = db.ConnectDB(dbtype, conn) 40 } 41 42 func afterEach() { 43 os.Remove(conn) 44 } 45 46 func TestDonburiFlows(t *testing.T) { 47 RegisterTestingT(t) 48 beforeEach() 49 defer afterEach() 50 donburi, err := schema.NewExtension(map[string]interface{}{ 51 "id": "donburi", 52 "url": "file://../../etc/extensions/donburi.js", 53 "path": ".*", 54 }) 55 if err != nil { 56 t.Error(err) 57 } 58 59 extension, err := schema.NewExtension(map[string]interface{}{ 60 "id": "test_donburi", 61 "code": `tasks: 62 - eval: "1 + 1" 63 register: result 64 - eval: "true" 65 register: when_is_working 66 when: "result == 2" 67 - block: 68 - vars: 69 list2 : [4, 5, 6] 70 - eval: "result += item" 71 with_items: 72 - 1 73 - 2 74 - 3 75 when: when_is_working 76 - vars: 77 message: "hello" 78 - vars: 79 retry_count: 0 80 rescue_executed: false 81 always_executed: false 82 template_test: "message: {{.message}}" 83 - eval: "result += item" 84 with_items: "list2" 85 - eval: "context[item.key] = item.value" 86 with_dict: 87 alice: 18 88 bob: 21 89 - block: 90 - sleep: 10 91 - eval: retry_count += 1 92 - eval: throw 'error' 93 rescue: 94 - eval: "rescue_executed = true" 95 always: 96 - eval: "always_executed = true" 97 retry: 3 98 `, 99 "path": ".*", 100 "code_type": "donburi", 101 }) 102 if err != nil { 103 t.Error(err) 104 } 105 106 context := map[string]interface{}{} 107 108 extensions := []*schema.Extension{donburi, extension} 109 env := NewEnvironment(dataStore, &middleware.FakeIdentity{}) 110 err = env.LoadExtensionsForPath(extensions, "test_path") 111 if err != nil { 112 t.Error(err) 113 } 114 err = env.HandleEvent("post_create", context) 115 if err != nil { 116 t.Error(err) 117 } 118 Expect(context["result"]).To(Equal(float64(23))) 119 Expect(context["when_is_working"]).To(Equal(true)) 120 Expect(context["rescue_executed"]).To(Equal(true)) 121 Expect(context["always_executed"]).To(Equal(true)) 122 Expect(context["template_test"]).To(Equal("message: hello")) 123 Expect(context["alice"]).To(Equal(int(18))) 124 Expect(context["retry_count"]).To(Equal(float64(3))) 125 } 126 127 func TestDefine(t *testing.T) { 128 RegisterTestingT(t) 129 beforeEach() 130 defer afterEach() 131 donburi, err := schema.NewExtension(map[string]interface{}{ 132 "id": "donburi", 133 "url": "file://../../etc/extensions/donburi.js", 134 "path": ".*", 135 }) 136 if err != nil { 137 t.Error(err) 138 } 139 140 extension, err := schema.NewExtension(map[string]interface{}{ 141 "id": "test_donburi", 142 "code": `tasks: 143 - define: 144 name: "add" 145 tasks: 146 - eval: "left+right" 147 - add: 148 left: 1 149 right: 2 150 register: answer 151 `, 152 "path": ".*", 153 "code_type": "donburi", 154 }) 155 if err != nil { 156 t.Error(err) 157 } 158 159 context := map[string]interface{}{} 160 161 extensions := []*schema.Extension{donburi, extension} 162 env := NewEnvironment(dataStore, &middleware.FakeIdentity{}) 163 err = env.LoadExtensionsForPath(extensions, "test_path") 164 if err != nil { 165 t.Error(err) 166 } 167 err = env.HandleEvent("post_create", context) 168 if err != nil { 169 t.Error(err) 170 } 171 Expect(context["answer"]).To(Equal(float64(3))) 172 } 173 174 func TestDonburiExec(t *testing.T) { 175 RegisterTestingT(t) 176 beforeEach() 177 defer afterEach() 178 donburi, err := schema.NewExtension(map[string]interface{}{ 179 "id": "donburi", 180 "url": "file://../../etc/extensions/donburi.js", 181 "path": ".*", 182 }) 183 if err != nil { 184 t.Error(err) 185 } 186 187 extension, err := schema.NewExtension(map[string]interface{}{ 188 "id": "test_donburi", 189 "code": `tasks: 190 - command: 191 name: echo 192 args: 193 - test 194 register: result 195 - command: 196 name: no_command 197 args: [] 198 register: result2 199 `, 200 "path": ".*", 201 "code_type": "donburi", 202 }) 203 if err != nil { 204 t.Error(err) 205 } 206 207 context := map[string]interface{}{} 208 209 extensions := []*schema.Extension{donburi, extension} 210 env := NewEnvironment(dataStore, &middleware.FakeIdentity{}) 211 err = env.LoadExtensionsForPath(extensions, "test_path") 212 if err != nil { 213 t.Error(err) 214 } 215 err = env.HandleEvent("post_create", context) 216 if err != nil { 217 t.Error(err) 218 } 219 output := context["result"].(map[string]string) 220 Expect(output["status"]).To(Equal("success")) 221 Expect(output["output"]).To(Equal("test\n")) 222 output2 := context["result2"].(map[string]string) 223 Expect(output2["status"]).To(Equal("error")) 224 } 225 226 func TestDonburiInjectionAttack(t *testing.T) { 227 RegisterTestingT(t) 228 beforeEach() 229 defer afterEach() 230 donburi, err := schema.NewExtension(map[string]interface{}{ 231 "id": "donburi", 232 "url": "file://../../etc/extensions/donburi.js", 233 "path": ".*", 234 }) 235 if err != nil { 236 t.Error(err) 237 } 238 239 extension, err := schema.NewExtension(map[string]interface{}{ 240 "id": "test_donburi", 241 "code": `tasks: 242 - vars: 243 executed: true 244 when: code 245 - eval: "{{.code}}" 246 - block: 247 - eval: "throw error" 248 rescue: 249 - eval "{{.code}}" 250 always: 251 - eval "{{.code}}" 252 when: code 253 `, 254 "path": ".*", 255 "code_type": "donburi", 256 }) 257 if err != nil { 258 t.Error(err) 259 } 260 261 context := map[string]interface{}{ 262 "attacked": false, 263 "code": "context['attacked'] = true", 264 } 265 266 extensions := []*schema.Extension{donburi, extension} 267 env := NewEnvironment(dataStore, &middleware.FakeIdentity{}) 268 err = env.LoadExtensionsForPath(extensions, "test_path") 269 if err != nil { 270 t.Error(err) 271 } 272 err = env.HandleEvent("post_create", context) 273 if err != nil { 274 t.Error(err) 275 } 276 Expect(context["attacked"]).To(Equal(false)) 277 } 278 279 func TestDonburiResources(t *testing.T) { 280 RegisterTestingT(t) 281 beforeEach() 282 defer afterEach() 283 donburi, err := schema.NewExtension(map[string]interface{}{ 284 "id": "donburi", 285 "url": "file://../../etc/extensions/donburi.js", 286 "path": ".*", 287 }) 288 if err != nil { 289 t.Error(err) 290 } 291 292 extension, err := schema.NewExtension(map[string]interface{}{ 293 "id": "test_donburi", 294 "code": `tasks: 295 - vars: 296 failed: false 297 - resources: 298 - vars: 299 dependent: true 300 - eval: "if(dependent){failed = true}" 301 when: event_type == "pre_delete" 302 - eval: "if(!dependent){failed = true}" 303 when: event_type == "post_create" 304 - vars: 305 dependent: false 306 `, 307 "path": ".*", 308 "code_type": "donburi", 309 }) 310 if err != nil { 311 t.Error(err) 312 } 313 314 context := map[string]interface{}{} 315 316 extensions := []*schema.Extension{donburi, extension} 317 env := NewEnvironment(dataStore, &middleware.FakeIdentity{}) 318 err = env.LoadExtensionsForPath(extensions, "test_path") 319 if err != nil { 320 t.Error(err) 321 } 322 err = env.HandleEvent("post_create", context) 323 if err != nil { 324 t.Error(err) 325 } 326 Expect(context["failed"]).To(Equal(false)) 327 err = env.HandleEvent("pre_delete", context) 328 if err != nil { 329 t.Error(err) 330 } 331 Expect(context["failed"]).To(Equal(false)) 332 } 333 334 func BenchmarkDonburi(b *testing.B) { 335 beforeEach() 336 defer afterEach() 337 donburi, _ := schema.NewExtension(map[string]interface{}{ 338 "id": "donburi", 339 "url": "file://../../etc/extensions/donburi.js", 340 "path": ".*", 341 }) 342 extension, _ := schema.NewExtension(map[string]interface{}{ 343 "id": "test_donburi", 344 "code": `tasks: 345 - vars: 346 message: "hello" 347 - vars: 348 template_test: "message: {{.message}}" 349 `, 350 "path": ".*", 351 "code_type": "donburi", 352 }) 353 354 context := map[string]interface{}{} 355 356 extensions := []*schema.Extension{donburi, extension} 357 env := NewEnvironment(dataStore, &middleware.FakeIdentity{}) 358 err := env.LoadExtensionsForPath(extensions, "test_path") 359 if err != nil { 360 b.Error(err) 361 } 362 363 b.ResetTimer() 364 for i := 0; i < b.N; i++ { 365 env.HandleEvent("post_create", context) 366 } 367 }