Repository: SETI/rms-cspyce (language: python)

Issue:
`ekrcei` integer result does not return any values when ran repeatedly
The function `ekrcei` returns data from an integer column in a specified EK record. Here are the inputs and returns:

```
    Inputs:
      int    handle = Handle attached to EK file.
      int    segno  = Index of segment containing record.
      int    recno  = Record from which data is to be read.
      string column = Column name.
    
    Returns:
      int[*] ivals  = Integer values in column entry.
      bool   isnull = Flag indicating whether column entry is null.
```

Here is the current unit test:

```
import cspyce as cs
import numpy as np
import numpy.testing as npt
import os
import pytest

from gettestkernels import (
    download_kernels,
    TEST_FILE_DIR
)


@pytest.fixture(autouse=True)
def clear_kernel_pool_and_reset():
    cs.kclear()
    cs.reset()
    # yield for test
    yield
    # clear kernel pool again
    cs.kclear()
    cs.reset()


def cleanup_kernel(path):
    cs.kclear()
    cs.reset()
    if os.path.isfile(path):
        os.remove(path)  # pragma: no cover
    pass


def setup_module(module):
    download_kernels()


ekpath = os.path.join(TEST_FILE_DIR, "example_ekmany.ek")
tablename = "test_table_ekmany"
cleanup_kernel(ekpath)
# Create new EK and new segment with table
handle = cs.ekopn(ekpath, ekpath, 0)
decls = [
    "DATATYPE = CHARACTER*(10),   NULLS_OK = FALSE, SIZE = VARIABLE",
    "DATATYPE = DOUBLE PRECISION, NULLS_OK = FALSE, SIZE = VARIABLE",
    "DATATYPE = INTEGER,          NULLS_OK = FALSE, SIZE = VARIABLE",
]
segno = cs.ekbseg(handle, tablename, ["c1", "d1", "i1"], decls)
# Insert records:  1, 2, and 3 entries at rows 0, 1, 2, respectively
c_data = [["100"], ["101", "101"], ["102", "102", "102"]]
d_data = [[100.0], [101.0, 101.0], [102.0, 102.0, 102.0]]
i_data = [[100], [101, 101], [102, 102, 102]]
for r in range(0, 3):
    cs.ekinsr(handle, segno, r)
    cs.ekacec(handle, segno, r, "c1", c_data[r], False)
    cs.ekaced(handle, segno, r, "d1", d_data[r], False)
    cs.ekacei(handle, segno, r, "i1", i_data[r], False)
# Try record insertion beyond the next available, verify the exception
with pytest.raises(Exception):
    cs.ekinsr(handle, segno, 4)
# Close EK, then reopen for reading
cs.ekcls(handle)
cs.kclear()
#
# Start of part two
#
handle = cs.eklef(ekpath)
assert handle is not None
# Test query using ekpsel
query = "SELECT c1, d1, i1 from {}".format(tablename)
xbegs, xends, xtypes, xclass, tabs, cols = cs.ekpsel(query)
assert xtypes[0] == 0
assert xtypes[1] == 1
assert xtypes[2] == 2
assert ([0] * 3) == list(xclass)
assert ('TEST_TABLE_EKMANY',
        'TEST_TABLE_EKMANY', 
        'TEST_TABLE_EKMANY') == tabs
assert ('C1', 'D1', 'I1') == cols
# Run query to retrieve the row count
nmrows = cs.ekfind(query)
assert nmrows == 3
# test fail case for eknelt
with pytest.raises(Exception):
    cs.eknelt(0, nmrows + 1)
# Validate the content of each field, including exceptions when
# Loop over rows, test .ekgc/.ekgd/.ekgi
for r in range(nmrows):
    # get number of elements in this row
    n_elm = cs.eknelt(0, r)
    assert n_elm == r + 1
    for e in range(0, n_elm):
        # get row int data
        i_datum, i_null = cs.ekgi(2, r, e)
        assert not i_null
        assert i_datum == i_data[r][e]
        # get row double data
        d_datum, d_null = cs.ekgd(1, r, e)
        assert not d_null
        assert d_datum == d_data[r][e]
        # get row char data
        c_datum, c_null = cs.ekgc(0, r, e)
        assert not c_null
        assert c_datum == c_data[r][e]
# Loop over rows, test .ekrcec/.ekrced/.ekrcei
for r in range(nmrows):
    # get row int data
    ri_data, i_null = cs.ekrcei(handle, segno, r, "i1")
    assert not i_null

    npt.assert_array_equal(ri_data, i_data[r])
    # get row double data
    rd_data, d_null = cs.ekrced(handle, segno, r, "d1")
    assert not d_null
    npt.assert_array_equal(rd_data, d_data[r])
    # get row char data
    rc_data, c_null = cs.ekrcec(handle, segno, r, "c1")
    assert not c_null
    assert list(rc_data) == c_data[r]
# test out of bounds
with pytest.raises(IndexError):
    cs.ekrcei(handle, segno, 3, "i1")
with pytest.raises(IndexError):
    cs.ekrced(handle, segno, 3, "d1")
# with pytest.raises(Exception): TODO: FIX
#    cs.ekrcec(handle, segno, 4, "c1", 4) # this causes a SIGSEGV
#
# Part 3
#
# Close file, re-open for writing
cs.ekuef(handle)
handle = cs.ekopw(ekpath)
# Loop over rows, update values using .ekucec/.ekuced/.ekucei
c_data = [["200"], ["201", "201"], ["202", "202", "202"]]
d_data = [[200.0], [201.0, 201.0], [202.0, 202.0, 202.0]]
i_data = [[200], [201, 201], [202, 202, 202]]
for r in range(0, 3):
    cs.ekucec(handle, segno, r, "c1", c_data[r], False)
    cs.ekuced(handle, segno, r, "d1", d_data[r], False)
    cs.ekucei(handle, segno, r, "i1", i_data[r], False)
# Test invalid updates
with pytest.raises(Exception):
    cs.ekucec(handle, segno, 3, "c1", 1, ["300"], False)
with pytest.raises(Exception):
    cs.ekuced(handle, segno, 3, "d1", 1, [300.0], False)
with pytest.raises(Exception):
    cs.ekucei(handle, segno, 3, "i1", 1, [300], False)
# Loop over rows, use .ekrcec/.ekrced/.ekrcei to test updates
for r in range(nmrows):
    # get row int data
    ri_data, i_null = cs.ekrcei(handle, segno, r, "i1")
    assert not i_null
    npt.assert_array_equal(ri_data, i_data[r])
    # get row double data
    rd_data, d_null = cs.ekrced(handle, segno, r, "d1")
    assert not d_null
    npt.assert_array_equal(rd_data, d_data[r])
    # get row char data
    rc_data, c_null = cs.ekrcec(handle, segno, r, "c1")
    assert not c_null
    assert list(rc_data) == c_data[r]
# Cleanup
cs.ekcls(handle)
assert not cs.failed()
cleanup_kernel(ekpath)
```
The function returns the correct value the first time its called. On line 151, when it's called again, it fails. The float and character versions of this function (`ekrced` and `ekrcec`, respectively) work as intended. 


