diff options
Diffstat (limited to 'spec/services/ml')
4 files changed, 136 insertions, 0 deletions
diff --git a/spec/services/ml/experiment_tracking/candidate_repository_spec.rb b/spec/services/ml/experiment_tracking/candidate_repository_spec.rb index 079c36c9613..9b46675a08e 100644 --- a/spec/services/ml/experiment_tracking/candidate_repository_spec.rb +++ b/spec/services/ml/experiment_tracking/candidate_repository_spec.rb @@ -61,6 +61,15 @@ RSpec.describe ::Ml::ExperimentTracking::CandidateRepository, feature_category: expect(subject.name).to eq('blah') end end + + context 'when name is nil and no mlflow.runName is not present' do + let(:tags) { nil } + let(:name) { nil } + + it 'gives the candidate a random name' do + expect(subject.name).to match(/[a-z]+-[a-z]+-[a-z]+-\d+/) + end + end end end diff --git a/spec/services/ml/find_or_create_experiment_service_spec.rb b/spec/services/ml/find_or_create_experiment_service_spec.rb new file mode 100644 index 00000000000..a8c533d1320 --- /dev/null +++ b/spec/services/ml/find_or_create_experiment_service_spec.rb @@ -0,0 +1,33 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe ::Ml::FindOrCreateExperimentService, feature_category: :mlops do + let_it_be(:project) { create(:project) } + let_it_be(:user) { project.first_owner } + let_it_be(:existing_experiment) { create(:ml_experiments, project: project, user: user) } + + let(:name) { 'new_experiment' } + + subject(:new_experiment) { described_class.new(project, name, user).execute } + + describe '#execute' do + it 'creates an experiment using Ml::Experiment.find_or_create', :aggregate_failures do + expect(Ml::Experiment).to receive(:find_or_create).and_call_original + + expect(new_experiment.name).to eq('new_experiment') + expect(new_experiment.project).to eq(project) + expect(new_experiment.user).to eq(user) + end + + context 'when experiment already exists' do + let(:name) { existing_experiment.name } + + it 'fetches existing experiment', :aggregate_failures do + expect { new_experiment }.not_to change { Ml::Experiment.count } + + expect(new_experiment).to eq(existing_experiment) + end + end + end +end diff --git a/spec/services/ml/find_or_create_model_service_spec.rb b/spec/services/ml/find_or_create_model_service_spec.rb new file mode 100644 index 00000000000..6ddae20f8d6 --- /dev/null +++ b/spec/services/ml/find_or_create_model_service_spec.rb @@ -0,0 +1,45 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe ::Ml::FindOrCreateModelService, feature_category: :mlops do + let_it_be(:existing_model) { create(:ml_models) } + let_it_be(:another_project) { create(:project) } + + subject(:create_model) { described_class.new(project, name).execute } + + describe '#execute' do + context 'when model name does not exist in the project' do + let(:name) { 'new_model' } + let(:project) { existing_model.project } + + it 'creates a model', :aggregate_failures do + expect { create_model }.to change { Ml::Model.count }.by(1) + + expect(create_model.name).to eq(name) + end + end + + context 'when model name exists but project is different' do + let(:name) { existing_model.name } + let(:project) { another_project } + + it 'creates a model', :aggregate_failures do + expect { create_model }.to change { Ml::Model.count }.by(1) + + expect(create_model.name).to eq(name) + end + end + + context 'when model with name exists' do + let(:name) { existing_model.name } + let(:project) { existing_model.project } + + it 'fetches existing model', :aggregate_failures do + expect { create_model }.to change { Ml::Model.count }.by(0) + + expect(create_model).to eq(existing_model) + end + end + end +end diff --git a/spec/services/ml/find_or_create_model_version_service_spec.rb b/spec/services/ml/find_or_create_model_version_service_spec.rb new file mode 100644 index 00000000000..1211a9b1165 --- /dev/null +++ b/spec/services/ml/find_or_create_model_version_service_spec.rb @@ -0,0 +1,49 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe ::Ml::FindOrCreateModelVersionService, feature_category: :mlops do + let_it_be(:existing_version) { create(:ml_model_versions) } + let_it_be(:another_project) { create(:project) } + + let(:package) { nil } + + let(:params) do + { + model_name: name, + version: version, + package: package + } + end + + subject(:model_version) { described_class.new(project, params).execute } + + describe '#execute' do + context 'when model version exists' do + let(:name) { existing_version.name } + let(:version) { existing_version.version } + let(:project) { existing_version.project } + + it 'returns existing model version', :aggregate_failures do + expect { model_version }.to change { Ml::ModelVersion.count }.by(0) + expect(model_version).to eq(existing_version) + end + end + + context 'when model version does not exist' do + let(:project) { existing_version.project } + let(:name) { 'a_new_model' } + let(:version) { '2.0.0' } + + let(:package) { create(:ml_model_package, project: project, name: name, version: version) } + + it 'creates a new model version', :aggregate_failures do + expect { model_version }.to change { Ml::ModelVersion.count } + + expect(model_version.name).to eq(name) + expect(model_version.version).to eq(version) + expect(model_version.package).to eq(package) + end + end + end +end |