Skip to content

Commit

Permalink
feat: Introduce TestData#delete to simplify testing of flag deletion. (
Browse files Browse the repository at this point in the history
…#21)

This is migrating a [PR from the java-server-sdk
repo](launchdarkly/java-server-sdk@c8bdd2d).
The java-server-sdk repo will be archived after this is merged.

Co-authored-by: David Moravek <dmoravek@confluent.io>
  • Loading branch information
tanderson-ld and dmvk authored May 23, 2024
1 parent 28f702d commit 388dd04
Show file tree
Hide file tree
Showing 3 changed files with 79 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,36 @@ public FlagBuilder flag(String key) {
}
return new FlagBuilder(key).booleanFlag();
}


/**
* Deletes a specific flag from the test data by create a versioned tombstone.
* <p>
* This has the same effect as if a flag were removed on the LaunchDarkly dashboard.
* It immediately propagates the flag change to any {@code LDClient} instance(s) that you have
* already configured to use this {@code TestData}. If no {@code LDClient} has been started yet,
* it simply adds tombstone to the test data which will be provided to any {@code LDClient} that
* you subsequently configure.
*
* @param key the flag key
* @return a flag configuration builder
*/
public TestData delete(String key) {
final ItemDescriptor tombstoneItem;
synchronized (lock) {
final ItemDescriptor oldItem = currentFlags.get(key);
final int oldVersion = oldItem == null ? 0 : oldItem.getVersion();
tombstoneItem = ItemDescriptor.deletedItem(oldVersion + 1);
currentFlags.put(key, tombstoneItem);
currentBuilders.remove(key);
}

for (DataSourceImpl instance: instances) {
instance.updates.upsert(DataModel.FEATURES, key, tombstoneItem);
}

return this;
}

/**
* Updates the test data with the specified flag configuration.
* <p>
Expand Down Expand Up @@ -146,7 +175,7 @@ public TestData update(FlagBuilder flagBuilder) {

return this;
}

/**
* Simulates a change in the data source status.
* <p>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.iterableWithSize;
import static org.hamcrest.Matchers.not;
import static org.hamcrest.Matchers.notNullValue;
import static org.hamcrest.Matchers.nullValue;

@SuppressWarnings("javadoc")
Expand Down Expand Up @@ -151,7 +152,34 @@ public void updatesFlag() throws Exception {
expectedFlag.on(true).version(2);
assertJsonEquals(flagJson(expectedFlag, 2), flagJson(flag1));
}


@Test
public void deletesFlag() throws Exception {
final TestData td = TestData.dataSource();

try (final DataSource ds = td.build(clientContext("", new LDConfig.Builder().build(), updates))) {
final Future<Void> started = ds.start();
assertThat(started.isDone(), is(true));
assertThat(updates.valid, is(true));

td.update(td.flag("foo").on(false).valueForAll(LDValue.of("bar")));
td.delete("foo");

assertThat(updates.upserts.size(), equalTo(2));
UpsertParams up = updates.upserts.take();
assertThat(up.kind, is(DataModel.FEATURES));
assertThat(up.key, equalTo("foo"));
assertThat(up.item.getVersion(), equalTo(1));
assertThat(up.item.getItem(), notNullValue());

up = updates.upserts.take();
assertThat(up.kind, is(DataModel.FEATURES));
assertThat(up.key, equalTo("foo"));
assertThat(up.item.getVersion(), equalTo(2));
assertThat(up.item.getItem(), nullValue());
}
}

@Test
public void flagConfigSimpleBoolean() throws Exception {
Function<ModelBuilders.FlagBuilder, ModelBuilders.FlagBuilder> expectedBooleanFlag = fb ->
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package com.launchdarkly.sdk.server.integrations;

import com.launchdarkly.sdk.EvaluationDetail;
import com.launchdarkly.sdk.EvaluationReason;
import com.launchdarkly.sdk.LDContext;
import com.launchdarkly.sdk.LDValue;
import com.launchdarkly.sdk.server.Components;
Expand Down Expand Up @@ -52,7 +54,23 @@ public void updatesFlag() throws Exception {
assertThat(client.boolVariation("flag", LDContext.create("user"), false), is(true));
}
}


@Test
public void deletesFlag() throws Exception {
td.update(td.flag("flag").on(true));

try (LDClient client = new LDClient(SDK_KEY, config)) {
assertThat(client.boolVariation("flag", LDContext.create("user"), false), is(true));

td.delete("flag");

final EvaluationDetail<Boolean> detail = client.boolVariationDetail("flag", LDContext.create("user"), false);
assertThat(detail.getValue(), is(false));
assertThat(detail.isDefaultValue(), is(true));
assertThat(detail.getReason().getErrorKind(), is(EvaluationReason.ErrorKind.FLAG_NOT_FOUND));
}
}

@Test
public void usesTargets() throws Exception {
td.update(td.flag("flag").fallthroughVariation(false).variationForUser("user1", true));
Expand Down

0 comments on commit 388dd04

Please sign in to comment.