Skip to content

Commit b69d494

Browse files
committed
CM-4553: Implemented test cases for CometApi.getExperimentMetadata(). Implemented related test cases
1 parent 1adb75c commit b69d494

File tree

9 files changed

+90
-15
lines changed

9 files changed

+90
-15
lines changed

comet-java-client/src/main/java/ml/comet/experiment/CometApi.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,15 @@ public interface CometApi extends Closeable {
6060

6161
List<ExperimentMetadata> getExperiments(String workspaceName);
6262

63+
/**
64+
* Allows to load metadata of the particular Comet experiment using provided {@code experimentKey}.
65+
*
66+
* @param experimentKey the ID of the Comet experiment.
67+
* @return the initialized {@code ExperimentMetadata}.
68+
* @throws ExperimentNotFoundException if Comet experiment with specified {@code experimentKey} not found.
69+
*/
70+
ExperimentMetadata getExperimentMetadata(String experimentKey) throws ExperimentNotFoundException;
71+
6372
/**
6473
* Register model defined in the specified experiment in the Comet's model registry.
6574
*
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
package ml.comet.experiment;
2+
3+
import ml.comet.experiment.exception.CometApiException;
4+
5+
/**
6+
* Exception to be thrown when Comet experiment was not found.
7+
*/
8+
public class ExperimentNotFoundException extends CometApiException {
9+
10+
/**
11+
* Constructs a new ExperimentNotFoundException exception with the specified detail message.
12+
* The cause is not initialized, and may subsequently be initialized by a
13+
* call to {@link #initCause}.
14+
*
15+
* @param message the detail message. The detail message is saved for
16+
* later retrieval by the {@link #getMessage()} method.
17+
*/
18+
public ExperimentNotFoundException(String message) {
19+
super(message);
20+
}
21+
}

comet-java-client/src/main/java/ml/comet/experiment/impl/BaseExperiment.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -797,7 +797,7 @@ public ExperimentMetadata getMetadata() {
797797
getLogger().debug("get metadata for experiment {}", this.experimentKey);
798798
}
799799

800-
return loadRemote(restApiClient::getMetadata, "METADATA").toExperimentMetadata();
800+
return loadRemote(restApiClient::getExperimentMetadata, "METADATA").toExperimentMetadata();
801801
}
802802

803803
@Override

comet-java-client/src/main/java/ml/comet/experiment/impl/CometApiImpl.java

Lines changed: 25 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import lombok.NonNull;
66
import lombok.SneakyThrows;
77
import ml.comet.experiment.CometApi;
8+
import ml.comet.experiment.ExperimentNotFoundException;
89
import ml.comet.experiment.builder.BaseCometBuilder;
910
import ml.comet.experiment.builder.CometApiBuilder;
1011
import ml.comet.experiment.exception.CometApiException;
@@ -67,6 +68,7 @@
6768
import static ml.comet.experiment.impl.resources.LogMessages.DOWNLOADING_REGISTRY_MODEL_TO_DIR;
6869
import static ml.comet.experiment.impl.resources.LogMessages.DOWNLOADING_REGISTRY_MODEL_TO_FILE;
6970
import static ml.comet.experiment.impl.resources.LogMessages.EXPERIMENT_HAS_NO_MODELS;
71+
import static ml.comet.experiment.impl.resources.LogMessages.EXPERIMENT_WITH_KEY_NOT_FOUND;
7072
import static ml.comet.experiment.impl.resources.LogMessages.EXTRACTED_N_REGISTRY_MODEL_FILES;
7173
import static ml.comet.experiment.impl.resources.LogMessages.FAILED_TO_DELETE_REGISTRY_MODEL;
7274
import static ml.comet.experiment.impl.resources.LogMessages.FAILED_TO_DELETE_REGISTRY_MODEL_VERSION;
@@ -200,15 +202,31 @@ public List<ExperimentMetadata> getExperiments(
200202
return this.getExperiments(workspaceName, projectName)
201203
.stream()
202204
.filter(experimentMetadata -> {
203-
if (StringUtils.isEmpty(experimentMetadata.getExperimentName())) {
204-
return false;
205-
} else {
206-
return p.matcher(experimentMetadata.getExperimentName()).matches();
207-
}
208-
})
205+
if (StringUtils.isEmpty(experimentMetadata.getExperimentName())) {
206+
return false;
207+
} else {
208+
return p.matcher(experimentMetadata.getExperimentName()).matches();
209+
}
210+
})
209211
.collect(Collectors.toList());
210212
}
211213

