package org.exist.dom.persistent; import org.exist.storage.BrokerPool; import org.exist.storage.BrokerPoolServiceException; import org.exist.storage.io.VariableByteInput; import org.easymock.Capture; import org.exist.storage.io.VariableByteOutputStream; import org.easymock.EasyMock; import java.io.IOException; import java.nio.file.Path; import java.nio.file.Paths; import org.exist.EXistException; import org.exist.util.Configuration; import org.junit.Test; import static org.easymock.EasyMock.*; import static org.junit.Assert.assertEquals; /** * @author Adam Retter <adam@exist-db.org> */ public class SymbolTableTest { private final Path tmpDir = Paths.get(System.getProperty("java.io.tmpdir")); private final SymbolTable createSymbolTable() throws BrokerPoolServiceException { final SymbolTable symbolTable = new SymbolTable(); final Configuration configuration = createMock(Configuration.class); expect(configuration.getProperty(BrokerPool.PROPERTY_DATA_DIR)).andReturn(tmpDir); replay(configuration); symbolTable.configure(configuration); symbolTable.prepare(null); return symbolTable; } @Test public void getName_returns_empty_string_when_id_is_zero() throws EXistException, IOException, BrokerPoolServiceException { final SymbolTable symbolTable = createSymbolTable(); assertEquals("", symbolTable.getName((short)0)); symbolTable.close(); } @Test public void getNameSpace_returns_empty_string_when_id_is_zero() throws EXistException, BrokerPoolServiceException { final SymbolTable symbolTable = createSymbolTable(); assertEquals("", symbolTable.getNamespace((short)0)); } @Test public void geMimeType_returns_empty_string_when_id_is_zero() throws EXistException, IOException, BrokerPoolServiceException { final SymbolTable symbolTable = createSymbolTable(); assertEquals("", symbolTable.getMimeType((short)0)); symbolTable.close(); } @Test(expected=IllegalArgumentException.class) public void getSymbol_for_localName_throws_exception_when_name_is_empty_string() throws EXistException, IOException, BrokerPoolServiceException { final SymbolTable symbolTable = createSymbolTable(); symbolTable.getSymbol(""); symbolTable.close(); } @Test public void getNSSymbol_returns_zero_when_namespace_is_null() throws EXistException, IOException, BrokerPoolServiceException { final SymbolTable symbolTable = createSymbolTable(); assertEquals(0, symbolTable.getNSSymbol(null)); symbolTable.close(); } @Test public void getNSSymbol_returns_zero_when_namespace_is_empty_string() throws EXistException, IOException, BrokerPoolServiceException { final SymbolTable symbolTable = createSymbolTable(); assertEquals(0, symbolTable.getNSSymbol("")); symbolTable.close(); } @Test public void localName_ids_are_stable() throws EXistException, IOException, BrokerPoolServiceException { SymbolTable symbolTable = createSymbolTable(); final String localName = "some-name"; final short localNameId = symbolTable.getSymbol(localName); symbolTable.close(); symbolTable = createSymbolTable(); final String roundTrippedLocalName = symbolTable.getName(localNameId); symbolTable.close(); assertEquals(localName, roundTrippedLocalName); } @Test public void namespace_ids_are_stable() throws EXistException, IOException, BrokerPoolServiceException { SymbolTable symbolTable = createSymbolTable(); final String namespace = "http://something/or/other"; final short namespaceId = symbolTable.getNSSymbol(namespace); symbolTable.close(); symbolTable = createSymbolTable(); final String roundTrippedNamespace = symbolTable.getNamespace(namespaceId); symbolTable.close(); assertEquals(namespace, roundTrippedNamespace); } @Test public void mimetype_ids_are_stable() throws EXistException, IOException, BrokerPoolServiceException { SymbolTable symbolTable = createSymbolTable(); final String mimetype = "something/other"; final int mimetypeId = symbolTable.getMimeTypeId(mimetype); symbolTable.close(); symbolTable = createSymbolTable(); final String roundTrippedMimetype = symbolTable.getMimeType(mimetypeId); symbolTable.close(); assertEquals(mimetype, roundTrippedMimetype); } @Test public void write_and_read_are_balanced() throws EXistException, IOException, BrokerPoolServiceException { final SymbolTable symbolTable = createSymbolTable(); symbolTable.getSymbol("some-name"); VariableByteOutputStream mockOs = createMock(VariableByteOutputStream.class); VariableByteInput mockIs = createMock(VariableByteInput.class); final Capture<Byte> byteCapture = new Capture<Byte>(); final Capture<Integer> intCapture = new Capture<Integer>(); final Capture<String> strCapture = new Capture<String>(); //write expectations mockOs.writeByte(captureByte(byteCapture)); mockOs.writeInt(captureInt(intCapture)); mockOs.writeUTF(capture(strCapture)); replay(mockOs); symbolTable.localNameSymbols.write(mockOs); verify(mockOs); //read expectations expect(mockIs.available()).andReturn(1); expect(mockIs.readByte()).andReturn(byteCapture.getValue()); expect(mockIs.readInt()).andReturn(intCapture.getValue()); expect(mockIs.readUTF()).andReturn(strCapture.getValue()); expect(mockIs.available()).andReturn(0); replay(mockIs); symbolTable.read(mockIs); verify(mockIs); } @Test public void readLegacyFormat() throws EXistException, IOException, BrokerPoolServiceException { final SymbolTable symbolTable = createSymbolTable(); VariableByteInput mockIs = createMock(VariableByteInput.class); /* readLegacy expectations */ //max and nsMax expect(mockIs.readShort()).andReturn((short)1); expect(mockIs.readShort()).andReturn((short)1); //localnames expect(mockIs.readInt()).andReturn(1); expect(mockIs.readUTF()).andReturn("local-name"); expect(mockIs.readShort()).andReturn((short)67); //namespaces expect(mockIs.readInt()).andReturn(1); expect(mockIs.readUTF()).andReturn("http://some/or/other"); expect(mockIs.readShort()).andReturn((short)77); //default mappings expect(mockIs.readInt()).andReturn(1); expect(mockIs.readUTF()).andReturn("mapping"); expect(mockIs.readShort()).andReturn((short)87); //mimetypes expect(mockIs.readInt()).andReturn(1); expect(mockIs.readUTF()).andReturn("some/other"); expect(mockIs.readInt()).andReturn(97); //replay replay(mockIs); //action symbolTable.readLegacy(mockIs); //verify verify(mockIs); symbolTable.close(); } }