github.com/devcamcar/cli@v0.0.0-20181107134215-706a05759d18/test/cli_crud_test.go (about)

     1  package test
     2  
     3  import (
     4  	"fmt"
     5  	"testing"
     6  
     7  	"regexp"
     8  	"strings"
     9  
    10  	"github.com/fnproject/cli/testharness"
    11  )
    12  
    13  // TODO: These are both  Super minimal
    14  func TestFnAppUpdateCycle(t *testing.T) {
    15  	t.Parallel()
    16  
    17  	h := testharness.Create(t)
    18  	defer h.Cleanup()
    19  
    20  	appName := h.NewAppName()
    21  
    22  	// can't create an app twice
    23  	h.Fn("create", "app", appName).AssertSuccess()
    24  	h.Fn("create", "app", appName).AssertFailed()
    25  	h.Fn("list", "apps", appName).AssertSuccess().AssertStdoutContains(appName)
    26  	// Test looking up app by name when multiple pages worth of apps exist
    27  	for i := 0; i < 50; i++ {
    28  		h.Fn("create", "app", fmt.Sprintf("%s%d", appName, i)).AssertSuccess()
    29  	}
    30  	h.Fn("inspect", "app", appName).AssertSuccess().AssertStdoutContains(fmt.Sprintf(`"name": "%s"`, appName))
    31  	h.Fn("config", "app", appName, "fooConfig", "barval").AssertSuccess()
    32  	h.Fn("get", "config", "app", appName, "fooConfig").AssertSuccess().AssertStdoutContains("barval")
    33  	h.Fn("list", "config", "app", appName).AssertSuccess().AssertStdoutContains("barval")
    34  	h.Fn("unset", "config", "app", appName, "fooConfig").AssertSuccess()
    35  	h.Fn("get", "config", "app", appName, "fooConfig").AssertFailed()
    36  	h.Fn("list", "config", "app", appName).AssertSuccess().AssertStdoutEmpty()
    37  	h.Fn("delete", "app", appName).AssertSuccess()
    38  }
    39  
    40  // func
    41  func TestSimpleFnFunctionUpdateCycle(t *testing.T) {
    42  	t.Parallel()
    43  
    44  	h := testharness.Create(t)
    45  	defer h.Cleanup()
    46  	appName1 := h.NewAppName()
    47  	funcName1 := h.NewFuncName(appName1)
    48  	h.Fn("create", "function", appName1, funcName1, "foo/duffimage:0.0.1").AssertFailed()
    49  	h.Fn("create", "app", appName1).AssertSuccess()
    50  	h.Fn("create", "function", appName1, funcName1, "foo/duffimage:0.0.1").AssertSuccess()
    51  	h.Fn("create", "function", appName1, funcName1, "foo/duffimage:0.0.1").AssertFailed()
    52  	h.Fn("inspect", "function", appName1, funcName1).AssertSuccess().AssertStdoutContains(`"image": "foo/duffimage:0.0.1"`)
    53  	h.Fn("update", "function", appName1, funcName1, "bar/duffbeer:0.1.2").AssertSuccess()
    54  	h.Fn("config", "function", appName1, funcName1, "confA", "valB").AssertSuccess()
    55  	h.Fn("get", "config", "function", appName1, funcName1, "confA").AssertSuccess().AssertStdoutContains("valB")
    56  	h.Fn("list", "config", "function", appName1, funcName1).AssertSuccess().AssertStdoutContains("valB")
    57  	h.Fn("unset", "config", "function", appName1, funcName1, "confA").AssertSuccess()
    58  	h.Fn("get", "config", "function", appName1, funcName1, "confA").AssertFailed()
    59  }
    60  
    61  // triggers
    62  func TestSimpleFnTriggerUpdateCycle(t *testing.T) {
    63  	t.Parallel()
    64  
    65  	h := testharness.Create(t)
    66  	defer h.Cleanup()
    67  	appName1 := h.NewAppName()
    68  	funcName1 := h.NewFuncName(appName1)
    69  	triggerName1 := h.NewTriggerName(appName1, funcName1)
    70  	h.Fn("create", "trigger", appName1, funcName1, triggerName1).AssertFailed()
    71  	h.Fn("create", "app", appName1).AssertSuccess()
    72  	h.Fn("create", "trigger", appName1, funcName1, triggerName1).AssertFailed()
    73  	h.Fn("create", "function", appName1, funcName1, "foo/duffimage:0.0.1").AssertSuccess()
    74  	h.Fn("create", "trigger", appName1, funcName1, triggerName1, "--type", "http", "--source", "/mytrigger").AssertSuccess()
    75  	h.Fn("create", "trigger", appName1, funcName1, triggerName1, "--type", "http", "--source", "/mytrigger").AssertFailed()
    76  	h.Fn("inspect", "trigger", appName1, funcName1, triggerName1).AssertSuccess().AssertStdoutContains(`"source": "/mytrigger`)
    77  	h.Fn("update", "trigger", appName1, funcName1, triggerName1, "--annotation", `"val1='["val2"]'"`).AssertSuccess()
    78  }
    79  
    80  func TestRemovingFnAnnotation(t *testing.T) {
    81  	t.Parallel()
    82  
    83  	h := testharness.Create(t)
    84  	defer h.Cleanup()
    85  	appName1 := h.NewAppName()
    86  	funcName1 := h.NewFuncName(appName1)
    87  	h.Fn("create", "app", appName1).AssertSuccess()
    88  	h.Fn("create", "fn", appName1, funcName1, "foo/duffimage:0.0.1", "--annotation", "test=1").AssertSuccess()
    89  	h.Fn("inspect", "fn", appName1, funcName1).AssertSuccess().AssertStdoutContainsJSON([]string{"annotations", "test"}, 1.0)
    90  	h.Fn("update", "fn", appName1, funcName1, "foo/duffimage:0.0.1", "--annotation", `test=""`).AssertSuccess()
    91  	h.Fn("inspect", "fn", appName1, funcName1).AssertSuccess().AssertStdoutMissingJSONPath([]string{"annotations", "test"})
    92  }
    93  
    94  func TestInvalidFnAnnotationValue(t *testing.T) {
    95  	t.Parallel()
    96  
    97  	h := testharness.Create(t)
    98  	defer h.Cleanup()
    99  	appName1 := h.NewAppName()
   100  	funcName1 := h.NewFuncName(appName1)
   101  
   102  	h.Fn("create", "app", appName1).AssertSuccess()
   103  	h.Fn("create", "fn", appName1, funcName1, "foo/duffimage:0.0.1", "--annotation", "test=value").AssertSuccess().AssertStderrContains("Unable to parse annotation value 'value'. Annotations values must be valid JSON strings.")
   104  	h.Fn("inspect", "fn", appName1, funcName1).AssertSuccess().AssertStdoutMissingJSONPath([]string{"annotations", "test"})
   105  }
   106  
   107  func TestFnUpdateValues(t *testing.T) {
   108  	t.Parallel()
   109  
   110  	validCases := []struct {
   111  		args   []string
   112  		query  []string
   113  		result interface{}
   114  	}{
   115  		{[]string{"--memory", "129"}, []string{"memory"}, 129.0},
   116  		{[]string{"--timeout", "111"}, []string{"timeout"}, 111.0},
   117  		{[]string{"--idle-timeout", "128"}, []string{"idle_timeout"}, 128.0},
   118  		{[]string{"--config", "test=val"}, []string{"config", "test"}, "val"},
   119  		{[]string{"--annotation", "test=1"}, []string{"annotations", "test"}, 1.0},
   120  	}
   121  
   122  	for i, tcI := range validCases {
   123  		tc := tcI
   124  		t.Run(fmt.Sprintf("Valid Case %d", i), func(t *testing.T) {
   125  			t.Parallel()
   126  			h := testharness.Create(t)
   127  			defer h.Cleanup()
   128  			appName1 := h.NewAppName()
   129  			funcName1 := h.NewFuncName(appName1)
   130  			h.Fn("create", "app", appName1)
   131  			h.Fn("create", "fn", appName1, funcName1, "foo/someimage:0.0.1").AssertSuccess()
   132  
   133  			h.Fn(append([]string{"update", "fn", appName1, funcName1, "baz/fooimage:1.0.0"}, tc.args...)...).AssertSuccess()
   134  			h.Fn("inspect", "fn", appName1, funcName1).AssertSuccess().AssertStdoutContainsJSON(tc.query, tc.result)
   135  		})
   136  	}
   137  
   138  	invalidCases := [][]string{
   139  		{"--image", "fooimage:1.0.0"}, // image with no registry
   140  		//	{"--memory", "0"},  bug?
   141  		{"--memory", "wibble"},
   142  		{"--type", "blancmange"},
   143  		{"--headers", "potatocakes"},
   144  		{"--timeout", "86400"},
   145  		{"--timeout", "sit_in_the_corner"},
   146  		{"--idle-timeout", "86000"},
   147  		{"--idle-timeout", "yawn"},
   148  	}
   149  
   150  	for i, tcI := range invalidCases {
   151  		tc := tcI
   152  		t.Run(fmt.Sprintf("Invalid Case %d", i), func(t *testing.T) {
   153  			t.Parallel()
   154  			h := testharness.Create(t)
   155  			defer h.Cleanup()
   156  			appName1 := h.NewAppName()
   157  			funcName1 := h.NewFuncName(appName1)
   158  			h.Fn("create", "app", appName1)
   159  			h.Fn("create", "fn", appName1, funcName1, "foo/someimage:0.0.1").AssertSuccess()
   160  
   161  			h.Fn(append([]string{"update", "fn", appName1, funcName1}, tc...)...).AssertFailed()
   162  		})
   163  	}
   164  
   165  }
   166  
   167  func TestInspectEndpoints(t *testing.T) {
   168  
   169  	h := testharness.Create(t)
   170  	defer h.Cleanup()
   171  	appName1 := h.NewAppName()
   172  	funcName1 := h.NewFuncName(appName1)
   173  	h.Fn("create", "app", appName1)
   174  	h.Fn("create", "fn", appName1, funcName1, "foo/someimage:0.0.1").AssertSuccess()
   175  	h.Fn("create", "trigger", appName1, funcName1, "t1", "--type", "http", "--source", "/trig").AssertSuccess()
   176  
   177  	res := h.Fn("inspect", "function", appName1, funcName1, "id").AssertSuccess()
   178  	fnId := strings.Trim(strings.TrimSpace(res.Stdout), "\"")
   179  
   180  	res = h.Fn("inspect", "function", appName1, funcName1, "--endpoint").AssertSuccess()
   181  	invokeUrl := strings.TrimSpace(res.Stdout)
   182  
   183  	invokePattern := regexp.MustCompile("^http://.*/invoke/" + regexp.QuoteMeta(fnId) + "$")
   184  
   185  	if !invokePattern.MatchString(invokeUrl) {
   186  		t.Errorf("Expected invoke URL matching %s, got %s", invokePattern, invokeUrl)
   187  	}
   188  
   189  	res = h.Fn("inspect", "trigger", appName1, funcName1, "t1", "--endpoint").AssertSuccess()
   190  
   191  	triggerUrl := strings.TrimSpace(res.Stdout)
   192  	triggerPattern := regexp.MustCompile("^http://.*/t/" + regexp.QuoteMeta(appName1) + "/trig$")
   193  
   194  	if !triggerPattern.MatchString(triggerUrl) {
   195  		t.Errorf("Expected trigger URL matching %s, got %s", triggerPattern, triggerUrl)
   196  	}
   197  
   198  }