Skip to content

Commit

Permalink
Updated code to not support empty yaml file
Browse files Browse the repository at this point in the history
- Changed the functionality to mirror the old code that would fail on an emtpy file
- Removed the default empty endpoints array in the yaml parse
- Added a new error if an empty endpoints section is provided
- Updated tests to support changes
  • Loading branch information
tkmcmaster committed Sep 7, 2023
1 parent 1dd35b2 commit f4552d1
Show file tree
Hide file tree
Showing 4 changed files with 131 additions and 11 deletions.
60 changes: 57 additions & 3 deletions lib/config-gen/tests/wasm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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();

Expand Down
9 changes: 6 additions & 3 deletions lib/config-wasm/tests/test.js
Original file line number Diff line number Diff line change
Expand Up @@ -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();
}
});
Expand All @@ -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();
}
});
Expand All @@ -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();
}
});
Expand All @@ -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();
}
});
Expand All @@ -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();
}
});
Expand All @@ -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();
}
});
Expand Down
2 changes: 2 additions & 0 deletions lib/config/src/configv2/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ pub enum LoadTestGenError {
VarsError(#[from] VarsError),
#[error("error loading external js: {0}")]
LibLoad(#[from] Arc<io::Error>),
#[error("endpoints are required")]
NoEndpoints(),
// Used by the config-wasm when only passing back a V1 error
#[error("error {0}")]
OtherErr(String),
Expand Down
71 changes: 66 additions & 5 deletions lib/config/src/configv2/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ pub struct LoadTest<VD: Bool = True, ED: Bool = True> {
pub loggers: BTreeMap<Arc<str>, Logger<VD>>,
#[serde(default = "BTreeMap::new")]
pub providers: BTreeMap<ProviderName, ProviderType<VD>>,
#[serde(default = "Vec::new")]
#[serde()] // Don't have a default here
pub endpoints: Vec<Endpoint<VD>>,
/// Tracks errors that would prevent a full Load Test
#[serde(skip)]
Expand Down Expand Up @@ -166,6 +166,7 @@ impl LoadTest<True, True> {
file_path: Arc<Path>,
env_vars: &BTreeMap<String, String>,
) -> Result<Self, LoadTestGenError> {
use LoadTestGenError::NoEndpoints;
// TODO: Why isn't this causing errors on empty
let mut pre_envs: LoadTest<False, False> = serde_yaml::from_str(yaml)?;
log::debug!("from_yaml pre_envs: {:?}", pre_envs);
Expand Down Expand Up @@ -193,6 +194,10 @@ impl LoadTest<True, True> {
let lp = &lt.load_pattern;
let ep = &mut lt.endpoints;
let headers = &lt.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);
Expand Down Expand Up @@ -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: {}
Expand All @@ -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();
}
Expand Down Expand Up @@ -604,15 +651,21 @@ 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: []
"#;
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:
Expand All @@ -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
Expand Down Expand Up @@ -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();
Expand All @@ -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();
Expand Down

0 comments on commit f4552d1

Please sign in to comment.