Discussion / hints:

Fix patch:
diff --git a/swig/cspyce0_part2.i b/swig/cspyce0_part2.i
index 6302f415..b3fc4175 100644
--- a/swig/cspyce0_part2.i
+++ b/swig/cspyce0_part2.i
@@ -5707,7 +5707,7 @@ extern void ekuced_c(
 
 %rename (ekucei) ekucei_c;
 %apply (void RETURN_VOID) {void ekucei_c};
-%apply (SpiceInt DIM1, ConstSpiceDouble IN_ARRAY1[])
+%apply (SpiceInt DIM1, ConstSpiceInt IN_ARRAY1[])
                 {(SpiceInt nvals, ConstSpiceInt ivals[])};
 
 extern void ekucei_c(


Test patch:
diff --git a/unittests/test_e.py b/unittests/test_e.py
index 6ff0a491..7a0f3f42 100644
--- a/unittests/test_e.py
+++ b/unittests/test_e.py
@@ -520,7 +520,7 @@ def test_ekifld():
     assert not os.path.exists(ekpath)
 
 
-def fail_ekinsr_eknelt_ekpsel_ekrcec_ekrced_ekrcei():
+def test_ekinsr_eknelt_ekpsel_ekrcec_ekrced_ekrcei():
     ekpath = os.path.join(TEST_FILE_DIR, "example_ekmany.ek")
     tablename = "test_table_ekmany"
     cleanup_kernel(ekpath)
@@ -602,7 +602,7 @@ def fail_ekinsr_eknelt_ekpsel_ekrcec_ekrced_ekrcei():
         # get row char data
         rc_data, c_null = cs.ekrcec(handle, segno, r, "c1")
         assert not c_null
-        assert rc_data == c_data[r]
+        assert list(rc_data) == c_data[r]
     # test out of bounds
     with pytest.raises(IndexError):
         cs.ekrcei(handle, segno, 3, "i1")
@@ -642,9 +642,9 @@ def fail_ekinsr_eknelt_ekpsel_ekrcec_ekrced_ekrcei():
         assert not d_null
         npt.assert_array_equal(rd_data, d_data[r])
         # get row char data
-        rc_data, c_null = cs.ekrcec(handle, segno, r, "c1", 11)
+        rc_data, c_null = cs.ekrcec(handle, segno, r, "c1")
         assert not c_null
-        assert list(rc_data[0]) == c_data[r]
+        assert list(rc_data) == c_data[r]
     # Cleanup
     cs.ekcls(handle)
     assert not cs.failed()
diff --git a/unittests/test_k_o.py b/unittests/test_k_o.py
index ed804093..23eb4c11 100644
--- a/unittests/test_k_o.py
+++ b/unittests/test_k_o.py
@@ -781,45 +781,45 @@ def test_orderi():
     npt.assert_array_almost_equal(expected_order, order)
 
 
-def fail_oscelt():
+def test_oscelt():
     cs.furnsh(CoreKernels.testMetaKernel)
     et = cs.str2et("Dec 25, 2007")
     state, ltime = cs.spkezr("Moon", et, "J2000", "LT+S", "EARTH")
     mass_earth = cs.bodvrd("EARTH", "GM")
     elts = cs.oscelt(state, et, mass_earth[0])
     expected = [
-        3.65914105273643566761e05,
-        4.23931145731340453494e05,
-        4.87177926278510253777e-01,
-        6.18584206992959551030e00,
-        1.88544634402406319218e00,
-        1.86769787246217056236e04,
-        2.51812865183709204197e08,
-        1.00000000000000000000e00,
-    ]
+        3.60975119168868346605e+05,
+        7.81035176779166367966e-02,
+        4.87177926278510309288e-01,
+        6.18584206992959551030e+00,
+        1.28678805411666807856e+00,
+        5.53312778515375192079e-01,
+        2.51812865183709204197e+08,
+        3.98600435436095925979e+05
+     ]
     npt.assert_array_almost_equal(elts, expected, decimal=4)
 
 
-def fail_oscltx():
+def test_oscltx():
     cs.furnsh(CoreKernels.testMetaKernel)
     et = cs.str2et("Dec 25, 2007")
     state, ltime = cs.spkezr("Moon", et, "J2000", "LT+S", "EARTH")
     mass_earth = cs.bodvrd("EARTH", "GM")
     elts = cs.oscltx(state, et, mass_earth[0])
     expected = [
-        3.65914105273643566761e05,
-        4.23931145731340453494e05,
-        4.87177926278510253777e-01,
-        6.18584206992959551030e00,
-        1.88544634402406319218e00,
-        1.86769787246217056236e04,
-        2.51812865183709204197e08,
-        1.00000000000000000000e00,
-        4.40283687897870881778e-02,
-        -8.63147169311087925081e-01,
-        0.00000000000000000000e00,
+        3.60975119168868346605e+05,
+        7.81035176779166367966e-02,
+        4.87177926278510309288e-01,
+        6.18584206992959551030e+00,
+        1.28678805411666807856e+00,
+        5.53312778515375192079e-01,
+        2.51812865183709204197e+08,
+        3.98600435436095925979e+05,
+        6.42686658697182999767e-01,
+        3.91557106563244480640e+05,
+        2.43839270213373843580e+06
     ]
-    npt.assert_array_almost_equal(elts, expected, decimal=4)
+    npt.assert_array_almost_equal(elts[0:11], expected, decimal=4)
 
 
 # =============================================================================