Esempio n. 1
0
def storage_persistent(storage_empty, outgoing):
    storage = storage_empty
    
    storage.setEntryTypeValue("boolean/True", Value.makeBoolean(True))
    storage.setEntryTypeValue("boolean/False", Value.makeBoolean(False))
    storage.setEntryTypeValue("double/neg", Value.makeDouble(-1.5))
    storage.setEntryTypeValue("double/zero", Value.makeDouble(0.0))
    storage.setEntryTypeValue("double/big", Value.makeDouble(1.3e8))
    storage.setEntryTypeValue("string/empty", Value.makeString(""))
    storage.setEntryTypeValue("string/normal", Value.makeString("hello"))
    storage.setEntryTypeValue("string/special", Value.makeString("\0\3\5\n"))
    storage.setEntryTypeValue("raw/empty", Value.makeRaw(b""))
    storage.setEntryTypeValue("raw/normal", Value.makeRaw(b"hello"))
    storage.setEntryTypeValue("raw/special", Value.makeRaw(b"\0\3\5\n"))
    storage.setEntryTypeValue("booleanarr/empty", Value.makeBooleanArray([]))
    storage.setEntryTypeValue("booleanarr/one", Value.makeBooleanArray([True]))
    storage.setEntryTypeValue("booleanarr/two", Value.makeBooleanArray([True, False]))
    storage.setEntryTypeValue("doublearr/empty", Value.makeDoubleArray([]))
    storage.setEntryTypeValue("doublearr/one", Value.makeDoubleArray([0.5]))
    storage.setEntryTypeValue("doublearr/two", Value.makeDoubleArray([0.5, -0.25]))
    storage.setEntryTypeValue("stringarr/empty", Value.makeStringArray([]))
    storage.setEntryTypeValue("stringarr/one", Value.makeStringArray(["hello"]))
    storage.setEntryTypeValue("stringarr/two", Value.makeStringArray(["hello", "world\n"]))
    storage.setEntryTypeValue("\0\3\5\n",Value.makeBoolean(True))
    del outgoing[:]
    
    return storage
def test_EntryNewRemote(nt_live, server_cb):
    nt_server, nt_client = nt_live
    nt_server_api = nt_server._api
    nt_client_api = nt_client._api

    nt_server_api.addEntryListenerById(
        nt_server_api.getEntryId("/foo"), server_cb, NT_NOTIFY_NEW
    )

    # Trigger an event
    nt_client_api.setEntryValueById(
        nt_client_api.getEntryId("/foo/bar"), Value.makeDouble(2.0)
    )
    nt_client_api.setEntryValueById(
        nt_client_api.getEntryId("/foo"), Value.makeDouble(1.0)
    )

    nt_client_api.flush()

    assert nt_server_api.waitForEntryListenerQueue(1.0)

    # Check the event
    events = server_cb.wait(1)

    # assert events[0].listener == handle
    assert events[0].local_id == nt_server_api.getEntryId("/foo")
    assert events[0].name == "/foo"
    assert events[0].value == Value.makeDouble(1.0)
    assert events[0].flags == NT_NOTIFY_NEW
Esempio n. 3
0
def test_LoadPersistentUpdateValueFlags(storage_populated, outgoing, is_server):
    storage = storage_populated
    
    fp = StringIO("[NetworkTables Storage 3.0]\ndouble \"foo2\"=1.0\n")
    assert storage.loadPersistent(fp=fp) is None
    
    entry = storage.m_entries.get("foo2")
    assert Value.makeDouble(1.0) == entry.value
    assert NT_PERSISTENT == entry.flags

    if is_server:
        assert 2 == len(outgoing)
        assert not outgoing[0].only
        assert not outgoing[0].conn
        msg = outgoing[0].msg
        assert kEntryUpdate == msg.type
        assert 1 == msg.id  # assigned as server
        assert 2 == msg.seq_num_uid  # incremented
        assert Value.makeDouble(1.0) == msg.value

        assert not outgoing[1].only
        assert not outgoing[1].conn
        msg = outgoing[1].msg
        assert kFlagsUpdate == msg.type
        assert 1 == msg.id  # assigned as server
        assert NT_PERSISTENT == msg.flags

    else:
        # shouldn't send an update id not assigned yet (happens on client only)
        assert len(outgoing) == 0
        assert 2 == storage.m_entries.get("foo2").seq_num  # still should be incremented
def test_EntryNewRemote(nt_live, server_cb):
    nt_server, nt_client = nt_live
    nt_server_api = nt_server._api
    nt_client_api = nt_client._api

    nt_server_api.addEntryListenerById(nt_server_api.getEntryId("/foo"),
                                       server_cb, NT_NOTIFY_NEW)

    # Trigger an event
    nt_client_api.setEntryValueById(nt_client_api.getEntryId("/foo/bar"),
                                    Value.makeDouble(2.0))
    nt_client_api.setEntryValueById(nt_client_api.getEntryId("/foo"),
                                    Value.makeDouble(1.0))

    nt_client_api.flush()

    assert nt_server_api.waitForEntryListenerQueue(1.0)

    # Check the event
    events = server_cb.wait(1)

    #assert events[0].listener == handle
    assert events[0].local_id == nt_server_api.getEntryId("/foo")
    assert events[0].name == "/foo"
    assert events[0].value == Value.makeDouble(1.0)
    assert events[0].flags == NT_NOTIFY_NEW
Esempio n. 5
0
def test_Double():
    v = Value.makeDouble(0.5)
    assert NT_DOUBLE == v.type
    assert 0.5 == v.value

    v = Value.makeDouble(0.25)
    assert NT_DOUBLE == v.type
    assert 0.25 == v.value
Esempio n. 6
0
def test_Double():
    v = Value.makeDouble(0.5)
    assert NT_DOUBLE == v.type
    assert 0.5 == v.value

    v = Value.makeDouble(0.25)
    assert NT_DOUBLE == v.type
    assert 0.25 == v.value
Esempio n. 7
0
def storage_populated(storage_empty, outgoing):
    storage = storage_empty
    
    storage.setEntryTypeValue("foo", Value.makeBoolean(True))
    storage.setEntryTypeValue("foo2", Value.makeDouble(0.0))
    storage.setEntryTypeValue("bar", Value.makeDouble(1.0))
    storage.setEntryTypeValue("bar2", Value.makeBoolean(False))
    del outgoing[:]

    return storage
