Skip to content
This repository was archived by the owner on Dec 6, 2024. It is now read-only.

Commit fe64acc

Browse files
prepare 2.4.2 release (#38)
1 parent 81fd9d7 commit fe64acc

File tree

6 files changed

+203
-24
lines changed

6 files changed

+203
-24
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,4 @@
11
docs/build/
22
build/
3+
.idea/
4+
cmake-build-debug/

.ldrelease/build.ps1

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -33,14 +33,15 @@ Push-Location
3333
New-Item -ItemType Directory -Force -Path ".\build-static"
3434
cd "build-static"
3535
New-Item -ItemType Directory -Force -Path release
36+
Write-Host
3637
ExecuteOrFail {
3738
cmake -G "Visual Studio 16 2019" -A x64 `
3839
-D SKIP_DATABASE_TESTS=ON `
39-
-D CMAKE_INSTALL_PREFIX="C:/Users/circleci/project/build-static/release" `
40-
-D CURL_LIBRARY="C:/Users/circleci/project/curl-7.59.0/builds/libcurl-vc-x64-release-static-ipv6-sspi-winssl/lib/libcurl_a.lib" `
41-
-D CURL_INCLUDE_DIR="C:/Users/circleci/project/curl-7.59.0/builds/libcurl-vc-x64-release-static-ipv6-sspi-winssl/include" `
42-
-D PCRE_LIBRARY="C:/Users/circleci/project/pcre-8.43/build/Debug/pcred.lib" `
43-
-D PCRE_INCLUDE_DIR="C:/Users/circleci/project/pcre-8.43/build" `
40+
-D CMAKE_INSTALL_PREFIX="${PSScriptRoot}/../build-static/release" `
41+
-D CURL_LIBRARY="${PSScriptRoot}/../curl-7.59.0/builds/libcurl-vc-x64-release-static-ipv6-sspi-winssl/lib/libcurl_a.lib" `
42+
-D CURL_INCLUDE_DIR="${PSScriptRoot}/../curl-7.59.0/builds/libcurl-vc-x64-release-static-ipv6-sspi-winssl/include" `
43+
-D PCRE_LIBRARY="${PSScriptRoot}/../pcre-8.43/build/Debug/pcred.lib" `
44+
-D PCRE_INCLUDE_DIR="${PSScriptRoot}/../pcre-8.43/build" `
4445
..
4546
}
4647
ExecuteOrFail { cmake --build . }
@@ -57,11 +58,11 @@ ExecuteOrFail {
5758
cmake -G "Visual Studio 16 2019" -A x64 `
5859
-D BUILD_TESTING=OFF `
5960
-D BUILD_SHARED_LIBS=ON `
60-
-D CMAKE_INSTALL_PREFIX="C:/Users/circleci/project/build-dynamic/release" `
61-
-D CURL_LIBRARY="C:/Users/circleci/project/curl-7.59.0/builds/libcurl-vc-x64-release-static-ipv6-sspi-winssl/lib/libcurl_a.lib" `
62-
-D CURL_INCLUDE_DIR="C:/Users/circleci/project/curl-7.59.0/builds/libcurl-vc-x64-release-static-ipv6-sspi-winssl/include" `
63-
-D PCRE_LIBRARY="C:/Users/circleci/project/pcre-8.43/build/Debug/pcred.lib" `
64-
-D PCRE_INCLUDE_DIR="C:/Users/circleci/project/pcre-8.43/build" `
61+
-D CMAKE_INSTALL_PREFIX="${PSScriptRoot}/../build-dynamic/release" `
62+
-D CURL_LIBRARY="${PSScriptRoot}/../curl-7.59.0/builds/libcurl-vc-x64-release-static-ipv6-sspi-winssl/lib/libcurl_a.lib" `
63+
-D CURL_INCLUDE_DIR="${PSScriptRoot}/../curl-7.59.0/builds/libcurl-vc-x64-release-static-ipv6-sspi-winssl/include" `
64+
-D PCRE_LIBRARY="${PSScriptRoot}/../pcre-8.43/build/Debug/pcred.lib" `
65+
-D PCRE_INCLUDE_DIR="${PSScriptRoot}/../pcre-8.43/build" `
6566
..
6667
}
6768
ExecuteOrFail { cmake --build . }

src/variations.c

Lines changed: 11 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -328,7 +328,8 @@ variation(
328328

329329
LDJSONFree(subEvents);
330330

331-
goto error;
331+
/* In this case the value will be null, so after LDi_processEvaluation the value will be checked,
332+
* and then it will move on to the error condition. */
332333
}
333334
}
334335

@@ -639,14 +640,18 @@ LDAllFlags(struct LDClient *const client, const struct LDUser *const user)
639640
return NULL;
640641
}
641642

643+
/* In this case we have read from the store without error, but there are no flags in it. */
644+
if (!rawFlagsRC) {
645+
return evaluatedFlags;
646+
}
647+
642648
rawFlags = LDJSONRCGet(rawFlagsRC);
643649
LD_ASSERT(rawFlags);
644650

645651
for (rawFlagsIter = LDGetIter(rawFlags); rawFlagsIter;
646652
rawFlagsIter = LDIterNext(rawFlagsIter))
647653
{
648654
struct LDJSON * value, *events;
649-
EvalStatus status;
650655
struct LDDetails details;
651656
struct LDJSON * flag;
652657
const char * key;
@@ -660,7 +665,7 @@ LDAllFlags(struct LDClient *const client, const struct LDUser *const user)
660665

661666
LDDetailsInit(&details);
662667

663-
status = LDi_evaluate(
668+
LDi_evaluate(
664669
client,
665670
flag,
666671
user,
@@ -669,18 +674,10 @@ LDAllFlags(struct LDClient *const client, const struct LDUser *const user)
669674
&events,
670675
&value,
671676
LDBooleanFalse);
672-
673-
if (LDi_isEvalError(status)) {
674-
LDJSONFree(events);
675-
LDDetailsClear(&details);
676-
677-
goto error;
678-
}
679-
680-
key = LDGetText(LDObjectLookup(flag, "key"));
681-
LD_ASSERT(key);
682-
677+
683678
if (value) {
679+
key = LDGetText(LDObjectLookup(flag, "key"));
680+
LD_ASSERT(key);
684681
if (!LDObjectSetKey(evaluatedFlags, key, value)) {
685682
LDJSONFree(events);
686683
LDJSONFree(value);

tests/test-allflags.c

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,85 @@ testAllFlags()
6161
LDClientClose(client);
6262
}
6363

64+
/* If there is a problem with a single flag, then that should not prevent returning other flags.
65+
* In this test one of the flags will have an invalid fallthrough that contains neither a variation
66+
* nor rollout.
67+
*/
68+
static void
69+
testAllFlagsWithFlagWithFallthroughWithNoVariationAndNoRollout()
70+
{
71+
struct LDJSON * flag1, *flag2, *allFlags;
72+
struct LDClient *client;
73+
struct LDUser * user;
74+
75+
LD_ASSERT(client = makeTestClient());
76+
LD_ASSERT(user = LDUserNew("userkey"));
77+
78+
/* flag1 */
79+
LD_ASSERT(flag1 = LDNewObject());
80+
LD_ASSERT(LDObjectSetKey(flag1, "key", LDNewText("flag1")));
81+
LD_ASSERT(LDObjectSetKey(flag1, "version", LDNewNumber(1)));
82+
LD_ASSERT(LDObjectSetKey(flag1, "on", LDNewBool(LDBooleanTrue)));
83+
LD_ASSERT(LDObjectSetKey(flag1, "salt", LDNewText("abc")));
84+
setFallthrough(flag1, 1);
85+
addVariation(flag1, LDNewText("a"));
86+
addVariation(flag1, LDNewText("b"));
87+
88+
/* flag2 */
89+
LD_ASSERT(flag2 = LDNewObject());
90+
LD_ASSERT(LDObjectSetKey(flag2, "key", LDNewText("flag2")));
91+
LD_ASSERT(LDObjectSetKey(flag2, "version", LDNewNumber(1)));
92+
LD_ASSERT(LDObjectSetKey(flag2, "on", LDNewBool(LDBooleanTrue)));
93+
LD_ASSERT(LDObjectSetKey(flag2, "salt", LDNewText("abc")));
94+
95+
/* Set a fallthrough which has no variation or rollout. */
96+
struct LDJSON *fallthrough;
97+
LD_ASSERT(fallthrough = LDNewObject());
98+
LD_ASSERT(LDObjectSetKey(flag2, "fallthrough", fallthrough));
99+
100+
/* store */
101+
LD_ASSERT(LDStoreInitEmpty(client->store));
102+
LD_ASSERT(LDStoreUpsert(client->store, LD_FLAG, flag1));
103+
LD_ASSERT(LDStoreUpsert(client->store, LD_FLAG, flag2));
104+
105+
/* test */
106+
LD_ASSERT(allFlags = LDAllFlags(client, user));
107+
108+
/* validation */
109+
LD_ASSERT(LDCollectionGetSize(allFlags) == 1);
110+
LD_ASSERT(strcmp(LDGetText(LDObjectLookup(allFlags, "flag1")), "b") == 0);
111+
112+
/* cleanup */
113+
LDJSONFree(allFlags);
114+
LDUserFree(user);
115+
LDClientClose(client);
116+
}
117+
118+
static void
119+
testAllFlagsNoFlagsInStore()
120+
{
121+
struct LDJSON * flag1, *flag2, *allFlags;
122+
struct LDClient *client;
123+
struct LDUser * user;
124+
125+
LD_ASSERT(client = makeTestClient());
126+
LD_ASSERT(user = LDUserNew("userkey"));
127+
128+
/* store */
129+
LD_ASSERT(LDStoreInitEmpty(client->store));
130+
131+
/* test */
132+
LD_ASSERT(allFlags = LDAllFlags(client, user));
133+
134+
/* validation */
135+
LD_ASSERT(LDCollectionGetSize(allFlags) == 0);
136+
137+
/* cleanup */
138+
LDJSONFree(allFlags);
139+
LDUserFree(user);
140+
LDClientClose(client);
141+
}
142+
64143
int
65144
main()
66145
{
@@ -69,6 +148,8 @@ main()
69148
LDGlobalInit();
70149

71150
testAllFlags();
151+
testAllFlagsWithFlagWithFallthroughWithNoVariationAndNoRollout();
152+
testAllFlagsNoFlagsInStore();
72153

73154
LDBasicLoggerThreadSafeShutdown();
74155

tests/test-eval.c

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -219,6 +219,58 @@ testFlagReturnsFallthroughIfFlagIsOnAndThereAreNoRules()
219219
LDClientClose(client);
220220
}
221221

222+
static void
223+
testFlagReturnsErrorForFallthroughWithNoVariationAndNoRollout()
224+
{
225+
struct LDUser * user;
226+
struct LDJSON * flag, *result, *events;
227+
struct LDDetails details;
228+
struct LDClient *client;
229+
struct LDConfig *config;
230+
231+
events = NULL;
232+
result = NULL;
233+
234+
LDDetailsInit(&details);
235+
LD_ASSERT(config = LDConfigNew("abc"));
236+
LD_ASSERT(client = LDClientInit(config, 0));
237+
LD_ASSERT(user = LDUserNew("userKeyA"));
238+
239+
/* flag */
240+
LD_ASSERT(flag = LDNewObject());
241+
LD_ASSERT(LDObjectSetKey(flag, "key", LDNewText("feature0")));
242+
LD_ASSERT(LDObjectSetKey(flag, "on", LDNewBool(LDBooleanTrue)));
243+
LD_ASSERT(LDObjectSetKey(flag, "rules", LDNewArray()));
244+
LD_ASSERT(LDObjectSetKey(flag, "salt", LDNewText("abc")));
245+
246+
/* Set a fallthrough which has no variation or rollout. */
247+
struct LDJSON *fallthrough;
248+
LD_ASSERT(fallthrough = LDNewObject());
249+
LD_ASSERT(LDObjectSetKey(flag, "fallthrough", fallthrough));
250+
251+
/* run */
252+
LD_ASSERT(
253+
LDi_evaluate(
254+
client,
255+
flag,
256+
user,
257+
(struct LDStore *)1,
258+
&details,
259+
&events,
260+
&result,
261+
LDBooleanFalse) == EVAL_SCHEMA);
262+
263+
LD_ASSERT(!details.hasVariation);
264+
LD_ASSERT(details.reason == LD_FALLTHROUGH);
265+
LD_ASSERT(!events);
266+
LD_ASSERT(!result);
267+
268+
LDJSONFree(flag);
269+
LDUserFree(user);
270+
LDDetailsClear(&details);
271+
LDClientClose(client);
272+
}
273+
222274
static void
223275
testFlagReturnsOffVariationIfPrerequisiteIsOff()
224276
{
@@ -1424,6 +1476,7 @@ main()
14241476
testInExperimentExplanation();
14251477
testNotInExperimentExplanation();
14261478
testRolloutCustomSeed();
1479+
testFlagReturnsErrorForFallthroughWithNoVariationAndNoRollout();
14271480

14281481
LDBasicLoggerThreadSafeShutdown();
14291482

tests/test-variations.c

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -272,6 +272,50 @@ testJSONVariationNullFallback()
272272
LDDetailsClear(&details);
273273
}
274274

275+
static void
276+
testFallthroughWithNoVariationOrRollout()
277+
{
278+
struct LDJSON *flag, *fallthrough, *variation, *rollout, *variations;
279+
struct LDClient *client;
280+
struct LDUser * user;
281+
char *actual;
282+
struct LDDetails details;
283+
284+
struct LDJSON *events;
285+
286+
/* setup */
287+
LD_ASSERT(client = makeTestClient());
288+
LD_ASSERT(user = LDUserNew("userkey"));
289+
/* flag */
290+
LD_ASSERT(flag = LDNewObject());
291+
LD_ASSERT(LDObjectSetKey(flag, "key", LDNewText("feature0")));
292+
LD_ASSERT(LDObjectSetKey(flag, "offVariation", LDNewNull()));
293+
LD_ASSERT(LDObjectSetKey(flag, "on", LDNewBool(LDBooleanTrue)));
294+
LD_ASSERT(LDObjectSetKey(flag, "salt", LDNewText("123123")));
295+
LD_ASSERT(LDObjectSetKey(flag, "version", LDNewNumber(3)));
296+
297+
LD_ASSERT(fallthrough = LDNewObject());
298+
LD_ASSERT(LDObjectSetKey(flag, "fallthrough", fallthrough));
299+
300+
addVariation(flag, LDNewText("ExpectedPrefix_A"));
301+
addVariation(flag, LDNewText("ExpectedPrefix_B"));
302+
addVariation(flag, LDNewText("ExpectedPrefix_C"));
303+
304+
LD_ASSERT(LDStoreInitEmpty(client->store));
305+
LDStoreUpsert(client->store, LD_FLAG, flag);
306+
/* run */
307+
actual = LDStringVariation(client, user, "feature0", NULL, &details);
308+
/* The schema will fail, so the fallback value will be used. */
309+
/* validate */
310+
LD_ASSERT(!actual);
311+
LD_ASSERT(details.reason == LD_ERROR);
312+
313+
/* cleanup */
314+
LDUserFree(user);
315+
LDClientClose(client);
316+
LDDetailsClear(&details);
317+
}
318+
275319
int
276320
main()
277321
{
@@ -287,6 +331,7 @@ main()
287331
testStringVariationNullFallback();
288332
testJSONVariation();
289333
testJSONVariationNullFallback();
334+
testFallthroughWithNoVariationOrRollout();
290335

291336
LDBasicLoggerThreadSafeShutdown();
292337

0 commit comments

Comments
 (0)