diff --git a/lib/config-gen/tests/wasm.rs b/lib/config-gen/tests/wasm.rs index f7c48866..88b133d6 100644 --- a/lib/config-gen/tests/wasm.rs +++ b/lib/config-gen/tests/wasm.rs @@ -90,9 +90,63 @@ loggers: #[wasm_bindgen_test] fn other_test() { - let json_str = "{\"vars\":{\"rampTime\":\"${e:RAMP_TIME}\",\"loadTime\":\"${e:LOAD_TIME}\",\"peakLoad\":\"${e:PEAK_LOAD}\",\"sessionId\":\"${e:SESSIONID}\"},\"config\":{\"client\":{\"headers\":{\"User-Agent\":\"Pewpew Performance Load Test\"}},\"general\":{\"bucket_size\":\"1m\",\"log_provider_stats\":true}},\"load_pattern\":[{\"linear\":{\"from\":\"10%\",\"to\":\"100%\",\"over\":\"15m\"}},{\"linear\":{\"from\":\"100%\",\"to\":\"100%\",\"over\":\"15m\"}}],\"loggers\":{\"httpErrors\":{\"query\":{\"select\":{\"timestamp\":\"epoch(\\\"ms\\\")\",\"rtt\":\"stats.rtt\",\"request\":\"request[\\\"start-line\\\"]\",\"requestHeaders\":\"request.headers\",\"requestBody\":\"request.body\",\"response\":\"response[\\\"start-line\\\"]\",\"status\":\"response.status\",\"responseHeaders\":\"response.headers\"},\"where\":\"response.status >= 400\"},\"to\":\"stderr\",\"limit\":200},\"testEnd\":{\"query\":{\"select\":{\"timestamp\":\"epoch(\\\"ms\\\")\",\"status\":\"response.status\",\"request\":\"request[\\\"start-line\\\"]\",\"response\":\"response[\\\"start-line\\\"]\"},\"where\":\"response.status >= 500\"},\"to\":\"stderr\",\"limit\":50,\"kill\":true}}}"; - let _lt: LoadTest = serde_json::from_str(json_str).unwrap(); - let yaml = load_test_yaml_from_js(json_str, None) + let json = json!({ + "vars":{ + "rampTime":"${e:RAMP_TIME}", + "loadTime":"${e:LOAD_TIME}", + "peakLoad":"${e:PEAK_LOAD}", + "sessionId":"${e:SESSIONID}"}, + "config":{ + "client":{"headers":{"User-Agent":"Pewpew Performance Load Test"}}, + "general":{"bucket_size":"1m","log_provider_stats":true} + }, + "load_pattern":[ + {"linear":{"from":"10%","to":"100%","over":"15m"}}, + {"linear":{"from":"100%","to":"100%","over":"15m"}} + ], + "endpoints": [ + { + "url": "localhost", + "peak_load": "1.1hps" + } + ], + "loggers":{ + "httpErrors":{ + "query":{ + "select":{ + "timestamp":"epoch(\"ms\")", + "rtt":"stats.rtt","request": + "request[\"start-line\"]", + "requestHeaders":"request.headers", + "requestBody":"request.body", + "response":"response[\"start-line\"]", + "status":"response.status", + "responseHeaders":"response.headers" + }, + "where":"response.status >= 400" + }, + "to":"stderr", + "limit":200 + }, + "testEnd":{ + "query":{ + "select":{ + "timestamp":"epoch(\"ms\")", + "status":"response.status", + "request":"request[\"start-line\"]", + "response":"response[\"start-line\"]" + }, + "where":"response.status >= 500" + }, + "to":"stderr", + "limit":50, + "kill":true + } + } + }); + let json_str = serde_json::to_string(&json).unwrap(); + let _lt: LoadTest = serde_json::from_str(&json_str).unwrap(); + let yaml = load_test_yaml_from_js(&json_str, None) .map_err(JsValue::from) .unwrap(); diff --git a/lib/config-wasm/tests/test.js b/lib/config-wasm/tests/test.js index 9a069ca3..714e817d 100644 --- a/lib/config-wasm/tests/test.js +++ b/lib/config-wasm/tests/test.js @@ -277,7 +277,7 @@ const suite = describe("config-wasm", () => { config.checkOk(); done(new Error("empty.yaml should have failed")); } catch (error) { - expect(`${error}`).to.include("YamlDeserialize"); + expect(`${error}`).to.include("YamlParse"); done(); } }); @@ -288,7 +288,7 @@ const suite = describe("config-wasm", () => { config.checkOk(); done(new Error("bad.yaml should have failed")); } catch (error) { - expect(`${error}`).to.include("UnrecognizedKey"); + expect(`${error}`).to.include("YamlParse"); done(); } }); @@ -299,7 +299,7 @@ const suite = describe("config-wasm", () => { config.checkOk(); done(new Error("file.json should have failed")); } catch (error) { - expect(`${error}`).to.include("UnrecognizedKey"); + expect(`${error}`).to.include("YamlParse"); done(); } }); @@ -313,6 +313,7 @@ const suite = describe("config-wasm", () => { done(new Error("empty.yaml should have failed")); } catch (error) { expect(`${error}`).to.include("YamlDeserialize"); + expect(`${error}`).to.include("YamlParse"); done(); } }); @@ -324,6 +325,7 @@ const suite = describe("config-wasm", () => { done(new Error("bad.yaml should have failed")); } catch (error) { expect(`${error}`).to.include("UnrecognizedKey"); + expect(`${error}`).to.include("YamlParse"); done(); } }); @@ -335,6 +337,7 @@ const suite = describe("config-wasm", () => { done(new Error("file.json should have failed")); } catch (error) { expect(`${error}`).to.include("UnrecognizedKey"); + expect(`${error}`).to.include("YamlParse"); done(); } }); diff --git a/lib/config/src/configv2/error.rs b/lib/config/src/configv2/error.rs index 9282aa85..2f80650b 100644 --- a/lib/config/src/configv2/error.rs +++ b/lib/config/src/configv2/error.rs @@ -12,6 +12,8 @@ pub enum LoadTestGenError { VarsError(#[from] VarsError), #[error("error loading external js: {0}")] LibLoad(#[from] Arc), + #[error("endpoints are required")] + NoEndpoints(), // Used by the config-wasm when only passing back a V1 error #[error("error {0}")] OtherErr(String), diff --git a/lib/config/src/configv2/mod.rs b/lib/config/src/configv2/mod.rs index 47ee1553..2102c225 100644 --- a/lib/config/src/configv2/mod.rs +++ b/lib/config/src/configv2/mod.rs @@ -48,7 +48,7 @@ pub struct LoadTest { pub loggers: BTreeMap, Logger>, #[serde(default = "BTreeMap::new")] pub providers: BTreeMap>, - #[serde(default = "Vec::new")] + #[serde()] // Don't have a default here pub endpoints: Vec>, /// Tracks errors that would prevent a full Load Test #[serde(skip)] @@ -166,6 +166,7 @@ impl LoadTest { file_path: Arc, env_vars: &BTreeMap, ) -> Result { + use LoadTestGenError::NoEndpoints; // TODO: Why isn't this causing errors on empty let mut pre_envs: LoadTest = serde_yaml::from_str(yaml)?; log::debug!("from_yaml pre_envs: {:?}", pre_envs); @@ -193,6 +194,10 @@ impl LoadTest { let lp = <.load_pattern; let ep = &mut lt.endpoints; let headers = <.config.client.headers; + // Check for no endpoints + if ep.is_empty() { + return Err(NoEndpoints()); + } ep.iter_mut().enumerate().for_each(|(id, endpoint)| { endpoint.insert_load_pattern(lp.as_ref()); endpoint.insert_special_tags(id); @@ -466,7 +471,27 @@ mod tests { } #[test] - fn basic() { + fn empty() { + let input = r#" + "#; + let err = LoadTest::from_yaml(input, empty_path(), &BTreeMap::new()).unwrap_err(); + assert!(matches!(err, LoadTestGenError::YamlParse(_))); + assert!(format!("{:?}", err).contains("missing field `endpoints`")); + } + + #[test] + fn basic_no_endpoints() { + let input = r#" + config: + client: {} + general: {} + providers: {} + loggers: {} + vars: {} + "#; + let err = LoadTest::from_yaml(input, empty_path(), &BTreeMap::new()).unwrap_err(); + assert!(matches!(err, LoadTestGenError::YamlParse(_))); + assert!(format!("{:?}", err).contains("missing field `endpoints`")); let input = r#" config: client: {} @@ -476,6 +501,28 @@ mod tests { loggers: {} vars: {} "#; + let err = LoadTest::from_yaml(input, empty_path(), &BTreeMap::new()).unwrap_err(); + assert!(matches!(err, LoadTestGenError::NoEndpoints())); + } + + #[test] + fn basic() { + let input = r#" + config: + client: {} + general: {} + providers: {} + load_pattern: + - !linear + to: 50% + over: 1m + endpoints: + - method: GET + url: localhost:8000 + peak_load: 4hps + loggers: {} + vars: {} + "#; let lt = LoadTest::from_yaml(input, empty_path(), &BTreeMap::new()).unwrap(); lt.ok_for_loadtest().unwrap(); } @@ -604,7 +651,10 @@ mod tests { fn get_test_duration() { use std::time::Duration; let input = r#" - endpoints: [] + endpoints: + - method: GET + url: localhost:8000 + peak_load: 4hps loggers: {} vars: {} load_pattern: [] @@ -612,7 +662,10 @@ mod tests { let lt = LoadTest::from_yaml(input, empty_path(), &BTreeMap::new()).unwrap(); assert_eq!(lt.get_duration(), Duration::default()); let input = r#" - endpoints: [] + endpoints: + - method: GET + url: localhost:8000 + peak_load: 4hps loggers: {} vars: {} load_pattern: @@ -622,7 +675,7 @@ mod tests { over: 12h "#; let lt = LoadTest::from_yaml(input, empty_path(), &BTreeMap::new()).unwrap(); - assert_eq!(lt.get_duration(), Duration::default()); + assert_eq!(lt.get_duration(), Duration::from_secs(12 * 60 * 60)); let input = r#" endpoints: - url: localhost:8080 @@ -670,6 +723,10 @@ mod tests { - !linear to: '${x:inline2(${v:from_custom})}%' over: 1s + endpoints: + - method: GET + url: localhost:8000 + peak_load: 4hps "#; let lt = LoadTest::from_yaml(input, empty_path(), &BTreeMap::new()).unwrap(); let lp0 = lt.load_pattern.unwrap().into_iter().next().unwrap(); @@ -685,6 +742,10 @@ mod tests { - !linear to: '${x:foo_custom(${v:foo})}%' over: 1s + endpoints: + - method: GET + url: localhost:8000 + peak_load: 4hps "#; let lt = LoadTest::from_yaml(input, empty_path(), &BTreeMap::new()).unwrap(); let lp0 = lt.load_pattern.unwrap().into_iter().next().unwrap();