/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache 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://www.apache.org/licenses/LICENSE-2.0
*
* 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.apache.sling.installer.core.impl;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Collections;
import java.util.Dictionary;
import java.util.Hashtable;
import org.apache.sling.installer.api.InstallableResource;
import org.apache.sling.installer.api.tasks.RegisteredResource;
import org.apache.sling.installer.api.tasks.TaskResource;
import org.apache.sling.installer.api.tasks.TransformationResult;
import org.junit.Test;
import org.osgi.framework.BundleContext;
import org.osgi.framework.Constants;
public class RegisteredResourceTest {
public static final String TEST_URL = "test:url";
static File getTestBundle(String name) {
return new File(System.getProperty("osgi.installer.base.dir"),
"org.apache.sling.installer.core-" + System.getProperty("osgi.installer.pom.version") + "-" + name);
}
@org.junit.Test public void testResourceType() throws Exception {
{
final InputStream s = new FileInputStream(getTestBundle("testbundle-1.0.jar"));
final RegisteredResource r = create(new InstallableResource("test:1.jar", s, null, "some digest", null, null));
assertEquals(".jar URL creates a BUNDLE resource",
InstallableResource.TYPE_BUNDLE, r.getType());
final InputStream rs = r.getInputStream();
assertNotNull("BUNDLE resource provides an InputStream", rs);
rs.close();
assertNull("BUNDLE resource does not provide a Dictionary", r.getDictionary());
assertEquals("RegisteredResource entity ID must match", "bundle:osgi-installer-testbundle", r.getEntityId());
}
{
final Hashtable<String, Object> data = new Hashtable<String, Object>();
data.put("foo", "bar");
data.put("other", 2);
final TaskResource r = create(new InstallableResource("configuration:1", null, data, null, null, null));
assertEquals("No-extension URL with Dictionary creates a CONFIG resource",
InstallableResource.TYPE_CONFIG, r.getType());
final InputStream rs = r.getInputStream();
assertNull("CONFIG resource does not provide an InputStream", rs);
final Dictionary<String, Object> d = r.getDictionary();
assertNotNull("CONFIG resource provides a Dictionary", d);
assertEquals("CONFIG resource dictionary has two properties", 2, d.size());
assertNotNull("CONFIG resource has a pid attribute", r.getAttribute(Constants.SERVICE_PID));
}
}
@org.junit.Test public void testLocalFileCopy() throws Exception {
final File localFile = File.createTempFile("testLocalFileCopy", ".data");
localFile.deleteOnExit();
final BundleContext bc = new MockBundleContext();
final File f = getTestBundle("testbundle-1.0.jar");
final InputStream s = new FileInputStream(f);
FileDataStore.SHARED = new FileDataStore(bc) {
@Override
public File createNewDataFile(InputStream stream, String url,
String digest, String hint) throws IOException {
this.copyToLocalStorage(stream, localFile);
return localFile;
}
};
InternalResource.create("test", new InstallableResource("test:1.jar", s, null, "somedigest", null, null));
assertTrue("Local file exists", localFile.exists());
assertEquals("Local file length matches our data", f.length(), localFile.length());
}
@org.junit.Test public void testMissingDigest() throws Exception {
final String data = "This is some data";
final InputStream in = new ByteArrayInputStream(data.getBytes());
create(new InstallableResource("test:1.jar", in, null, null, null, null));
assertNotNull(create(new InstallableResource("test:1.jar", in, null, null, null, null)).getDigest());
}
@org.junit.Test public void testBundleManifest() throws Exception {
final File f = getTestBundle("testbundle-1.0.jar");
final InstallableResource i = new InstallableResource("test:" + f.getAbsolutePath(), new FileInputStream(f), null, f.getName(), null, null);
final TaskResource r = create(i);
assertNotNull("RegisteredResource must have bundle symbolic name", r.getAttribute(Constants.BUNDLE_SYMBOLICNAME));
assertEquals("RegisteredResource entity ID must match", "bundle:osgi-installer-testbundle", r.getEntityId());
}
// @org.junit.Test
public void testConfigEntity() throws Exception {
final InstallableResource i = new InstallableResource("test:/foo/someconfig", null, new Hashtable<String, Object>(), null, null, null);
final TaskResource r = create(i);
assertNull("RegisteredResource must not have bundle symbolic name", r.getAttribute(Constants.BUNDLE_SYMBOLICNAME));
assertEquals("RegisteredResource entity ID must match", "config:someconfig", r.getEntityId());
}
@org.junit.Test public void testConfigDigestIncludesUrl() throws Exception {
final Dictionary<String, Object> data = new Hashtable<String, Object>();
final InstallableResource rA = new InstallableResource("test:urlA", null, data, null, null, null);
final InstallableResource rB = new InstallableResource("test:urlB", null, data, null, null, null);
assertTrue(
"Expecting configs with same data but different URLs to have same digests",
create(rA).getDigest().equals(create(rB).getDigest()));
}
@Test
public void testDictionaryDigest() throws IOException {
final Dictionary<String, Object> d = new Hashtable<String, Object>();
final InstallableResource r = new InstallableResource("x:url", null, d, null, null, null);
assertNotNull("Expected RegisteredResource to compute its own digest", create(r).getDigest());
}
@org.junit.Test public void testDictionaryDigestFromDictionaries() throws Exception {
final Hashtable<String, Object> d1 = new Hashtable<String, Object>();
final Hashtable<String, Object> d2 = new Hashtable<String, Object>();
final String [] keys = { "foo", "bar", "something" };
for(int i=0 ; i < keys.length; i++) {
d1.put(keys[i], keys[i] + "." + keys[i]);
}
for(int i=keys.length - 1 ; i >= 0; i--) {
d2.put(keys[i], keys[i] + "." + keys[i]);
}
final InstallableResource r1 = new InstallableResource("test:url1", null, d1, null, null, null);
final InstallableResource r2 = new InstallableResource("test:url1", null, d2, null, null, null);
assertEquals(
"Two InstallableResource (Dictionary) with same values but different key orderings must have the same key",
create(r1).getDigest(),
create(r2).getDigest()
);
}
private TaskResource create(final InstallableResource is) throws IOException {
new FileDataStore(new MockBundleContext());
final InternalResource internal = InternalResource.create("test", is);
final RegisteredResourceImpl rr = RegisteredResourceImpl.create(internal);
final TransformationResult[] tr = new DefaultTransformer().transform(rr);
if ( tr != null ) {
return rr.clone(tr[0]);
} else if ( is.getId().startsWith("configuration:") ) {
final TransformationResult result = new TransformationResult();
result.setId(is.getId().substring(14));
result.setResourceType(InstallableResource.TYPE_CONFIG);
result.setAttributes(Collections.singletonMap(Constants.SERVICE_PID, (Object)result.getId()));
return rr.clone(result);
}
return rr;
}
}