Esempio n. 8
0
def test_loadPersistent(storage_empty, outgoing):
    storage = storage_empty
    
    inp = "[NetworkTables Storage 3.0]\n"
    inp += "boolean \"\\x00\\x03\\x05\\n\"=true\n"
    inp += "boolean \"boolean/false\"=false\n"
    inp += "boolean \"boolean/true\"=true\n"
    inp += "array boolean \"booleanarr/empty\"=\n"
    inp += "array boolean \"booleanarr/one\"=true\n"
    inp += "array boolean \"booleanarr/two\"=true,false\n"
    inp += "double \"double/big\"=1.3e+08\n"
    inp += "double \"double/neg\"=-1.5\n"
    inp += "double \"double/zero\"=0\n"
    inp += "array double \"doublearr/empty\"=\n"
    inp += "array double \"doublearr/one\"=0.5\n"
    inp += "array double \"doublearr/two\"=0.5,-0.25\n"
    inp += "raw \"raw/empty\"=\n"
    inp += "raw \"raw/normal\"=aGVsbG8=\n"
    inp += "raw \"raw/special\"=AAMFCg==\n"
    inp += "string \"string/empty\"=\"\"\n"
    inp += "string \"string/normal\"=\"hello\"\n"
    inp += "string \"string/special\"=\"\\x00\\x03\\x05\\n\"\n"
    inp += "array string \"stringarr/empty\"=\n"
    inp += "array string \"stringarr/one\"=\"hello\"\n"
    inp += "array string \"stringarr/two\"=\"hello\",\"world\\n\"\n"

    fp = StringIO(inp)
    assert storage.loadPersistent(fp=fp) is None
    
    assert 21 == len(storage.m_entries)
    assert 21 == len(outgoing)

    assert Value.makeBoolean(True) == storage.getEntryValue("boolean/true")
    assert Value.makeBoolean(False) == storage.getEntryValue("boolean/false")
    assert Value.makeDouble(-1.5) == storage.getEntryValue("double/neg")
    assert Value.makeDouble(0.0) == storage.getEntryValue("double/zero")
    assert Value.makeDouble(1.3e8) == storage.getEntryValue("double/big")
    assert Value.makeString("") == storage.getEntryValue("string/empty")
    assert Value.makeString("hello") == storage.getEntryValue("string/normal")
    assert Value.makeString("\0\3\5\n") == storage.getEntryValue("string/special")
    assert Value.makeRaw(b"") == storage.getEntryValue("raw/empty")
    assert Value.makeRaw(b"hello") == storage.getEntryValue("raw/normal")
    assert Value.makeRaw(b"\0\3\5\n") == storage.getEntryValue("raw/special")
    assert Value.makeBooleanArray([]) == storage.getEntryValue("booleanarr/empty")
    assert Value.makeBooleanArray([True]) == storage.getEntryValue("booleanarr/one")
    assert Value.makeBooleanArray([True, False]) == storage.getEntryValue("booleanarr/two")
    assert Value.makeDoubleArray([]) == storage.getEntryValue("doublearr/empty")
    assert Value.makeDoubleArray([0.5]) == storage.getEntryValue("doublearr/one")
    assert Value.makeDoubleArray([0.5, -0.25]) == storage.getEntryValue("doublearr/two")
    assert Value.makeStringArray([]) == storage.getEntryValue("stringarr/empty")
    assert Value.makeStringArray(["hello"]) == storage.getEntryValue("stringarr/one")
    assert Value.makeStringArray(["hello", "world\n"]) == storage.getEntryValue("stringarr/two")
    assert Value.makeBoolean(True) == storage.getEntryValue("\0\3\5\n")
Esempio n. 9
0
def test_ProcessIncomingEntryAssignWithFlags(storage_populate_one, dispatcher,
                                             entry_notifier, is_server, conn):
    storage = storage_populate_one
    value = Value.makeDouble(1.0)

    storage.processIncoming(Message.entryAssign("foo", 0, 1, value, 0x2), conn)

    #EXPECT_CALL(*conn, proto_rev()).WillRepeatedly(Return(0x0300u))
    if is_server:
        # server broadcasts new value/flags to all *other* connections
        dispatcher._queueOutgoing.assert_has_calls([
            call(Message.entryAssign("foo", 0, 1, value, 0x2), None, conn),
        ])

        entry_notifier.notifyEntry.assert_has_calls([
            call(0, "foo", value, NT_NOTIFY_UPDATE | NT_NOTIFY_FLAGS),
        ])

    else:
        # client forces flags back when an assign message is received for an
        # existing entry with different flags
        dispatcher._queueOutgoing.assert_has_calls([
            call(Message.flagsUpdate(0, 0), None, None),
        ])

        entry_notifier.notifyEntry.assert_has_calls([
            call(0, "foo", value, NT_NOTIFY_UPDATE),
        ])
Esempio n. 10
0
def storage_populated(storage_empty, dispatcher, entry_notifier):
    storage = storage_empty

    entry_notifier.m_local_notifiers = False

    entry_notifier.m_local_notifiers = False
    storage.setEntryTypeValue("foo", Value.makeBoolean(True))
    storage.setEntryTypeValue("foo2", Value.makeDouble(0.0))
    storage.setEntryTypeValue("bar", Value.makeDouble(1.0))
    storage.setEntryTypeValue("bar2", Value.makeBoolean(False))

    dispatcher.reset_mock()
    entry_notifier.reset_mock()
    entry_notifier.m_local_notifiers = True

    return storage
Esempio n. 11
0
 def forceSetDouble(self, value):
     """Sets the entry's value.
     
     :param value: the value to set
     """
     value = Value.makeDouble(value)
     return self.__api.setEntryTypeValueById(self._local_id, value)
Esempio n. 12
0
 def forceSetDouble(self, value):
     """Sets the entry's value.
     
     :param value: the value to set
     """
     value = Value.makeDouble(value)
     return self.__api.setEntryTypeValueById(self._local_id, value)
Esempio n. 13
0
def test_SetEntryValueDifferentValue(storage_populated, is_server, dispatcher,
                                     entry_notifier):
    storage = storage_populated

    # update with same type and different value results in value update message
    value = Value.makeDouble(1.0)
    assert storage.setEntryValue("foo2", value)
    entry = storage.m_entries.get("foo2")
    assert value == entry.value

    # client shouldn't send an update as id not assigned yet
    if is_server:
        # id assigned if server; seq_num incremented
        dispatcher._queueOutgoing.assert_has_calls([
            call(Message.entryUpdate(1, 2, value), None, None),
        ])
    else:
        assert dispatcher._queueOutgoing.call_count == 0

    entry_notifier.notifyEntry.assert_has_calls([
        call(1, "foo2", value, NT_NOTIFY_UPDATE | NT_NOTIFY_LOCAL),
    ])

    if not is_server:
        assert 2 == storage.m_entries.get(
            "foo2").seq_num  # still should be incremented