214+
@Override
215+
public ExperimentMetadata getExperimentMetadata(@NonNull final String experimentKey)
216+
throws ExperimentNotFoundException {
217+
try {
218+
return this.restApiClient
219+
.getExperimentMetadata(experimentKey)
220+
.blockingGet()
221+
.toExperimentMetadata();
222+
} catch (CometApiException ex) {
223+
if (ex.getStatusCode() == 400) {
224+
throw new ExperimentNotFoundException(getString(EXPERIMENT_WITH_KEY_NOT_FOUND, experimentKey));
225+
}
226+
throw ex;
227+
}
228+
}
229+
212230
@Override
213231
public ModelRegistryRecord registerModel(@NonNull final Model model, @NonNull final String experimentKey) {
214232
// get list of experiment models
@@ -239,7 +257,7 @@ public ModelRegistryRecord registerModel(@NonNull final Model model, @NonNull fi
239257
modelImpl.setExperimentModelId(details.get().getExperimentModelId());
240258

241259
// check if model already registered in the experiment's workspace records
242-
Boolean modelInRegistry = this.restApiClient.getMetadata(experimentKey)
260+
Boolean modelInRegistry = this.restApiClient.getExperimentMetadata(experimentKey)
243261
.concatMap(experimentMetadataRest -> {
244262
modelImpl.setWorkspace(experimentMetadataRest.getWorkspaceName());
245263
return this.restApiClient.getRegistryModelsForWorkspace(experimentMetadataRest.getWorkspaceName());

comet-java-client/src/main/java/ml/comet/experiment/impl/RestApiClient.java

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -172,8 +172,11 @@ Single<GetExperimentsResponse> getAllExperiments(String projectName, String work
172172
return singleFromSyncGetWithRetries(EXPERIMENTS, params, GetExperimentsResponse.class);
173173
}
174174

175-
Single<ExperimentMetadataRest> getMetadata(String experimentKey) {
176-
return singleFromSyncGetWithRetries(GET_METADATA, experimentKey, ExperimentMetadataRest.class);
175+
Single<ExperimentMetadataRest> getExperimentMetadata(String experimentKey) {
176+
return singleFromSyncGetWithRetries(GET_METADATA,
177+
Collections.singletonMap(EXPERIMENT_KEY, experimentKey),
178+
true,
179+
ExperimentMetadataRest.class);
177180
}
178181

179182
Single<GitMetadataRest> getGitMetadata(String experimentKey) {
@@ -503,7 +506,7 @@ private <T> Single<T> singleFromSyncPostWithRetries(@NonNull Object payload,
503506
return this.connection.sendPostWithRetries(request, endpoint, throwOnFailure)
504507
.map(body -> Single.just(JsonUtils.fromJson(body, clazz)))
505508
.orElse(Single.error(new CometApiException(
506-
String.format("No response was returned by endpoint: %s", endpoint))));
509+
getString(NO_RESPONSE_RETURNED_BY_REMOTE_ENDPOINT, endpoint))));
507510
}
508511

509512
private Single<RestApiResponse> singleFromSyncPostWithRetriesEmptyBody(@NonNull Object payload,
@@ -549,7 +552,7 @@ private <T> Single<T> singleFromSyncGetWithRetries(@NonNull String endpoint,
549552
return this.connection.sendGetWithRetries(endpoint, queryParams, throwOnFailure)
550553
.map(body -> Single.just(JsonUtils.fromJson(body, clazz)))
551554
.orElse(Single.error(new CometApiException(
552-
String.format("No response was returned by endpoint: %s", endpoint))));
555+
getString(NO_RESPONSE_RETURNED_BY_REMOTE_ENDPOINT, endpoint))));
553556
}
554557

555558
private static RestApiResponse mapResponse(Response response) {

comet-java-client/src/main/java/ml/comet/experiment/impl/http/Connection.java

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -428,9 +428,14 @@ Optional<String> executeRequestSyncWithRetries(
428428
return Optional.empty();
429429
} catch (Throwable e) {
430430
// unexpected error - throw or return
431-
this.logger.error("Failed to execute request: {}, unexpected error", request, e);
432-
if (throwOnFailure) {
433-
throw new CometApiException("failed to execute request, unexpected error", e);
431+
if (e instanceof InterruptedException) {
432+
// ignore InterruptedException as it can be thrown during shutdown - just debug it
433+
this.logger.debug("Failed to execute request: {}, unexpected error: {}", request, e);
434+
} else {
435+
this.logger.error("Failed to execute request: {}, unexpected error", request, e);
436+
if (throwOnFailure) {
437+
throw new CometApiException("failed to execute request, unexpected error", e);
438+
}
434439
}
435440
return Optional.empty();
436441
}

comet-java-client/src/main/java/ml/comet/experiment/impl/resources/LogMessages.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,7 @@ public class LogMessages {
102102
public static final String FAILED_TO_DELETE_REGISTRY_MODEL = "FAILED_TO_DELETE_REGISTRY_MODEL";
103103
public static final String NO_RESPONSE_RETURNED_BY_REMOTE_ENDPOINT = "NO_RESPONSE_RETURNED_BY_REMOTE_ENDPOINT";
104104
public static final String FAILED_TO_DELETE_REGISTRY_MODEL_VERSION = "FAILED_TO_DELETE_REGISTRY_MODEL_VERSION";
105+
public static final String EXPERIMENT_WITH_KEY_NOT_FOUND = "EXPERIMENT_WITH_KEY_NOT_FOUND";
105106

106107

107108
/**

comet-java-client/src/main/resources/messages.properties

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,3 +87,4 @@ REGISTRY_MODEL_VERSION_NOT_FOUND=Version '%s' of the registry model '%s/%s' is n
8787
FAILED_TO_DELETE_REGISTRY_MODEL=Failed to delete registry model '%s/%s'.
8888
NO_RESPONSE_RETURNED_BY_REMOTE_ENDPOINT=No response was returned by endpoint '%s'
8989
FAILED_TO_DELETE_REGISTRY_MODEL_VERSION=Failed to delete registry model '%s/%s:%s'.
90+
EXPERIMENT_WITH_KEY_NOT_FOUND=Failed to get Comet experiment with key '%s'.

comet-java-client/src/test/java/ml/comet/experiment/impl/CometApiTest.java

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import io.reactivex.rxjava3.core.Observable;
44
import ml.comet.experiment.CometApi;
5+
import ml.comet.experiment.ExperimentNotFoundException;
56
import ml.comet.experiment.OnlineExperiment;
67
import ml.comet.experiment.exception.CometApiException;
78
import ml.comet.experiment.impl.rest.RegistryModelItemOverview;
@@ -159,6 +160,22 @@ public void testGetExperiments_emptyProject_with_experimentName() {
159160
COMET_API.getExperiments(WORKSPACE_NAME, null, "someExperiment*."));
160161
}
161162

163+
@Test
164+
public void testGetExperimentMetadata() {
165+
ExperimentMetadata experimentMetadata = COMET_API.getExperimentMetadata(SHARED_EXPERIMENT.getExperimentKey());
166+
167+
assertEquals(SHARED_EXPERIMENT.getExperimentKey(), experimentMetadata.getExperimentKey());
168+
assertEquals(SHARED_EXPERIMENT.getExperimentName(), experimentMetadata.getExperimentName());
169+
assertEquals(SHARED_EXPERIMENT.getProjectName(), PROJECT_NAME);
170+
assertEquals(SHARED_EXPERIMENT.getWorkspaceName(), WORKSPACE_NAME);
171+
}
172+
173+
@Test
174+
public void testGetExperimentMetadata_not_found() {
175+
assertThrows(ExperimentNotFoundException.class, () ->
176+
COMET_API.getExperimentMetadata("not existing experiment key"));
177+
}
178+
162179
@Test
163180
public void testRegisterModel() {
164181
String modelName = String.format("%s-%d", SOME_MODEL_NAME, System.currentTimeMillis());

0 commit comments

Comments
 (0)