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

Commit 108de17

Browse files
committed
Introduce TestData#delete to simplify testing of flag deletion.
1 parent dfb6942 commit 108de17

File tree

3 files changed

+80
-4
lines changed

3 files changed

+80
-4
lines changed

src/main/java/com/launchdarkly/sdk/server/integrations/TestData.java

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
import com.launchdarkly.sdk.server.subsystems.DataStoreTypes.ItemDescriptor;
2121
import com.launchdarkly.sdk.server.subsystems.DataStoreTypes.KeyedItems;
2222

23+
import javax.annotation.concurrent.GuardedBy;
2324
import java.io.IOException;
2425
import java.util.ArrayList;
2526
import java.util.HashMap;
@@ -110,7 +111,36 @@ public FlagBuilder flag(String key) {
110111
}
111112
return new FlagBuilder(key).booleanFlag();
112113
}
113-
114+
115+
/**
116+
* Deletes a specific flag from the test data by create a versioned tombstone.
117+
* <p>
118+
* This has the same effect as if a flag were removed on the LaunchDarkly dashboard.
119+
* It immediately propagates the flag change to any {@code LDClient} instance(s) that you have
120+
* already configured to use this {@code TestData}. If no {@code LDClient} has been started yet,
121+
* it simply adds tombstone to the test data which will be provided to any {@code LDClient} that
122+
* you subsequently configure.
123+
*
124+
* @param key the flag key
125+
* @return a flag configuration builder
126+
*/
127+
public TestData delete(String key) {
128+
final ItemDescriptor tombstoneItem;
129+
synchronized (lock) {
130+
final ItemDescriptor oldItem = currentFlags.get(key);
131+
final int oldVersion = oldItem == null ? 0 : oldItem.getVersion();
132+
tombstoneItem = ItemDescriptor.deletedItem(oldVersion + 1);
133+
currentFlags.put(key, tombstoneItem);
134+
currentBuilders.remove(key);
135+
}
136+
137+
for (DataSourceImpl instance: instances) {
138+
instance.updates.upsert(DataModel.FEATURES, key, tombstoneItem);
139+
}
140+
141+
return this;
142+
}
143+
114144
/**
115145
* Updates the test data with the specified flag configuration.
116146
* <p>
@@ -146,7 +176,7 @@ public TestData update(FlagBuilder flagBuilder) {
146176

147177
return this;
148178
}
149-
179+
150180
/**
151181
* Simulates a change in the data source status.
152182
* <p>

src/test/java/com/launchdarkly/sdk/server/integrations/TestDataTest.java

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
import static org.hamcrest.Matchers.is;
3434
import static org.hamcrest.Matchers.iterableWithSize;
3535
import static org.hamcrest.Matchers.not;
36+
import static org.hamcrest.Matchers.notNullValue;
3637
import static org.hamcrest.Matchers.nullValue;
3738

3839
@SuppressWarnings("javadoc")
@@ -151,7 +152,34 @@ public void updatesFlag() throws Exception {
151152
expectedFlag.on(true).version(2);
152153
assertJsonEquals(flagJson(expectedFlag, 2), flagJson(flag1));
153154
}
154-
155+
156+
@Test
157+
public void deletesFlag() throws Exception {
158+
final TestData td = TestData.dataSource();
159+
160+
try (final DataSource ds = td.build(clientContext("", new LDConfig.Builder().build(), updates))) {
161+
final Future<Void> started = ds.start();
162+
assertThat(started.isDone(), is(true));
163+
assertThat(updates.valid, is(true));
164+
165+
td.update(td.flag("foo").on(false).valueForAll(LDValue.of("bar")));
166+
td.delete("foo");
167+
168+
assertThat(updates.upserts.size(), equalTo(2));
169+
UpsertParams up = updates.upserts.take();
170+
assertThat(up.kind, is(DataModel.FEATURES));
171+
assertThat(up.key, equalTo("foo"));
172+
assertThat(up.item.getVersion(), equalTo(1));
173+
assertThat(up.item.getItem(), notNullValue());
174+
175+
up = updates.upserts.take();
176+
assertThat(up.kind, is(DataModel.FEATURES));
177+
assertThat(up.key, equalTo("foo"));
178+
assertThat(up.item.getVersion(), equalTo(2));
179+
assertThat(up.item.getItem(), nullValue());
180+
}
181+
}
182+
155183
@Test
156184
public void flagConfigSimpleBoolean() throws Exception {
157185
Function<ModelBuilders.FlagBuilder, ModelBuilders.FlagBuilder> expectedBooleanFlag = fb ->

src/test/java/com/launchdarkly/sdk/server/integrations/TestDataWithClientTest.java

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
package com.launchdarkly.sdk.server.integrations;
22

3+
import com.launchdarkly.sdk.EvaluationDetail;
4+
import com.launchdarkly.sdk.EvaluationReason;
35
import com.launchdarkly.sdk.LDContext;
46
import com.launchdarkly.sdk.LDValue;
57
import com.launchdarkly.sdk.server.Components;
@@ -52,7 +54,23 @@ public void updatesFlag() throws Exception {
5254
assertThat(client.boolVariation("flag", LDContext.create("user"), false), is(true));
5355
}
5456
}
55-
57+
58+
@Test
59+
public void deletesFlag() throws Exception {
60+
td.update(td.flag("flag").on(true));
61+
62+
try (LDClient client = new LDClient(SDK_KEY, config)) {
63+
assertThat(client.boolVariation("flag", LDContext.create("user"), false), is(true));
64+
65+
td.delete("flag");
66+
67+
final EvaluationDetail<Boolean> detail = client.boolVariationDetail("flag", LDContext.create("user"), false);
68+
assertThat(detail.getValue(), is(false));
69+
assertThat(detail.isDefaultValue(), is(true));
70+
assertThat(detail.getReason().getErrorKind(), is(EvaluationReason.ErrorKind.FLAG_NOT_FOUND));
71+
}
72+
}
73+
5674
@Test
5775
public void usesTargets() throws Exception {
5876
td.update(td.flag("flag").fallthroughVariation(false).variationForUser("user1", true));

0 commit comments

Comments
 (0)