Esempio n. 14
0
def test_DeleteEntryExist(storage_populated, dispatcher, entry_notifier, is_server):
    storage = storage_populated

    storage.deleteEntry("foo2")

    entry = storage.m_entries.get("foo2")
    assert entry is not None
    assert entry.value is None
    assert entry.id == 0xFFFF
    assert entry.local_write == False

    # client shouldn't send an update as id not assigned yet
    if is_server:
        # id assigned as this is the server
        dispatcher._queueOutgoing.assert_has_calls(
            [call(Message.entryDelete(1), None, None)]
        )
    else:
        # shouldn't send an update id not assigned yet
        assert dispatcher._queueOutgoing.call_count == 0

    entry_notifier.notifyEntry.assert_has_calls(
        [call(1, "foo2", Value.makeDouble(0.0), NT_NOTIFY_DELETE | NT_NOTIFY_LOCAL)]
    )

    if is_server:
        assert len(storage.m_idmap) >= 2
        assert not storage.m_idmap[1]
Esempio n. 15
0
def test_ProcessIncomingEntryAssignWithFlags(
    storage_populate_one, dispatcher, entry_notifier, is_server, conn
):
    storage = storage_populate_one
    value = Value.makeDouble(1.0)

    storage.processIncoming(Message.entryAssign("foo", 0, 1, value, 0x2), conn)

    # EXPECT_CALL(*conn, proto_rev()).WillRepeatedly(Return(0x0300u))
    if is_server:
        # server broadcasts new value/flags to all *other* connections
        dispatcher._queueOutgoing.assert_has_calls(
            [call(Message.entryAssign("foo", 0, 1, value, 0x2), None, conn)]
        )

        entry_notifier.notifyEntry.assert_has_calls(
            [call(0, "foo", value, NT_NOTIFY_UPDATE | NT_NOTIFY_FLAGS)]
        )

    else:
        # client forces flags back when an assign message is received for an
        # existing entry with different flags
        dispatcher._queueOutgoing.assert_has_calls(
            [call(Message.flagsUpdate(0, 0), None, None)]
        )

        entry_notifier.notifyEntry.assert_has_calls(
            [call(0, "foo", value, NT_NOTIFY_UPDATE)]
        )
Esempio n. 16
0
def test_SetEntryValueDifferentValue(
    storage_populated, is_server, dispatcher, entry_notifier
):
    storage = storage_populated

    # update with same type and different value results in value update message
    value = Value.makeDouble(1.0)
    assert storage.setEntryValue("foo2", value)
    entry = storage.m_entries.get("foo2")
    assert value == entry.value

    # client shouldn't send an update as id not assigned yet
    if is_server:
        # id assigned if server; seq_num incremented
        dispatcher._queueOutgoing.assert_has_calls(
            [call(Message.entryUpdate(1, 2, value), None, None)]
        )
    else:
        assert dispatcher._queueOutgoing.call_count == 0

    entry_notifier.notifyEntry.assert_has_calls(
        [call(1, "foo2", value, NT_NOTIFY_UPDATE | NT_NOTIFY_LOCAL)]
    )

    if not is_server:
        assert 2 == storage.m_entries.get("foo2").seq_num  # still should be incremented
Esempio n. 17
0
def storage_populated(storage_empty, dispatcher, entry_notifier):
    storage = storage_empty

    entry_notifier.m_local_notifiers = False

    entry_notifier.m_local_notifiers = False
    storage.setEntryTypeValue("foo", Value.makeBoolean(True))
    storage.setEntryTypeValue("foo2", Value.makeDouble(0.0))
    storage.setEntryTypeValue("bar", Value.makeDouble(1.0))
    storage.setEntryTypeValue("bar2", Value.makeBoolean(False))

    dispatcher.reset_mock()
    entry_notifier.reset_mock()
    entry_notifier.m_local_notifiers = True

    return storage
Esempio n. 18
0
def test_LoadPersistentUpdateValueFlags(storage_populated, dispatcher,
                                        entry_notifier, is_server):
    storage = storage_populated

    fp = StringIO("[NetworkTables Storage 3.0]\ndouble \"foo2\"=1.0\n")
    assert storage.loadPersistent(fp=fp) is None

    entry = storage.m_entries.get("foo2")
    assert Value.makeDouble(1.0) == entry.value
    assert NT_PERSISTENT == entry.flags

    # client shouldn't send an update as id not assigned yet
    if is_server:
        # id assigned as this is the server; seq_num incremented
        dispatcher._queueOutgoing.assert_has_calls([
            call(Message.entryUpdate(1, 2, entry.value), None, None),
            call(Message.flagsUpdate(1, NT_PERSISTENT), None, None),
        ])
    else:
        assert dispatcher._queueOutgoing.call_count == 0

    entry_notifier.notifyEntry.assert_has_calls([
        call(1, "foo2", entry.value,
             NT_NOTIFY_FLAGS | NT_NOTIFY_UPDATE | NT_NOTIFY_LOCAL)
    ])

    if not is_server:
        assert 2 == storage.m_entries.get(
            "foo2").seq_num  # still should be incremented
Esempio n. 19
0
def test_DeleteEntryExist(storage_populated, dispatcher, entry_notifier,
                          is_server):
    storage = storage_populated

    storage.deleteEntry("foo2")

    entry = storage.m_entries.get("foo2")
    assert entry is not None
    assert entry.value is None
    assert entry.id == 0xffff
    assert entry.local_write == False

    # client shouldn't send an update as id not assigned yet
    if is_server:
        # id assigned as this is the server
        dispatcher._queueOutgoing.assert_has_calls([
            call(Message.entryDelete(1), None, None),
        ])
    else:
        # shouldn't send an update id not assigned yet
        assert dispatcher._queueOutgoing.call_count == 0

    entry_notifier.notifyEntry.assert_has_calls([
        call(1, "foo2", Value.makeDouble(0.0),
             NT_NOTIFY_DELETE | NT_NOTIFY_LOCAL),
    ])

    if is_server:
        assert len(storage.m_idmap) >= 2
        assert not storage.m_idmap[1]
