sentry-options 0.0.5__tar.gz → 0.0.7__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -31,6 +31,15 @@ version = "0.2.21"
31
31
  source = "registry+https://github.com/rust-lang/crates.io-index"
32
32
  checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923"
33
33
 
34
+ [[package]]
35
+ name = "android_system_properties"
36
+ version = "0.1.5"
37
+ source = "registry+https://github.com/rust-lang/crates.io-index"
38
+ checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311"
39
+ dependencies = [
40
+ "libc",
41
+ ]
42
+
34
43
  [[package]]
35
44
  name = "anstream"
36
45
  version = "0.6.21"
@@ -150,12 +159,33 @@ version = "1.11.0"
150
159
  source = "registry+https://github.com/rust-lang/crates.io-index"
151
160
  checksum = "b35204fbdc0b3f4446b89fc1ac2cf84a8a68971995d0bf2e925ec7cd960f9cb3"
152
161
 
162
+ [[package]]
163
+ name = "cc"
164
+ version = "1.2.52"
165
+ source = "registry+https://github.com/rust-lang/crates.io-index"
166
+ checksum = "cd4932aefd12402b36c60956a4fe0035421f544799057659ff86f923657aada3"
167
+ dependencies = [
168
+ "find-msvc-tools",
169
+ "shlex",
170
+ ]
171
+
153
172
  [[package]]
154
173
  name = "cfg-if"
155
174
  version = "1.0.4"
156
175
  source = "registry+https://github.com/rust-lang/crates.io-index"
157
176
  checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801"
158
177
 
178
+ [[package]]
179
+ name = "chrono"
180
+ version = "0.4.43"
181
+ source = "registry+https://github.com/rust-lang/crates.io-index"
182
+ checksum = "fac4744fb15ae8337dc853fee7fb3f4e48c0fbaa23d0afe49c447b4fab126118"
183
+ dependencies = [
184
+ "iana-time-zone",
185
+ "num-traits",
186
+ "windows-link",
187
+ ]
188
+
159
189
  [[package]]
160
190
  name = "clap"
161
191
  version = "4.5.53"
@@ -202,6 +232,12 @@ version = "1.0.4"
202
232
  source = "registry+https://github.com/rust-lang/crates.io-index"
203
233
  checksum = "b05b61dc5112cbb17e4b6cd61790d9845d13888356391624cbe7e41efeac1e75"
204
234
 
235
+ [[package]]
236
+ name = "core-foundation-sys"
237
+ version = "0.8.7"
238
+ source = "registry+https://github.com/rust-lang/crates.io-index"
239
+ checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b"
240
+
205
241
  [[package]]
206
242
  name = "displaydoc"
207
243
  version = "0.2.5"
