/** * Licensed to The Apereo Foundation under one or more contributor license * agreements. See the NOTICE file distributed with this work for additional * information regarding copyright ownership. * * * The Apereo Foundation licenses this file to you under the Educational * Community License, Version 2.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of the License * at: * * http://opensource.org/licenses/ecl2.txt * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. * */ package org.opencastproject.composer.impl.endpoint; import org.opencastproject.composer.api.ComposerService; import org.opencastproject.composer.api.EncodingProfile; import org.opencastproject.composer.api.EncodingProfileImpl; import org.opencastproject.composer.api.EncodingProfileList; import org.opencastproject.composer.layout.Dimension; import org.opencastproject.composer.layout.Serializer; import org.opencastproject.job.api.JaxbJob; import org.opencastproject.job.api.Job; import org.opencastproject.job.api.JobImpl; import org.opencastproject.mediapackage.MediaPackageElementBuilder; import org.opencastproject.mediapackage.MediaPackageElementBuilderFactory; import org.opencastproject.mediapackage.MediaPackageElementParser; import org.opencastproject.mediapackage.MediaPackageElements; import org.opencastproject.mediapackage.Track; import org.opencastproject.util.NotFoundException; import org.opencastproject.util.data.Collections; import org.easymock.EasyMock; import org.junit.Assert; import org.junit.Before; import org.junit.Test; import java.util.ArrayList; import java.util.List; import javax.ws.rs.core.Response; import javax.ws.rs.core.Response.Status; /** * Tests the behavior of the composer rest endpoint, using a mock composer service. */ public class ComposerRestServiceTest { private JobImpl job; private EncodingProfileImpl profile; private EncodingProfileList profileList; private Track audioTrack; private Track videoTrack; private String profileId; private ComposerRestService restService; @Before public void setUp() throws Exception { MediaPackageElementBuilder builder = MediaPackageElementBuilderFactory.newInstance().newElementBuilder(); // Set up our arguments and return values audioTrack = (Track) builder.newElement(Track.TYPE, MediaPackageElements.PRESENTATION_SOURCE); audioTrack.setIdentifier("audio1"); videoTrack = (Track) builder.newElement(Track.TYPE, MediaPackageElements.PRESENTATION_SOURCE); videoTrack.setIdentifier("video1"); profileId = "profile1"; job = new JobImpl(1); job.setStatus(Job.Status.QUEUED); job.setJobType(ComposerService.JOB_TYPE); profile = new EncodingProfileImpl(); profile.setIdentifier(profileId); List<EncodingProfileImpl> list = new ArrayList<EncodingProfileImpl>(); list.add(profile); profileList = new EncodingProfileList(list); // Train a mock composer with some known behavior ComposerService composer = EasyMock.createNiceMock(ComposerService.class); EasyMock.expect(composer.encode(videoTrack, profileId)).andReturn(job).anyTimes(); EasyMock.expect(composer.mux(videoTrack, audioTrack, profileId)).andReturn(job).anyTimes(); EasyMock.expect(composer.listProfiles()).andReturn(list.toArray(new EncodingProfile[list.size()])); EasyMock.expect(composer.getProfile(profileId)).andReturn(profile); EasyMock.expect(composer.concat(EasyMock.eq(profileId), EasyMock.eq(new Dimension(640, 480)), (Track) EasyMock.notNull(), (Track) EasyMock.notNull())).andReturn(job); EasyMock.expect(composer.concat(EasyMock.eq(profileId), EasyMock.eq(new Dimension(640, 480)), EasyMock.gt(0.0f), (Track) EasyMock.notNull(), (Track) EasyMock.notNull())).andReturn(job); EasyMock.replay(composer); // Set up the rest endpoint restService = new ComposerRestService(); restService.setComposerService(composer); restService.activate(null); } @Test public void testMissingArguments() throws Exception { // Ensure the rest endpoint tests for missing parameters Response response = restService.encode(generateVideoTrack(), null); Assert.assertEquals(Status.BAD_REQUEST.getStatusCode(), response.getStatus()); response = restService.encode(null, "profile"); Assert.assertEquals(Status.BAD_REQUEST.getStatusCode(), response.getStatus()); response = restService.mux(generateAudioTrack(), null, "profile"); Assert.assertEquals(Status.BAD_REQUEST.getStatusCode(), response.getStatus()); response = restService.mux(null, generateVideoTrack(), "profile"); Assert.assertEquals(Status.BAD_REQUEST.getStatusCode(), response.getStatus()); response = restService.mux(generateAudioTrack(), generateVideoTrack(), null); Assert.assertEquals(Status.BAD_REQUEST.getStatusCode(), response.getStatus()); } @Test public void testEncode() throws Exception { Response response = restService.encode(generateVideoTrack(), profileId); Assert.assertEquals(Response.Status.OK.getStatusCode(), response.getStatus()); Assert.assertEquals(new JaxbJob(job), response.getEntity()); } @Test public void testMux() throws Exception { Response response = restService.mux(generateAudioTrack(), generateVideoTrack(), profileId); Assert.assertEquals(Response.Status.OK.getStatusCode(), response.getStatus()); Assert.assertEquals(new JaxbJob(job), response.getEntity()); } @Test public void testProfiles() throws Exception { Response response = restService.getProfile(profileId); Assert.assertEquals(Response.Status.OK.getStatusCode(), response.getStatus()); Assert.assertEquals(profile, response.getEntity()); try { restService.getProfile("some other ID"); Assert.fail("This ID should cause the rest endpoint to throw"); } catch (NotFoundException e) { // expected } EncodingProfileList list = restService.listProfiles(); Assert.assertEquals(profileList, list); } @Test public void testConcat() throws Exception { Dimension dimension = new Dimension(640, 480); Track videoTrack = (Track) MediaPackageElementParser.getFromXml(generateVideoTrack()); String sourceTracks = MediaPackageElementParser.getArrayAsXml(Collections.list(videoTrack, videoTrack)); Response response = restService.concat(sourceTracks, profileId, Serializer.json(dimension).toJson(), "25"); Assert.assertEquals(Response.Status.OK.getStatusCode(), response.getStatus()); Assert.assertNotNull("Concat rest endpoint should send a job in response", response.getEntity()); } protected String generateVideoTrack() { return "<track xmlns=\"http://mediapackage.opencastproject.org\" id=\"video1\" type=\"presentation/source\">\n" + " <mimetype>video/quicktime</mimetype>\n" + " <url>serverUrl/workflow/samples/camera.mpg</url>\n" + " <checksum type=\"md5\">43b7d843b02c4a429b2f547a4f230d31</checksum>\n" + " <duration>14546</duration>\n" + " <video>\n" + " <device type=\"UFG03\" version=\"30112007\" vendor=\"Unigraf\" />\n" + " <encoder type=\"H.264\" version=\"7.4\" vendor=\"Apple Inc\" />\n" + " <resolution>640x480</resolution>\n" + " <scanType type=\"progressive\" />\n" + " <bitrate>540520</bitrate>\n" + " <frameRate>2</frameRate>\n" + " </video>\n" + "</track>"; } protected String generateAudioTrack() { return "<track xmlns=\"http://mediapackage.opencastproject.org\" id=\"audio1\" type=\"presentation/source\">\n" + " <mimetype>audio/mp3</mimetype>\n" + " <url>serverUrl/workflow/samples/audio.mp3</url>\n" + " <checksum type=\"md5\">950f9fa49caa8f1c5bbc36892f6fd062</checksum>\n" + " <duration>10472</duration>\n" + " <audio>\n" + " <channels>2</channels>\n" + " <bitdepth>0</bitdepth>\n" + " <bitrate>128004.0</bitrate>\n" + " <samplingrate>44100</samplingrate>\n" + " </audio>\n" + "</track>"; } }