def generateNotifications(notifier):
    # All flags combos that can be generated by Storage
    flags = [
        # "normal" notifications
        NT_NOTIFY_NEW,
        NT_NOTIFY_DELETE,
        NT_NOTIFY_UPDATE,
        NT_NOTIFY_FLAGS,
        NT_NOTIFY_UPDATE | NT_NOTIFY_FLAGS,
        # immediate notifications are always "new"
        NT_NOTIFY_IMMEDIATE | NT_NOTIFY_NEW,
        # local notifications can be of any flag combo
        NT_NOTIFY_LOCAL | NT_NOTIFY_NEW,
        NT_NOTIFY_LOCAL | NT_NOTIFY_DELETE,
        NT_NOTIFY_LOCAL | NT_NOTIFY_UPDATE,
        NT_NOTIFY_LOCAL | NT_NOTIFY_FLAGS,
        NT_NOTIFY_LOCAL | NT_NOTIFY_UPDATE | NT_NOTIFY_FLAGS,
    ]

    # Generate across keys
    keys = ["/foo/bar", "/baz", "/boo"]

    val = Value.makeDouble(1)

    # Provide unique key indexes for each key
    keyindex = 5
    for key in keys:
        for flag in flags:
            notifier.notifyEntry(keyindex, key, val, flag)

        keyindex += 1
Esempio n. 21
0
def test_LoadPersistentUpdateValue(
    storage_populated, dispatcher, entry_notifier, is_server
):
    storage = storage_populated

    entry = storage.m_entries.get("foo2")
    entry.flags = NT_PERSISTENT
    entry.isPersistent = True

    fp = StringIO('[NetworkTables Storage 3.0]\ndouble "foo2"=1.0\n')
    assert storage.loadPersistent(fp=fp) is None

    entry = storage.m_entries.get("foo2")
    assert Value.makeDouble(1.0) == entry.value
    assert NT_PERSISTENT == entry.flags
    assert entry.isPersistent

    # client shouldn't send an update as id not assigned yet
    if is_server:
        # id assigned as this is the server; seq_num incremented
        dispatcher._queueOutgoing.assert_has_calls(
            [call(Message.entryUpdate(1, 2, entry.value), None, None)]
        )
    else:
        assert dispatcher._queueOutgoing.call_count == 0

    entry_notifier.notifyEntry.assert_has_calls(
        [call(1, "foo2", entry.value, NT_NOTIFY_UPDATE | NT_NOTIFY_LOCAL)]
    )

    if not is_server:
        assert 2 == storage.m_entries.get("foo2").seq_num  # still should be incremented
Esempio n. 22
0
def generateNotifications(notifier):
    # All flags combos that can be generated by Storage
    flags = [
        # "normal" notifications
        NT_NOTIFY_NEW,
        NT_NOTIFY_DELETE,
        NT_NOTIFY_UPDATE,
        NT_NOTIFY_FLAGS,
        NT_NOTIFY_UPDATE | NT_NOTIFY_FLAGS,
        # immediate notifications are always "new"
        NT_NOTIFY_IMMEDIATE | NT_NOTIFY_NEW,
        # local notifications can be of any flag combo
        NT_NOTIFY_LOCAL | NT_NOTIFY_NEW,
        NT_NOTIFY_LOCAL | NT_NOTIFY_DELETE,
        NT_NOTIFY_LOCAL | NT_NOTIFY_UPDATE,
        NT_NOTIFY_LOCAL | NT_NOTIFY_FLAGS,
        NT_NOTIFY_LOCAL | NT_NOTIFY_UPDATE | NT_NOTIFY_FLAGS
    ]

    # Generate across keys
    keys = ["/foo/bar", "/baz", "/boo"]

    val = Value.makeDouble(1)

    # Provide unique key indexes for each key
    keyindex = 5
    for key in keys:
        for flag in flags:
            notifier.notifyEntry(keyindex, key, val, flag)

        keyindex += 1
Esempio n. 23
0
 def setDouble(self, value):
     """Sets the entry's value.
     
     :param value: the value to set
     :returns: False if the entry exists with a different type
     """
     value = Value.makeDouble(value)
     return self.__api.setEntryValueById(self._local_id, value)
Esempio n. 24
0
 def setDouble(self, value):
     """Sets the entry's value.
     
     :param value: the value to set
     :returns: False if the entry exists with a different type
     """
     value = Value.makeDouble(value)
     return self.__api.setEntryValueById(self._local_id, value)
Esempio n. 25
0
 def setDefaultDouble(self, defaultValue):
     """Sets the entry's value if it does not exist.
     
     :param defaultValue: the default value to set
     :returns: False if the entry exists with a different type
     """
     value = Value.makeDouble(defaultValue)
     return self.__api.setDefaultEntryValueById(self._local_id, value)
Esempio n. 26
0
 def setDefaultDouble(self, defaultValue):
     """Sets the entry's value if it does not exist.
     
     :param defaultValue: the default value to set
     :returns: False if the entry exists with a different type
     """
     value = Value.makeDouble(defaultValue)
     return self.__api.setDefaultEntryValueById(self._local_id, value)
Esempio n. 27
0
def test_SetEntryValueAssignTypeChange(storage_populate_one, outgoing):
    storage = storage_populate_one
    
    # update with different type results in error and no message
    value = Value.makeDouble(0.0)
    assert not storage.setEntryValue("foo", value)
    entry = storage.m_entries.get("foo")
    assert value != entry.value
    assert len(outgoing) == 0
Esempio n. 28
0
def test_ProcessIncomingEntryAssignIgnore(
    storage_populate_one, dispatcher, entry_notifier, is_server, conn
):
    storage = storage_populate_one
    value = Value.makeDouble(1.0)

    storage.processIncoming(Message.entryAssign("foo", 0xFFFF, 1, value, 0), conn)

    assert dispatcher._queueOutgoing.call_count == 0
    assert entry_notifier.notifyEntry.call_count == 0
Esempio n. 29
0
def test_ProcessIncomingEntryAssignIgnore(storage_populate_one, dispatcher,
                                          entry_notifier, is_server, conn):
    storage = storage_populate_one
    value = Value.makeDouble(1.0)

    storage.processIncoming(Message.entryAssign("foo", 0xffff, 1, value, 0),
                            conn)

    assert dispatcher._queueOutgoing.call_count == 0
    assert entry_notifier.notifyEntry.call_count == 0
Esempio n. 30
0
def test_SetDefaultEntryExistsDifferentType(storage_populate_one, outgoing):
    storage = storage_populate_one
    
    # existing entry is boolean
    value = Value.makeDouble(2.0)
    ret_val = storage.setDefaultEntryValue("foo", value)
    assert not ret_val
    # should not have updated value in table if it already existed.
    assert value != storage.m_entries.get("foo").value

    assert len(outgoing) == 0
