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  }