github.com/webonyx/up@v0.7.4-0.20180808230834-91b94e551323/platform/lambda/stack/resources/warming_test.go (about) 1 package resources 2 3 import ( 4 "encoding/json" 5 "strings" 6 "testing" 7 8 "github.com/apex/up/config" 9 "github.com/tj/assert" 10 ) 11 12 func parse(s string) *Config { 13 return &Config{ 14 Config: config.MustParseConfigString(s), 15 Versions: Versions{ 16 "beta": "1", 17 "staging": "1", 18 "production": "1", 19 }, 20 } 21 } 22 23 func assertJSON(t testing.TB, expected string, actual interface{}) { 24 t.Helper() 25 b, err := json.MarshalIndent(actual, "", " ") 26 assert.NoError(t, err, "marshal") 27 s := string(b) 28 if expected != s { 29 t.Fatalf("expected:\n\n%s\n\ngot:\n\n%s\n\n", expected, s) 30 } 31 } 32 33 var functionJSON = `{ 34 "Properties": { 35 "Code": { 36 "ZipFile": "\nconst http = require('https')\n\nexports.handle = function(e, ctx, fn) {\n const start = Date.now()\n let pending = e.count\n console.log('requesting %d', e.count)\n\n for (let i = 0; i \u003c e.count; i++) {\n console.log('GET %s', e.url)\n http.get(e.url, function (res) {\n const d = Date.now() - start\n console.log('GET %s -\u003e %s (%dms)', e.url, res.statusCode, d)\n --pending || fn()\n })\n }\n}" 37 }, 38 "Description": "Warming function (Managed by Up).", 39 "FunctionName": "polls-warming", 40 "Handler": "index.handle", 41 "MemorySize": 512, 42 "Role": { 43 "Fn::GetAtt": [ 44 "WarmingFunctionRole", 45 "Arn" 46 ] 47 }, 48 "Runtime": "nodejs6.10", 49 "Timeout": 300 50 }, 51 "Type": "AWS::Lambda::Function" 52 }` 53 54 var roleJSON = `{ 55 "Properties": { 56 "AssumeRolePolicyDocument": { 57 "Statement": [ 58 { 59 "Action": [ 60 "sts:AssumeRole" 61 ], 62 "Effect": "Allow", 63 "Principal": { 64 "Service": [ 65 "lambda.amazonaws.com" 66 ] 67 } 68 } 69 ], 70 "Version": "2012-10-17" 71 }, 72 "Path": "/", 73 "Policies": [ 74 { 75 "PolicyDocument": { 76 "Statement": [ 77 { 78 "Action": [ 79 "logs:*" 80 ], 81 "Effect": "Allow", 82 "Resource": "arn:aws:logs:*:*:*" 83 } 84 ], 85 "Version": "2012-10-17" 86 }, 87 "PolicyName": "root" 88 } 89 ], 90 "RoleName": "polls-warming-function" 91 }, 92 "Type": "AWS::IAM::Role" 93 }` 94 95 var eventJSON = `{ 96 "Properties": { 97 "Description": "Warming function scheduled event (Managed by Up).", 98 "ScheduleExpression": "rate(15 minutes)", 99 "State": "ENABLED", 100 "Targets": [ 101 { 102 "Arn": { 103 "Fn::GetAtt": [ 104 "WarmingFunction", 105 "Arn" 106 ] 107 }, 108 "Id": "WarmingFunction", 109 "Input": { 110 "Fn::Join": [ 111 "", 112 [ 113 "{ \"url\": \"", 114 { 115 "Fn::Join": [ 116 "", 117 [ 118 "https://", 119 { 120 "Ref": "Api" 121 }, 122 ".execute-api.", 123 { 124 "Ref": "AWS::Region" 125 }, 126 ".amazonaws.com", 127 "/production/_ping" 128 ] 129 ] 130 }, 131 "\", \"count\": 15 }" 132 ] 133 ] 134 } 135 } 136 ] 137 }, 138 "Type": "AWS::Events::Rule" 139 }` 140 141 var permissionJSON = `{ 142 "Properties": { 143 "Action": "lambda:InvokeFunction", 144 "FunctionName": { 145 "Ref": "WarmingFunction" 146 }, 147 "Principal": "events.amazonaws.com", 148 "SourceArn": { 149 "Fn::GetAtt": [ 150 "WarmingEventProduction", 151 "Arn" 152 ] 153 } 154 }, 155 "Type": "AWS::Lambda::Permission" 156 }` 157 158 func TestWarming_none(t *testing.T) { 159 c := parse(`{ 160 "name": "polls" 161 }`) 162 163 assert.Nil(t, getResource(c, "WarmingFunction")) 164 assert.Nil(t, getResource(c, "WarmingFunctionRole")) 165 } 166 167 func TestWarming_globalDefaults(t *testing.T) { 168 c := parse(`{ 169 "name": "polls", 170 "lambda": { 171 "warm": true 172 } 173 }`) 174 175 assertJSON(t, functionJSON, getResource(c, "WarmingFunction")) 176 assertJSON(t, roleJSON, getResource(c, "WarmingFunctionRole")) 177 178 assertJSON(t, strings.Replace(eventJSON, "production", "staging", 1), getResource(c, "WarmingEventStaging")) 179 assertJSON(t, eventJSON, getResource(c, "WarmingEventProduction")) 180 181 assertJSON(t, strings.Replace(permissionJSON, "Production", "Staging", 1), getResource(c, "WarmingFunctionPermissionStaging")) 182 assertJSON(t, permissionJSON, getResource(c, "WarmingFunctionPermissionProduction")) 183 } 184 185 func TestWarming_globalValues(t *testing.T) { 186 c := parse(`{ 187 "name": "polls", 188 "lambda": { 189 "warm": true, 190 "warm_count": 60, 191 "warm_rate": "5m" 192 }, 193 "stages": { 194 "beta": {} 195 } 196 }`) 197 198 assertJSON(t, functionJSON, getResource(c, "WarmingFunction")) 199 assertJSON(t, roleJSON, getResource(c, "WarmingFunctionRole")) 200 201 e := strings.Replace(eventJSON, ": 15", ": 60", 1) 202 e = strings.Replace(e, "rate(15 minutes)", "rate(5 minutes)", 1) 203 204 assertJSON(t, strings.Replace(e, "production", "staging", 1), getResource(c, "WarmingEventStaging")) 205 assertJSON(t, strings.Replace(e, "production", "beta", 1), getResource(c, "WarmingEventBeta")) 206 assertJSON(t, e, getResource(c, "WarmingEventProduction")) 207 208 assertJSON(t, strings.Replace(permissionJSON, "Production", "Staging", 1), getResource(c, "WarmingFunctionPermissionStaging")) 209 assertJSON(t, strings.Replace(permissionJSON, "Production", "Beta", 1), getResource(c, "WarmingFunctionPermissionBeta")) 210 assertJSON(t, permissionJSON, getResource(c, "WarmingFunctionPermissionProduction")) 211 } 212 213 func TestWarming_globalValuesWithOverrides(t *testing.T) { 214 c := parse(`{ 215 "name": "polls", 216 "lambda": { 217 "warm": true, 218 "warm_count": 60, 219 "warm_rate": "5m" 220 }, 221 "stages": { 222 "beta": { 223 "lambda": { 224 "warm": false 225 } 226 }, 227 "production": { 228 "lambda": { 229 "warm_count": 100, 230 "warm_rate": "10m" 231 } 232 } 233 } 234 }`) 235 236 // TODO: test for warm count override 237 // TODO: test for warm rate override 238 // TODO: it is a pointer problem... 239 240 assertJSON(t, functionJSON, getResource(c, "WarmingFunction")) 241 assertJSON(t, roleJSON, getResource(c, "WarmingFunctionRole")) 242 assert.Nil(t, getResource(c, "WarmingEventBeta"), "beta disabled") 243 244 prod := strings.Replace(eventJSON, ": 15", ": 100", 1) 245 prod = strings.Replace(prod, "rate(15 minutes)", "rate(10 minutes)", 1) 246 assertJSON(t, prod, getResource(c, "WarmingEventProduction")) 247 248 stage := strings.Replace(eventJSON, ": 15", ": 60", 1) 249 stage = strings.Replace(stage, "rate(15 minutes)", "rate(5 minutes)", 1) 250 stage = strings.Replace(stage, "production", "staging", 1) 251 assertJSON(t, stage, getResource(c, "WarmingEventStaging")) 252 253 assertJSON(t, strings.Replace(permissionJSON, "Production", "Staging", 1), getResource(c, "WarmingFunctionPermissionStaging")) 254 assert.Nil(t, getResource(c, "WarmingFunctionPermissionBeta"), "beta disabled") 255 assertJSON(t, permissionJSON, getResource(c, "WarmingFunctionPermissionProduction")) 256 }