Esempio n. 31
0
def test_SetEntryValueAssignTypeChange(storage_populate_one, dispatcher,
                                       entry_notifier):
    storage = storage_populate_one

    # update with different type results in error and no message
    value = Value.makeDouble(0.0)
    assert not storage.setEntryValue("foo", value)
    entry = storage.m_entries.get("foo")
    assert value != entry.value

    assert dispatcher._queueOutgoing.call_count == 0
    assert entry_notifier.notifyEntry.call_count == 0
Esempio n. 32
0
def test_SetDefaultEntryExistsDifferentType(storage_populate_one, dispatcher,
                                            entry_notifier):
    storage = storage_populate_one

    # existing entry is boolean
    value = Value.makeDouble(2.0)
    ret_val = storage.setDefaultEntryValue("foo", value)
    assert not ret_val
    # should not have updated value in table if it already existed.
    assert value != storage.m_entries.get("foo").value

    assert dispatcher._queueOutgoing.call_count == 0
    assert entry_notifier.notifyEntry.call_count == 0
Esempio n. 33
0
def test_SetEntryValueAssignTypeChange(
    storage_populate_one, dispatcher, entry_notifier
):
    storage = storage_populate_one

    # update with different type results in error and no message
    value = Value.makeDouble(0.0)
    assert not storage.setEntryValue("foo", value)
    entry = storage.m_entries.get("foo")
    assert value != entry.value

    assert dispatcher._queueOutgoing.call_count == 0
    assert entry_notifier.notifyEntry.call_count == 0
 def putNumber(self, key, value):
     """Put a number in the table
     
     :param key: the key to be assigned to
     :type key: str
     :param value: the value that will be assigned
     :type value: int, float
     
     :returns: False if the table key already exists with a different type
     :rtype: bool
     """
     path = self._path + key
     return self._api.setEntryValue(path, Value.makeDouble(value))
Esempio n. 35
0
 def putNumber(self, key, value):
     """Put a number in the table
     
     :param key: the key to be assigned to
     :type key: str
     :param value: the value that will be assigned
     :type value: int, float
     
     :returns: False if the table key already exists with a different type
     :rtype: bool
     """
     path = self._path + key
     return self._api.setEntryValue(path, Value.makeDouble(value))
def test_PrefixNewLocal(nt_live, server_cb):
    nt_server, nt_client = nt_live
    nt_server_api = nt_server._api

    nt_server_api.addEntryListener("/foo", server_cb,
                                   NT_NOTIFY_NEW | NT_NOTIFY_LOCAL)

    # Trigger an event
    nt_server_api.setEntryValueById(nt_server_api.getEntryId("/foo/bar"),
                                    Value.makeDouble(1.0))
    nt_server_api.setEntryValueById(nt_server_api.getEntryId("/baz"),
                                    Value.makeDouble(1.0))

    assert nt_server_api.waitForEntryListenerQueue(1.0)

    events = server_cb.wait(1)

    #assert events[0].listener == handle
    assert events[0].local_id == nt_server_api.getEntryId("/foo/bar")
    assert events[0].name == "/foo/bar"
    assert events[0].value == Value.makeDouble(1.0)
    assert events[0].flags == NT_NOTIFY_NEW | NT_NOTIFY_LOCAL
Esempio n. 37
0
def storage_persistent(storage_empty, dispatcher, entry_notifier):
    storage = storage_empty

    entry_notifier.m_local_notifiers = False

    storage.setEntryTypeValue("boolean/true", Value.makeBoolean(True))
    storage.setEntryTypeValue("boolean/false", Value.makeBoolean(False))
    storage.setEntryTypeValue("double/neg", Value.makeDouble(-1.5))
    storage.setEntryTypeValue("double/zero", Value.makeDouble(0.0))
    storage.setEntryTypeValue("double/big", Value.makeDouble(1.3e8))
    storage.setEntryTypeValue("string/empty", Value.makeString(""))
    storage.setEntryTypeValue("string/normal", Value.makeString("hello"))
    storage.setEntryTypeValue("string/special", Value.makeString("\0\3\5\n"))
    storage.setEntryTypeValue("raw/empty", Value.makeRaw(b""))
    storage.setEntryTypeValue("raw/normal", Value.makeRaw(b"hello"))
    storage.setEntryTypeValue("raw/special", Value.makeRaw(b"\0\3\5\n"))
    storage.setEntryTypeValue("booleanarr/empty", Value.makeBooleanArray([]))
    storage.setEntryTypeValue("booleanarr/one", Value.makeBooleanArray([True]))
    storage.setEntryTypeValue("booleanarr/two",
                              Value.makeBooleanArray([True, False]))
    storage.setEntryTypeValue("doublearr/empty", Value.makeDoubleArray([]))
    storage.setEntryTypeValue("doublearr/one", Value.makeDoubleArray([0.5]))
    storage.setEntryTypeValue("doublearr/two",
                              Value.makeDoubleArray([0.5, -0.25]))
    storage.setEntryTypeValue("stringarr/empty", Value.makeStringArray([]))
    storage.setEntryTypeValue("stringarr/one",
                              Value.makeStringArray(["hello"]))
    storage.setEntryTypeValue("stringarr/two",
                              Value.makeStringArray(["hello", "world\n"]))
    storage.setEntryTypeValue("\0\3\5\n", Value.makeBoolean(True))
    storage.setEntryTypeValue("CaseSensitive/KeyName", Value.makeBoolean(True))
    storage.setEntryTypeValue("=", Value.makeBoolean(True))

    dispatcher.reset_mock()
    entry_notifier.reset_mock()
    entry_notifier.m_local_notifiers = True

    return storage
def test_PrefixNewLocal(nt_live, server_cb):
    nt_server, nt_client = nt_live
    nt_server_api = nt_server._api

    nt_server_api.addEntryListener("/foo", server_cb, NT_NOTIFY_NEW | NT_NOTIFY_LOCAL)

    # Trigger an event
    nt_server_api.setEntryValueById(
        nt_server_api.getEntryId("/foo/bar"), Value.makeDouble(1.0)
    )
    nt_server_api.setEntryValueById(
        nt_server_api.getEntryId("/baz"), Value.makeDouble(1.0)
    )

    assert nt_server_api.waitForEntryListenerQueue(1.0)

    events = server_cb.wait(1)

    # assert events[0].listener == handle
    assert events[0].local_id == nt_server_api.getEntryId("/foo/bar")
    assert events[0].name == "/foo/bar"
    assert events[0].value == Value.makeDouble(1.0)
    assert events[0].flags == NT_NOTIFY_NEW | NT_NOTIFY_LOCAL