@@ -240,7 +276,7 @@ dependencies = [
240
276
 
241
277
  [[package]]
242
278
  name = "example"
243
- version = "0.0.5"
279
+ version = "0.0.7"
244
280
  dependencies = [
245
281
  "anyhow",
246
282
  "sentry-options",
@@ -264,6 +300,12 @@ version = "2.3.0"
264
300
  source = "registry+https://github.com/rust-lang/crates.io-index"
265
301
  checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be"
266
302
 
303
+ [[package]]
304
+ name = "find-msvc-tools"
305
+ version = "0.1.7"
306
+ source = "registry+https://github.com/rust-lang/crates.io-index"
307
+ checksum = "f449e6c6c08c865631d4890cfacf252b3d396c9bcc83adb6623cdb02a8336c41"
308
+
267
309
  [[package]]
268
310
  name = "fluent-uri"
269
311
  version = "0.4.1"
@@ -472,6 +514,30 @@ dependencies = [
472
514
  "tracing",
473
515
  ]
474
516
 
517
+ [[package]]
518
+ name = "iana-time-zone"
519
+ version = "0.1.64"
520
+ source = "registry+https://github.com/rust-lang/crates.io-index"
521
+ checksum = "33e57f83510bb73707521ebaffa789ec8caf86f9657cad665b092b581d40e9fb"
522
+ dependencies = [
523
+ "android_system_properties",
524
+ "core-foundation-sys",
525
+ "iana-time-zone-haiku",
526
+ "js-sys",
527
+ "log",
528
+ "wasm-bindgen",
529
+ "windows-core",
530
+ ]
531
+
532
+ [[package]]
533
+ name = "iana-time-zone-haiku"
534
+ version = "0.1.2"
535
+ source = "registry+https://github.com/rust-lang/crates.io-index"
536
+ checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f"
537
+ dependencies = [
538
+ "cc",
539
+ ]
540
+
475
541
  [[package]]
476
542
  name = "icu_collections"
477
543
  version = "2.1.1"
@@ -1111,7 +1177,7 @@ checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
1111
1177
 
1112
1178
  [[package]]
1113
1179
  name = "sentry-options"
1114
- version = "0.0.5"
1180
+ version = "0.0.7"
1115
1181
  dependencies = [
1116
1182
  "sentry-options-validation",
1117
1183
  "serde_json",
@@ -1121,8 +1187,9 @@ dependencies = [
1121
1187
 
1122
1188
  [[package]]
1123
1189
  name = "sentry-options-cli"
1124
- version = "0.0.5"
1190
+ version = "0.0.7"
1125
1191
  dependencies = [
1192
+ "chrono",
1126
1193
  "clap",
1127
1194
  "sentry-options-validation",
1128
1195
  "serde",
@@ -1135,7 +1202,7 @@ dependencies = [
1135
1202
 
1136
1203
  [[package]]
1137
1204
  name = "sentry-options-python"
1138
- version = "0.0.5"
1205
+ version = "0.0.7"
1139
1206
  dependencies = [
1140
1207
  "pyo3",
1141
1208
  "sentry-options",
@@ -1144,7 +1211,7 @@ dependencies = [
1144
1211
 
1145
1212
  [[package]]
1146
1213
  name = "sentry-options-validation"
1147
- version = "0.0.5"
1214
+ version = "0.0.7"
1148
1215
  dependencies = [
1149
1216
  "anyhow",
1150
1217
  "jsonschema",
@@ -1222,6 +1289,12 @@ dependencies = [
1222
1289
  "unsafe-libyaml",
1223
1290
  ]
1224
1291
 
1292
+ [[package]]
1293
+ name = "shlex"
1294
+ version = "1.3.0"
1295
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1296
+ checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"
1297
+
1225
1298
  [[package]]
1226
1299
  name = "slab"
1227
1300
  version = "0.4.11"
@@ -1600,12 +1673,65 @@ dependencies = [
1600
1673
  "windows-sys 0.61.2",
1601
1674
  ]
1602
1675
 
1676
+ [[package]]
1677
+ name = "windows-core"
1678
+ version = "0.62.2"
1679
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1680
+ checksum = "b8e83a14d34d0623b51dce9581199302a221863196a1dde71a7663a4c2be9deb"
1681
+ dependencies = [
1682
+ "windows-implement",
1683
+ "windows-interface",
1684
+ "windows-link",
1685
+ "windows-result",
1686
+ "windows-strings",
1687
+ ]
1688
+
1689
+ [[package]]
1690
+ name = "windows-implement"
1691
+ version = "0.60.2"
1692
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1693
+ checksum = "053e2e040ab57b9dc951b72c264860db7eb3b0200ba345b4e4c3b14f67855ddf"
1694
+ dependencies = [
1695
+ "proc-macro2",
1696
+ "quote",
1697
+ "syn",
1698
+ ]
1699
+
1700
+ [[package]]
1701
+ name = "windows-interface"
1702
+ version = "0.59.3"
1703
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1704
+ checksum = "3f316c4a2570ba26bbec722032c4099d8c8bc095efccdc15688708623367e358"
1705
+ dependencies = [
1706
+ "proc-macro2",
1707
+ "quote",
1708
+ "syn",
1709
+ ]
1710
+
1603
1711
  [[package]]
1604
1712
  name = "windows-link"
1605
1713
  version = "0.2.1"
1606
1714
  source = "registry+https://github.com/rust-lang/crates.io-index"
1607
1715
  checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5"
1608
1716
 
1717
+ [[package]]
1718
+ name = "windows-result"
1719
+ version = "0.4.1"
1720
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1721
+ checksum = "7781fa89eaf60850ac3d2da7af8e5242a5ea78d1a11c49bf2910bb5a73853eb5"
1722
+ dependencies = [
1723
+ "windows-link",
1724
+ ]
1725
+
1726
+ [[package]]
1727
+ name = "windows-strings"
1728
+ version = "0.5.1"
1729
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1730
+ checksum = "7837d08f69c77cf6b07689544538e017c1bfcf57e34b4c0ff58e6c2cd3b37091"
1731
+ dependencies = [
1732
+ "windows-link",
1733
+ ]
1734
+
1609
1735
  [[package]]
1610
1736
  name = "windows-sys"
1611
1737
  version = "0.60.2"
@@ -11,13 +11,13 @@ default-members = [
11
11
  ]
12
12
 
13
13
  [workspace.package]
14
- version = "0.0.5"
14
+ version = "0.0.7"
15
15
  edition = "2024"
16
16
  repository = "https://github.com/getsentry/sentry-options"
17
17
  license = "Apache-2.0"
18
18
 
19
19
  [workspace.dependencies]
20
- sentry-options-validation = { path = "sentry-options-validation", version = "0.0.5" }
20
+ sentry-options-validation = { path = "sentry-options-validation", version = "0.0.7" }
21
21
  serde = { version = "1.0", features = ["derive"] }
22
22
  serde_json = "1.0.145"
23
23
  anyhow = "1.0.100"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: sentry_options
3
- Version: 0.0.5
3
+ Version: 0.0.7
4
4
  Classifier: Programming Language :: Python :: 3
5
5
  Classifier: Programming Language :: Python :: 3 :: Only
6
6
  Classifier: Programming Language :: Python :: Implementation :: CPython
@@ -19,7 +19,7 @@ def init_options(tmp_path_factory: pytest.TempPathFactory) -> None:
19
19
  tmpdir = tmp_path_factory.mktemp('sentry_options')
20
20
 
21
21
  # Create schema
22
- schema_dir = tmpdir / 'schemas' / 'testing'
22
+ schema_dir = tmpdir / 'schemas' / 'sentry-options-testing'
23
23
  schema_dir.mkdir(parents=True)
24
24
  (schema_dir / 'schema.json').write_text(
25
25
  json.dumps(
@@ -53,9 +53,9 @@ def init_options(tmp_path_factory: pytest.TempPathFactory) -> None:
53
53
  )
54
54
 
55
55
  # Create values (override str-opt)
56
- values_dir = tmpdir / 'values' / 'testing'
56
+ values_dir = tmpdir / 'values' / 'sentry-options-testing'
57
57
  values_dir.mkdir(parents=True)
58
- values = {'str-opt': 'custom-value'}
58
+ values = {'options': {'str-opt': 'custom-value'}}
59
59
  (values_dir / 'values.json').write_text(json.dumps(values))
60
60
 
61
61
  # Set env var and initialize
@@ -74,25 +74,25 @@ def init_options(tmp_path_factory: pytest.TempPathFactory) -> None:
74
74
 
75
75
 
76
76
  def test_get_string_from_values() -> None:
77
- value = options('testing').get('str-opt')
77
+ value = options('sentry-options-testing').get('str-opt')
78
78
  assert value == 'custom-value'
79
79
  assert isinstance(value, str)
80
80
 
81
81
 
82
82
  def test_get_int_default() -> None:
83
- value = options('testing').get('int-opt')
83
+ value = options('sentry-options-testing').get('int-opt')
84
84
  assert value == 42
85
85
  assert isinstance(value, int)
86
86
 
87
87
 
88
88
  def test_get_float_default() -> None:
89
- value = options('testing').get('float-opt')
89
+ value = options('sentry-options-testing').get('float-opt')
90
90
  assert value == 3.14
91
91
  assert isinstance(value, float)
92
92
 
93
93
 
94
94
  def test_get_bool_default() -> None:
95
- value = options('testing').get('bool-opt')
95
+ value = options('sentry-options-testing').get('bool-opt')
96
96
  assert value is True
97
97
  assert isinstance(value, bool)
98
98
 
@@ -104,7 +104,7 @@ def test_unknown_namespace() -> None:
104
104
 
105
105
  def test_unknown_option() -> None:
106
106
  with pytest.raises(UnknownOptionError, match='bad-key'):
107
- options('testing').get('bad-key')
107
+ options('sentry-options-testing').get('bad-key')
108
108
 
109
109
 
110
110
  def test_double_init() -> None:
@@ -171,7 +171,7 @@ mod tests {
171
171
  }
172
172
  }"#,
173
173
  );
174
- create_values(&values, "test", r#"{"enabled": true}"#);
174
+ create_values(&values, "test", r#"{"options": {"enabled": true}}"#);
175
175
 
176
176
  let options = Options::from_directory(temp.path()).unwrap();
177
177
  assert_eq!(options.get("test", "enabled").unwrap(), json!(true));
@@ -4,7 +4,7 @@ build-backend = "maturin"
4
4
 
5
5
  [project]
6
6
  name = "sentry_options"
7
- version = "0.0.5"
7
+ version = "0.0.7"
8
8
  description = "Python client for sentry-options using Rust validation"
9
9
  license = "Apache-2.0"
10
10
  requires-python = ">=3.11"
@@ -81,6 +81,40 @@ pub enum ValidationError {
81
81
 
82
82
  #[error("{} validation error(s)", .0.len())]
83
83
  ValidationErrors(Vec<ValidationError>),
84
+
85
+ #[error("Invalid {label} '{name}': {reason}")]
86
+ InvalidName {
87
+ label: String,
88
+ name: String,
89
+ reason: String,
90
+ },
91
+ }
92
+
93
+ /// Validate a name component is valid for K8s (lowercase alphanumeric, '-', '.')
94
+ pub fn validate_k8s_name_component(name: &str, label: &str) -> ValidationResult<()> {
95
+ if let Some(c) = name
96
+ .chars()
97
+ .find(|&c| !matches!(c, 'a'..='z' | '0'..='9' | '-' | '.'))
98
+ {
99
+ return Err(ValidationError::InvalidName {
100
+ label: label.to_string(),
101
+ name: name.to_string(),
102
+ reason: format!(
103
+ "character '{}' not allowed. Use lowercase alphanumeric, '-', or '.'",
104
+ c
105
+ ),
106
+ });
107
+ }
108
+ if !name.starts_with(|c: char| c.is_ascii_alphanumeric())
109
+ || !name.ends_with(|c: char| c.is_ascii_alphanumeric())
110
+ {
111
+ return Err(ValidationError::InvalidName {
112
+ label: label.to_string(),
113
+ name: name.to_string(),
114
+ reason: "must start and end with alphanumeric".to_string(),
115
+ });
116
+ }
117
+ Ok(())
84
118
  }
85
119
 
86
120
  /// Metadata for a single option in a namespace schema
@@ -202,6 +236,8 @@ impl SchemaRegistry {
202
236
  message: "Directory name contains invalid UTF-8".to_string(),
203
237
  })?;
204
238
 
239
+ validate_k8s_name_component(&namespace, "namespace name")?;
240
+
205
241
  let schema_file = entry.path().join(SCHEMA_FILE_NAME);
206
242
  let schema = Self::load_schema(&schema_file, &namespace, &namespace_validator)?;
207
243
  schemas.insert(namespace, schema);
@@ -329,6 +365,7 @@ impl SchemaRegistry {
329
365
 
330
366
  /// Load and validate JSON values from a directory.
331
367
  /// Expects structure: `{values_dir}/{namespace}/values.json`
368
+ /// Values file must have format: `{"options": {"key": value, ...}}`
332
369
  /// Skips namespaces without a values.json file.
333
370
  pub fn load_values_json(&self, values_dir: &Path) -> ValidationResult<ValuesByNamespace> {
334
371
  let mut all_values = HashMap::new();
@@ -340,10 +377,18 @@ impl SchemaRegistry {
340
377
  continue;
341
378
  }
342
379
 
343
- let values: Value = serde_json::from_reader(fs::File::open(&values_file)?)?;
344
- self.validate_values(namespace, &values)?;
380
+ let parsed: Value = serde_json::from_reader(fs::File::open(&values_file)?)?;
381
+
382
+ let values = parsed
383
+ .get("options")
384
+ .ok_or_else(|| ValidationError::ValueError {
385
+ namespace: namespace.clone(),
386
+ errors: "values.json must have an 'options' key".to_string(),
387
+ })?;
388
+
389
+ self.validate_values(namespace, values)?;
345
390
 
346
- if let Value::Object(obj) = values {
391
+ if let Value::Object(obj) = values.clone() {
347
392
  let ns_values: HashMap<String, Value> = obj.into_iter().collect();
348
393
  all_values.insert(namespace.clone(), ns_values);
349
394
  }
@@ -535,6 +580,52 @@ mod tests {
535
580
  schema_file
536
581
  }
537
582
 
583
+ #[test]
584
+ fn test_validate_k8s_name_component_valid() {
585
+ assert!(validate_k8s_name_component("relay", "namespace").is_ok());
586
+ assert!(validate_k8s_name_component("my-service", "namespace").is_ok());
587
+ assert!(validate_k8s_name_component("my.service", "namespace").is_ok());
588
+ assert!(validate_k8s_name_component("a1-b2.c3", "namespace").is_ok());
589
+ }
590
+
591
+ #[test]
592
+ fn test_validate_k8s_name_component_rejects_uppercase() {
593
+ let result = validate_k8s_name_component("MyService", "namespace");
594
+ assert!(matches!(result, Err(ValidationError::InvalidName { .. })));
595
+ assert!(result.unwrap_err().to_string().contains("'M' not allowed"));
596
+ }
597
+
598
+ #[test]
599
+ fn test_validate_k8s_name_component_rejects_underscore() {
600
+ let result = validate_k8s_name_component("my_service", "target");
601
+ assert!(matches!(result, Err(ValidationError::InvalidName { .. })));
602
+ assert!(result.unwrap_err().to_string().contains("'_' not allowed"));
603
+ }
604
+
605
+ #[test]
606
+ fn test_validate_k8s_name_component_rejects_leading_hyphen() {
607
+ let result = validate_k8s_name_component("-service", "namespace");
608
+ assert!(matches!(result, Err(ValidationError::InvalidName { .. })));
609
+ assert!(
610
+ result
611
+ .unwrap_err()
612
+ .to_string()
613
+ .contains("start and end with alphanumeric")
614
+ );
615
+ }
616
+
617
+ #[test]
618
+ fn test_validate_k8s_name_component_rejects_trailing_dot() {
619
+ let result = validate_k8s_name_component("service.", "namespace");
620
+ assert!(matches!(result, Err(ValidationError::InvalidName { .. })));
621
+ assert!(
622
+ result
623
+ .unwrap_err()
624
+ .to_string()
625
+ .contains("start and end with alphanumeric")
626
+ );
627
+ }
628
+
538
629
  #[test]
539
630
  fn test_load_schema_valid() {
540
631
  let temp_dir = TempDir::new().unwrap();
@@ -724,7 +815,7 @@ Error: \"version\" is a required property"
724
815
  fn test_invalid_directory_structure() {
725
816
  let temp_dir = TempDir::new().unwrap();
726
817
  // Create a namespace directory without schema.json file
727
- let schema_dir = temp_dir.path().join("missing_schema");
818
+ let schema_dir = temp_dir.path().join("missing-schema");
728
819
  fs::create_dir_all(&schema_dir).unwrap();
729
820
 
730
821
  let result = SchemaRegistry::from_directory(temp_dir.path());
@@ -897,10 +988,12 @@ Error: \"version\" is a required property"
897
988
  fs::write(
898
989
  test_values_dir.join("values.json"),
899
990
  r#"{
900
- "enabled": true,
901
- "name": "test-name",
902
- "count": 42,
903
- "rate": 0.75
991
+ "options": {
992
+ "enabled": true,
993
+ "name": "test-name",
994
+ "count": 42,
995
+ "rate": 0.75
996
+ }
904
997
  }"#,
905
998
  )
906
999
  .unwrap();
@@ -940,7 +1033,7 @@ Error: \"version\" is a required property"
940
1033
  let values_dir = temp_dir.path().join("values");
941
1034
 
942
1035
  // Create two schemas
943
- let schema_dir1 = schemas_dir.join("with_values");
1036
+ let schema_dir1 = schemas_dir.join("with-values");
944
1037
  fs::create_dir_all(&schema_dir1).unwrap();
945
1038
  fs::write(
946
1039
  schema_dir1.join("schema.json"),
@@ -954,7 +1047,7 @@ Error: \"version\" is a required property"
954
1047
  )
955
1048
  .unwrap();
956
1049
 
957
- let schema_dir2 = schemas_dir.join("without_values");
1050
+ let schema_dir2 = schemas_dir.join("without-values");
958
1051
  fs::create_dir_all(&schema_dir2).unwrap();
959
1052
  fs::write(
960
1053
  schema_dir2.join("schema.json"),
@@ -969,16 +1062,20 @@ Error: \"version\" is a required property"
969
1062
  .unwrap();
970
1063
 
971
1064
  // Only create values for one namespace
972
- let with_values_dir = values_dir.join("with_values");
1065
+ let with_values_dir = values_dir.join("with-values");
973
1066
  fs::create_dir_all(&with_values_dir).unwrap();
974
- fs::write(with_values_dir.join("values.json"), r#"{"opt": "y"}"#).unwrap();
1067
+ fs::write(
1068
+ with_values_dir.join("values.json"),
1069
+ r#"{"options": {"opt": "y"}}"#,
1070
+ )
1071
+ .unwrap();
975
1072
 
976
1073
  let registry = SchemaRegistry::from_directory(&schemas_dir).unwrap();
977
1074
  let values = registry.load_values_json(&values_dir).unwrap();
978
1075
 
979
1076
  assert_eq!(values.len(), 1);
980
- assert!(values.contains_key("with_values"));
981
- assert!(!values.contains_key("without_values"));
1077
+ assert!(values.contains_key("with-values"));
1078
+ assert!(!values.contains_key("without-values"));
982
1079
  }
983
1080
 
984
1081
  #[test]
@@ -1005,7 +1102,7 @@ Error: \"version\" is a required property"
1005
1102
  fs::create_dir_all(&test_values_dir).unwrap();
1006
1103
  fs::write(
1007
1104
  test_values_dir.join("values.json"),
1008
- r#"{"count": "not-a-number"}"#,
1105
+ r#"{"options": {"count": "not-a-number"}}"#,
1009
1106
  )
1010
1107
  .unwrap();
1011
1108
 
@@ -1041,7 +1138,11 @@ Error: \"version\" is a required property"
1041
1138
 
1042
1139
  let ns1_values = values_dir.join("ns1");
1043
1140
  fs::create_dir_all(&ns1_values).unwrap();
1044
- fs::write(ns1_values.join("values.json"), r#"{"enabled": true}"#).unwrap();
1141
+ fs::write(
1142
+ ns1_values.join("values.json"),
1143
+ r#"{"options": {"enabled": true}}"#,
1144
+ )
1145
+ .unwrap();
1045
1146
 
1046
1147
  let ns2_schema = schemas_dir.join("ns2");
1047
1148
  fs::create_dir_all(&ns2_schema).unwrap();
@@ -1059,7 +1160,11 @@ Error: \"version\" is a required property"
1059
1160
 
1060
1161
  let ns2_values = values_dir.join("ns2");
1061
1162
  fs::create_dir_all(&ns2_values).unwrap();
1062
- fs::write(ns2_values.join("values.json"), r#"{"count": 42}"#).unwrap();
1163
+ fs::write(
1164
+ ns2_values.join("values.json"),
1165
+ r#"{"options": {"count": 42}}"#,
1166
+ )
1167
+ .unwrap();
1063
1168
 
1064
1169
  (temp_dir, schemas_dir, values_dir)
1065
1170
  }
@@ -1076,7 +1181,7 @@ Error: \"version\" is a required property"
1076
1181
  thread::sleep(std::time::Duration::from_millis(10));
1077
1182
  fs::write(
1078
1183
  values_dir.join("ns1").join("values.json"),
1079
- r#"{"enabled": false}"#,
1184
+ r#"{"options": {"enabled": false}}"#,
1080
1185
  )
1081
1186
  .unwrap();
1082
1187
 
@@ -1113,12 +1218,12 @@ Error: \"version\" is a required property"
1113
1218
  // modify
1114
1219
  fs::write(
1115
1220
  values_dir.join("ns1").join("values.json"),
1116
- r#"{"enabled": false}"#,
1221
+ r#"{"options": {"enabled": false}}"#,
1117
1222
  )
1118
1223
  .unwrap();
1119
1224
  fs::write(
1120
1225
  values_dir.join("ns2").join("values.json"),
1121
- r#"{"count": 100}"#,
1226
+ r#"{"options": {"count": 100}}"#,
1122
1227
  )
1123
1228
  .unwrap();
1124
1229
 
@@ -1149,7 +1254,7 @@ Error: \"version\" is a required property"
1149
1254
  // won't pass validation
1150
1255
  fs::write(
1151
1256
  values_dir.join("ns1").join("values.json"),
1152
- r#"{"enabled": "not-a-boolean"}"#,
1257
+ r#"{"options": {"enabled": "not-a-boolean"}}"#,
1153
1258
  )
1154
1259
  .unwrap();
1155
1260