Skip to content

Commit 3271f0b

Browse files
authored
refactor: add helper methods to trait LicenseManager (#17761)
* refactor: add help methods to LicenseManager - `is_license_valid` - `check_license` * tweak comments * refactor: log message when license expired * tweak log level * Use cache while parsing license * ut for RealLicenseManager::parse_license * cleanup * more ut * tweak unit test
1 parent dc44454 commit 3271f0b

File tree

3 files changed

+323
-22
lines changed

3 files changed

+323
-22
lines changed

src/common/license/src/license.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -175,7 +175,7 @@ impl Feature {
175175
}
176176
}
177177

178-
#[derive(Serialize, Deserialize)]
178+
#[derive(Serialize, Deserialize, Clone)]
179179
pub struct LicenseInfo {
180180
#[serde(rename = "type")]
181181
pub r#type: Option<String>,

src/common/license/src/license_manager.rs

Lines changed: 118 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,9 +52,17 @@ pub trait LicenseManager: Sync + Send {
5252
/// # Errors
5353
///
5454
/// This function may return `LicenseKeyParseError` error if the encoding or decoding of the JWT fails.
55-
/// ```
5655
fn parse_license(&self, raw: &str) -> Result<JWTClaims<LicenseInfo>>;
5756

57+
fn is_license_valid(&self, license_key: String) -> bool {
58+
self.check_license(license_key).is_ok()
59+
}
60+
61+
fn check_license(&self, license_key: String) -> Result<()> {
62+
self.parse_license(&license_key)?;
63+
Ok(())
64+
}
65+
5866
/// Get the storage quota from license key.
5967
fn get_storage_quota(&self, license_key: String) -> Result<StorageQuota>;
6068
}
@@ -110,3 +118,112 @@ impl LicenseManager for OssLicenseManager {
110118
Ok(StorageQuota::default())
111119
}
112120
}
121+
122+
#[cfg(test)]
123+
mod tests {
124+
use std::sync::Arc;
125+
126+
use databend_common_exception::ErrorCode;
127+
use databend_common_exception::Result;
128+
129+
use super::*;
130+
131+
// A mock LicenseManager implementation for testing
132+
struct MockLicenseManager {
133+
license_claim: Result<JWTClaims<LicenseInfo>>,
134+
}
135+
136+
struct MockLicenseManagerBuilder;
137+
impl MockLicenseManagerBuilder {
138+
fn invalid() -> MockLicenseManager {
139+
MockLicenseManager {
140+
license_claim: Err(ErrorCode::LicenceDenied("")),
141+
}
142+
}
143+
144+
fn valid_but_expired() -> MockLicenseManager {
145+
MockLicenseManager {
146+
license_claim: Err(ErrorCode::LicenseKeyExpired("")),
147+
}
148+
}
149+
150+
fn valid_and_active() -> MockLicenseManager {
151+
let claim = new_license_claim();
152+
MockLicenseManager {
153+
license_claim: Ok(claim),
154+
}
155+
}
156+
}
157+
158+
fn new_license_claim() -> JWTClaims<LicenseInfo> {
159+
JWTClaims {
160+
issued_at: None,
161+
expires_at: None,
162+
invalid_before: None,
163+
issuer: None,
164+
subject: None,
165+
audiences: None,
166+
jwt_id: None,
167+
nonce: None,
168+
custom: LicenseInfo {
169+
r#type: None,
170+
org: None,
171+
tenants: None,
172+
features: None,
173+
},
174+
}
175+
}
176+
177+
impl LicenseManager for MockLicenseManager {
178+
fn init(_tenant: String) -> Result<()> {
179+
unimplemented!()
180+
}
181+
182+
fn instance() -> Arc<Box<dyn LicenseManager>> {
183+
unimplemented!()
184+
}
185+
186+
fn check_enterprise_enabled(&self, _license_key: String, _feature: Feature) -> Result<()> {
187+
unimplemented!()
188+
}
189+
190+
fn parse_license(&self, _raw: &str) -> Result<JWTClaims<LicenseInfo>> {
191+
self.license_claim.clone()
192+
}
193+
194+
fn get_storage_quota(&self, _license_key: String) -> Result<StorageQuota> {
195+
unimplemented!()
196+
}
197+
}
198+
199+
#[test]
200+
fn test_is_license_valid() {
201+
let valid_and_active = MockLicenseManagerBuilder::valid_and_active();
202+
assert!(valid_and_active.is_license_valid("".to_string()));
203+
204+
let invalid = MockLicenseManagerBuilder::invalid();
205+
assert!(!invalid.is_license_valid("".to_string()));
206+
207+
let used_to_be_valid_but_expired_now = MockLicenseManagerBuilder::valid_but_expired();
208+
assert!(!used_to_be_valid_but_expired_now.is_license_valid("".to_string()));
209+
}
210+
211+
#[test]
212+
fn test_check_license() {
213+
let valid_and_active = MockLicenseManagerBuilder::valid_and_active();
214+
let result = valid_and_active.check_license("".to_string());
215+
assert!(result.is_ok());
216+
217+
let used_to_be_valid_but_expired_now = MockLicenseManagerBuilder::valid_but_expired();
218+
let result = used_to_be_valid_but_expired_now.check_license("".to_string());
219+
assert!(result.is_err());
220+
let e = result.unwrap_err();
221+
assert_eq!(ErrorCode::LICENSE_KEY_EXPIRED, e.code());
222+
223+
let invalid = MockLicenseManagerBuilder::invalid();
224+
let result = invalid.check_license("".to_string());
225+
assert!(result.is_err());
226+
let e = result.unwrap_err();
227+
assert_eq!(ErrorCode::LICENCE_DENIED, e.code());
228+
}
229+
}

0 commit comments

Comments
 (0)