Esempio n. 39
0
def test_SetDefaultEntryExistsDifferentType(
    storage_populate_one, dispatcher, entry_notifier
):
    storage = storage_populate_one

    # existing entry is boolean
    value = Value.makeDouble(2.0)
    ret_val = storage.setDefaultEntryValue("foo", value)
    assert not ret_val
    # should not have updated value in table if it already existed.
    assert value != storage.m_entries.get("foo").value

    assert dispatcher._queueOutgoing.call_count == 0
    assert entry_notifier.notifyEntry.call_count == 0
Esempio n. 40
0
def storage_persistent(storage_empty, dispatcher, entry_notifier):
    storage = storage_empty

    entry_notifier.m_local_notifiers = False

    storage.setEntryTypeValue("boolean/true", Value.makeBoolean(True))
    storage.setEntryTypeValue("boolean/false", Value.makeBoolean(False))
    storage.setEntryTypeValue("double/neg", Value.makeDouble(-1.5))
    storage.setEntryTypeValue("double/zero", Value.makeDouble(0.0))
    storage.setEntryTypeValue("double/big", Value.makeDouble(1.3e8))
    storage.setEntryTypeValue("string/empty", Value.makeString(""))
    storage.setEntryTypeValue("string/normal", Value.makeString("hello"))
    storage.setEntryTypeValue("string/special", Value.makeString("\0\3\5\n"))
    storage.setEntryTypeValue("string/quoted", Value.makeString('"a"'))
    storage.setEntryTypeValue("raw/empty", Value.makeRaw(b""))
    storage.setEntryTypeValue("raw/normal", Value.makeRaw(b"hello"))
    storage.setEntryTypeValue("raw/special", Value.makeRaw(b"\0\3\5\n"))
    storage.setEntryTypeValue("booleanarr/empty", Value.makeBooleanArray([]))
    storage.setEntryTypeValue("booleanarr/one", Value.makeBooleanArray([True]))
    storage.setEntryTypeValue("booleanarr/two", Value.makeBooleanArray([True, False]))
    storage.setEntryTypeValue("doublearr/empty", Value.makeDoubleArray([]))
    storage.setEntryTypeValue("doublearr/one", Value.makeDoubleArray([0.5]))
    storage.setEntryTypeValue("doublearr/two", Value.makeDoubleArray([0.5, -0.25]))
    storage.setEntryTypeValue("stringarr/empty", Value.makeStringArray([]))
    storage.setEntryTypeValue("stringarr/one", Value.makeStringArray(["hello"]))
    storage.setEntryTypeValue(
        "stringarr/two", Value.makeStringArray(["hello", "world\n"])
    )
    storage.setEntryTypeValue("\0\3\5\n", Value.makeBoolean(True))
    storage.setEntryTypeValue("CaseSensitive/KeyName", Value.makeBoolean(True))
    storage.setEntryTypeValue("=", Value.makeBoolean(True))

    dispatcher.reset_mock()
    entry_notifier.reset_mock()
    entry_notifier.m_local_notifiers = True

    return storage
Esempio n. 41
0
def test_PollPrefixBasic(notifier):
    poller = notifier.createPoller()
    g1 = notifier.addPolled(poller, "/foo", NT_NOTIFY_NEW)
    g2 = notifier.addPolled(poller, "/foo", NT_NOTIFY_DELETE)
    g3 = notifier.addPolled(poller, "/foo", NT_NOTIFY_UPDATE)
    g4 = notifier.addPolled(poller, "/foo", NT_NOTIFY_FLAGS)
    notifier.addPolled(poller, "/bar", NT_NOTIFY_NEW)
    notifier.addPolled(poller, "/bar", NT_NOTIFY_DELETE)
    notifier.addPolled(poller, "/bar", NT_NOTIFY_UPDATE)
    notifier.addPolled(poller, "/bar", NT_NOTIFY_FLAGS)

    assert not notifier.m_local_notifiers

    generateNotifications(notifier)

    assert notifier.waitForQueue(1.0)

    results, timed_out = notifier.poll(poller, 0)
    assert not timed_out

    g1count = 0
    g2count = 0
    g3count = 0
    g4count = 0
    for h, result in results:
        print(result)
        assert result.name.startswith("/foo")
        assert result.value == Value.makeDouble(1)

        if h == g1:
            g1count += 1
            assert (result.flags & NT_NOTIFY_NEW) != 0
        elif h == g2:
            g2count += 1
            assert (result.flags & NT_NOTIFY_DELETE) != 0
        elif h == g3:
            g3count += 1
            assert (result.flags & NT_NOTIFY_UPDATE) != 0
        elif h == g4:
            g4count += 1
            assert (result.flags & NT_NOTIFY_FLAGS) != 0
        else:
            assert False, "unknown listener index"

    assert g1count == 2
    assert g2count == 1  # NT_NOTIFY_DELETE
    assert g3count == 2
    assert g4count == 2
def test_PollPrefixBasic(notifier):
    poller = notifier.createPoller()
    g1 = notifier.addPolled(poller, "/foo", NT_NOTIFY_NEW)
    g2 = notifier.addPolled(poller, "/foo", NT_NOTIFY_DELETE)
    g3 = notifier.addPolled(poller, "/foo", NT_NOTIFY_UPDATE)
    g4 = notifier.addPolled(poller, "/foo", NT_NOTIFY_FLAGS)
    notifier.addPolled(poller, "/bar", NT_NOTIFY_NEW)
    notifier.addPolled(poller, "/bar", NT_NOTIFY_DELETE)
    notifier.addPolled(poller, "/bar", NT_NOTIFY_UPDATE)
    notifier.addPolled(poller, "/bar", NT_NOTIFY_FLAGS)

    assert not notifier.m_local_notifiers

    generateNotifications(notifier)

    assert notifier.waitForQueue(1.0)

    results, timed_out = notifier.poll(poller, 0)
    assert not timed_out

    g1count = 0
    g2count = 0
    g3count = 0
    g4count = 0
    for h, result in results:
        print(result)
        assert result.name.startswith("/foo")
        assert result.value == Value.makeDouble(1)

        if h == g1:
            g1count += 1
            assert (result.flags & NT_NOTIFY_NEW) != 0
        elif h == g2:
            g2count += 1
            assert (result.flags & NT_NOTIFY_DELETE) != 0
        elif h == g3:
            g3count += 1
            assert (result.flags & NT_NOTIFY_UPDATE) != 0
        elif h == g4:
            g4count += 1
            assert (result.flags & NT_NOTIFY_FLAGS) != 0
        else:
            assert False, "unknown listener index"

    assert g1count == 2
    assert g2count == 1  # NT_NOTIFY_DELETE
    assert g3count == 2
    assert g4count == 2
