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 }