Esempio n. 43
0
 def setDefaultNumber(self, key, defaultValue):
     """If the key doesn't currently exist, then the specified value will
     be assigned to the key.
     
     :param key: the key to be assigned to
     :type key: str
     :param defaultValue: the default value to set if key doesn't exist.
     :type defaultValue: int, float
     
     :returns: False if the table key exists with a different type
     :rtype: bool
     
     .. versionadded:: 2017.0.0
     """
     path = self._path + key
     return self._api.setDefaultEntryValue(path, Value.makeDouble(defaultValue))
Esempio n. 44
0
 def setDefaultNumber(self, key, defaultValue):
     """If the key doesn't currently exist, then the specified value will
     be assigned to the key.
     
     :param key: the key to be assigned to
     :type key: str
     :param defaultValue: the default value to set if key doesn't exist.
     :type defaultValue: int, float
     
     :returns: False if the table key exists with a different type
     :rtype: bool
     
     .. versionadded:: 2017.0.0
     """
     path = self._path + key
     return self._api.setDefaultEntryValue(path, Value.makeDouble(defaultValue))
Esempio n. 45
0
def test_SetEntryTypeValueAssignTypeChange(storage_populate_one, dispatcher,
                                           entry_notifier, is_server):
    storage = storage_populate_one

    # update with different type results in assignment message
    value = Value.makeDouble(0.0)
    storage.setEntryTypeValue("foo", value)
    assert value == storage.m_entries.get("foo").value

    dispatcher._queueOutgoing.assert_has_calls([
        call(
            Message.entryAssign("foo", 0 if is_server else 0xffff, 2, value,
                                0), None, None),
    ])
    entry_notifier.notifyEntry.assert_has_calls([
        call(0, "foo", value, NT_NOTIFY_UPDATE | NT_NOTIFY_LOCAL),
    ])
Esempio n. 46
0
def test_ProcessIncomingEntryAssign1(storage_populate_one, dispatcher,
                                     entry_notifier, is_server, conn):
    storage = storage_populate_one
    value = Value.makeDouble(1.0)

    storage.processIncoming(Message.entryAssign("foo", 0, 1, value, 0), conn)

    # EXPECT_CALL(*conn, proto_rev()).WillRepeatedly(Return(0x0300u))
    if is_server:
        # server broadcasts new value to all *other* connections
        dispatcher._queueOutgoing.assert_has_calls(
            [call(Message.entryAssign("foo", 0, 1, value, 0), None, conn)])
    else:
        assert dispatcher._queueOutgoing.call_count == 0

    entry_notifier.notifyEntry.assert_has_calls(
        [call(0, "foo", value, NT_NOTIFY_UPDATE)])
Esempio n. 47
0
def test_LoadPersistentUpdateFlags(storage_populated, dispatcher,
                                   entry_notifier, is_server):
    storage = storage_populated

    fp = StringIO('[NetworkTables Storage 3.0]\ndouble "foo2"=0.0\n')
    assert storage.loadPersistent(fp=fp) is None

    entry = storage.m_entries.get("foo2")
    assert Value.makeDouble(0.0) == entry.value
    assert NT_PERSISTENT == entry.flags

    if is_server:
        dispatcher._queueOutgoing.assert_has_calls(
            [call(Message.flagsUpdate(1, NT_PERSISTENT), None, None)])
    else:
        assert dispatcher._queueOutgoing.call_count == 0

    entry_notifier.notifyEntry.assert_has_calls(
        [call(1, "foo2", entry.value, NT_NOTIFY_FLAGS | NT_NOTIFY_LOCAL)])
Esempio n. 48
0
def test_ProcessIncomingEntryAssign0(
    storage_empty, dispatcher, entry_notifier, is_server, conn
):
    storage = storage_empty
    value = Value.makeDouble(1.0)

    entry_id = 0xFFFF if is_server else 0

    storage.processIncoming(Message.entryAssign("foo", entry_id, 0, value, 0), conn)

    if is_server:
        # id assign message reply generated on the server sent to everyone
        dispatcher._queueOutgoing.assert_has_calls(
            [call(Message.entryAssign("foo", 0, 0, value, 0), None, None)]
        )
    else:
        assert dispatcher._queueOutgoing.call_count == 0

    entry_notifier.notifyEntry.assert_has_calls([call(0, "foo", value, NT_NOTIFY_NEW)])
Esempio n. 49
0
def test_ProcessIncomingEntryAssign0(
    storage_empty, dispatcher, entry_notifier, is_server, conn
):
    storage = storage_empty
    value = Value.makeDouble(1.0)

    entry_id = 0xFFFF if is_server else 0

    storage.processIncoming(Message.entryAssign("foo", entry_id, 0, value, 0), conn)

    if is_server:
        # id assign message reply generated on the server sent to everyone
        dispatcher._queueOutgoing.assert_has_calls(
            [call(Message.entryAssign("foo", 0, 0, value, 0), None, None)]
        )
    else:
        assert dispatcher._queueOutgoing.call_count == 0

    entry_notifier.notifyEntry.assert_has_calls([call(0, "foo", value, NT_NOTIFY_NEW)])
Esempio n. 50
0
def test_ProcessIncomingEntryAssign1(
    storage_populate_one, dispatcher, entry_notifier, is_server, conn
):
    storage = storage_populate_one
    value = Value.makeDouble(1.0)

    storage.processIncoming(Message.entryAssign("foo", 0, 1, value, 0), conn)

    # EXPECT_CALL(*conn, proto_rev()).WillRepeatedly(Return(0x0300u))
    if is_server:
        # server broadcasts new value to all *other* connections
        dispatcher._queueOutgoing.assert_has_calls(
            [call(Message.entryAssign("foo", 0, 1, value, 0), None, conn)]
        )
    else:
        assert dispatcher._queueOutgoing.call_count == 0

    entry_notifier.notifyEntry.assert_has_calls(
        [call(0, "foo", value, NT_NOTIFY_UPDATE)]
    )
Esempio n. 51
0
def test_SetEntryTypeValueAssignTypeChange(
    storage_populate_one, dispatcher, entry_notifier, is_server
):
    storage = storage_populate_one

    # update with different type results in assignment message
    value = Value.makeDouble(0.0)
    storage.setEntryTypeValue("foo", value)
    assert value == storage.m_entries.get("foo").value

    dispatcher._queueOutgoing.assert_has_calls(
        [
            call(
                Message.entryAssign("foo", 0 if is_server else 0xFFFF, 2, value, 0),
                None,
                None,
            )
        ]
    )
    entry_notifier.notifyEntry.assert_has_calls(
        [call(0, "foo", value, NT_NOTIFY_UPDATE | NT_NOTIFY_LOCAL)]
    )
Esempio n. 52
0
def test_SetEntryTypeValueDifferentValue(storage_populated, outgoing, is_server):
    storage = storage_populated
    
    # update with same type and different value results in value update message
    value = Value.makeDouble(1.0)
    storage.setEntryTypeValue("foo2", value)
    assert value == storage.m_entries.get("foo2").value

    if is_server:
        assert 1 == len(outgoing)
        assert not outgoing[0].only
        assert not outgoing[0].conn
        msg = outgoing[0].msg
        assert kEntryUpdate == msg.type
        assert 1 == msg.id  # assigned as server
        assert 2 == msg.seq_num_uid  # incremented
        assert value == msg.value

    else:
        # shouldn't send an update id not assigned yet (happens on client only)
        assert len(outgoing) == 0
        assert 2 == storage.m_entries.get("foo2").seq_num  # still should be incremented
Esempio n. 53
0
def test_SetEntryTypeValueAssignTypeChange(storage_populate_one, outgoing, is_server):
    storage = storage_populate_one
    
    # update with different type results in assignment message
    value = Value.makeDouble(0.0)
    storage.setEntryTypeValue("foo", value)
    assert value == storage.m_entries.get("foo").value

    assert 1 == len(outgoing)
    assert not outgoing[0].only
    assert not outgoing[0].conn
    msg = outgoing[0].msg
    assert kEntryAssign == msg.type
    assert "foo" == msg.str
    if is_server:
        assert 0 == msg.id    # assigned as server

    else:
        assert 0xffff == msg.id    # not assigned as client

    assert 2 == msg.seq_num_uid  # incremented
    assert value == msg.value
    assert 0 == msg.flags
Esempio n. 54
0
def test_wire_double(v_round_trip):
    v_round_trip(Value.makeDouble(0.5))
Esempio n. 55
0
def test_DoubleComparison():
    v1 = Value.makeDouble(0.25)
    v2 = Value.makeDouble(0.25)
    assert v1 == v2
    v2 = Value.makeDouble(0.5)
    assert v1 != v2
Esempio n. 56
0
def test_MixedComparison():

    v2 = Value.makeBoolean(True)
    v3 = Value.makeDouble(0.5)
    assert v2 != v3  # boolean vs double
Esempio n. 57
0
def test_loadPersistent(storage_empty, dispatcher, entry_notifier):
    storage = storage_empty

    inp = "[NetworkTables Storage 3.0]\n"
    inp += "boolean \"\\x00\\x03\\x05\\n\"=true\n"
    inp += "boolean \"CaseSensitive/KeyName\"=true\n"
    inp += "boolean \"boolean/false\"=false\n"
    inp += "boolean \"boolean/true\"=true\n"
    inp += "array boolean \"booleanarr/empty\"=\n"
    inp += "array boolean \"booleanarr/one\"=true\n"
    inp += "array boolean \"booleanarr/two\"=true,false\n"
    inp += "double \"double/big\"=1.3e+08\n"
    inp += "double \"double/neg\"=-1.5\n"
    inp += "double \"double/zero\"=0\n"
    inp += "array double \"doublearr/empty\"=\n"
    inp += "array double \"doublearr/one\"=0.5\n"
    inp += "array double \"doublearr/two\"=0.5,-0.25\n"
    inp += "raw \"raw/empty\"=\n"
    inp += "raw \"raw/normal\"=aGVsbG8=\n"
    inp += "raw \"raw/special\"=AAMFCg==\n"
    inp += "string \"string/empty\"=\"\"\n"
    inp += "string \"string/normal\"=\"hello\"\n"
    inp += "string \"string/special\"=\"\\x00\\x03\\x05\\n\"\n"
    inp += "array string \"stringarr/empty\"=\n"
    inp += "array string \"stringarr/one\"=\"hello\"\n"
    inp += "array string \"stringarr/two\"=\"hello\",\"world\\n\"\n"

    fp = StringIO(inp)
    assert storage.loadPersistent(fp=fp) is None

    dispatcher._queueOutgoing.assert_has_calls([
        call(ANY, None, None),
    ] * 22)

    entry_notifier.notifyEntry.assert_has_calls(
        [call(ANY, ANY, ANY, NT_NOTIFY_NEW | NT_NOTIFY_LOCAL)] * 22)

    assert Value.makeBoolean(True) == storage.getEntryValue("boolean/true")
    assert Value.makeBoolean(False) == storage.getEntryValue("boolean/false")
    assert Value.makeDouble(-1.5) == storage.getEntryValue("double/neg")
    assert Value.makeDouble(0.0) == storage.getEntryValue("double/zero")
    assert Value.makeDouble(1.3e8) == storage.getEntryValue("double/big")
    assert Value.makeString("") == storage.getEntryValue("string/empty")
    assert Value.makeString("hello") == storage.getEntryValue("string/normal")
    assert Value.makeString("\0\3\5\n") == storage.getEntryValue(
        "string/special")
    assert Value.makeRaw(b"") == storage.getEntryValue("raw/empty")
    assert Value.makeRaw(b"hello") == storage.getEntryValue("raw/normal")
    assert Value.makeRaw(b"\0\3\5\n") == storage.getEntryValue("raw/special")
    assert Value.makeBooleanArray(
        []) == storage.getEntryValue("booleanarr/empty")
    assert Value.makeBooleanArray(
        [True]) == storage.getEntryValue("booleanarr/one")
    assert Value.makeBooleanArray(
        [True, False]) == storage.getEntryValue("booleanarr/two")
    assert Value.makeDoubleArray(
        []) == storage.getEntryValue("doublearr/empty")
    assert Value.makeDoubleArray([0.5
                                  ]) == storage.getEntryValue("doublearr/one")
    assert Value.makeDoubleArray([0.5, -0.25
                                  ]) == storage.getEntryValue("doublearr/two")
    assert Value.makeStringArray(
        []) == storage.getEntryValue("stringarr/empty")
    assert Value.makeStringArray(["hello"
                                  ]) == storage.getEntryValue("stringarr/one")
    assert Value.makeStringArray(["hello", "world\n"
                                  ]) == storage.getEntryValue("stringarr/two")
    assert Value.makeBoolean(True) == storage.getEntryValue("\0\3\5\n")
    assert Value.makeBoolean(True) == storage.getEntryValue(
        "CaseSensitive/KeyName")