def testAddingHostsToBackend(dhcpBackendWithoutLookup):
    dhcpBackendWithoutLookup.host_insertObject(
        OpsiClient(
            id='client1.test.invalid',
            hardwareAddress='00:01:02:03:04:05',
            ipAddress='192.168.1.101',
        ))
    dhcpBackendWithoutLookup.host_insertObject(
        OpsiClient(
            id='client2.test.invalid',
            hardwareAddress='00:01:02:03:11:22',
            ipAddress='192.168.1.102',
        ))
    dhcpBackendWithoutLookup.host_insertObject(
        OpsiClient(
            id='client3.test.invalid',
            hardwareAddress='1101:02:03-83:22',
            ipAddress='192.168.1.103',
        ))
    dhcpBackendWithoutLookup.host_insertObject(
        OpsiClient(
            id='client4.test.invalid',
            hardwareAddress='00:99:88:77:77:11',
            ipAddress='192.168.1.104',
        ))
示例#2
0
def createClientAndDepot(backend):
	client = OpsiClient(
		id='backend-test-1.vmnat.local',
		description='Unittest Test client.'
	)

	depot = OpsiDepotserver(
		id='depotserver1.some.test',
		description='Test Depot',
	)

	backend.host_createObjects([client, depot])

	clientConfigDepotId = UnicodeConfig(
		id=u'clientconfig.depot.id',
		description=u'Depotserver to use',
		possibleValues=[],
		defaultValues=[depot.id]
	)

	backend.config_createObjects(clientConfigDepotId)

	clientDepotMappingConfigState = ConfigState(
		configId=clientConfigDepotId.getId(),
		objectId=client.getId(),
		values=depot.getId()
	)

	backend.configState_createObjects(clientDepotMappingConfigState)

	return client, depot
示例#3
0
def testGetClientsWithActionRequest(backendManager, clients, param):
    for client in clients:
        backendManager.host_insertObject(client)

    testclient1 = OpsiClient(id='testclient1.test.invalid')
    backendManager.host_insertObject(testclient1)

    product1 = LocalbootProduct('product1', '1.0', '1')
    backendManager.product_insertObject(product1)
    product2 = LocalbootProduct('product2', '2.0', '1')
    backendManager.product_insertObject(product2)

    fillerProducts = [
        LocalbootProduct("filler1", '1', '1'),
        LocalbootProduct("filler2", '2', '2'),
        LocalbootProduct("filler3", '3', '3'),
    ]
    for poc in fillerProducts:
        backendManager.product_insertObject(poc)

    # Skipping update because we search for this
    actionRequests = ['setup', 'uninstall', 'always', 'once', 'custom', 'none']

    fillerPocs = [
        ProductOnClient(productId=product.getId(),
                        productType=product.getType(),
                        clientId=client.getId(),
                        installationStatus=random.choice(
                            ['installed', 'not_installed', 'unknown']),
                        actionRequest=random.choice(actionRequests),
                        productVersion=product.getProductVersion(),
                        packageVersion=product.getPackageVersion())
        for client, product in itertools.product(clients, fillerProducts)
    ]

    relevantPocs = [
        ProductOnClient(productId=product1.getId(),
                        productType=product1.getType(),
                        clientId=testclient1.getId(),
                        installationStatus='installed',
                        actionRequest='update',
                        productVersion=product1.getProductVersion(),
                        packageVersion=product1.getPackageVersion()),
        ProductOnClient(productId=product2.getId(),
                        productType=product2.getType(),
                        clientId=testclient1.getId(),
                        installationStatus='unknown',
                        actionRequest='update',
                        productVersion=product2.getProductVersion(),
                        packageVersion=product2.getPackageVersion()),
    ]

    for poc in fillerPocs + relevantPocs:
        backendManager.productOnClient_insertObject(poc)

    clientsToCheck = backendManager.getClientsWithActionRequest(param)

    assert len(clientsToCheck) == 1
    assert clientsToCheck[0] == testclient1.id
示例#4
0
def testRenamingOpsiClientFailsIfNewIdAlreadyExisting(
        extendedConfigDataBackend):
    backend = extendedConfigDataBackend

    host = OpsiClient(id='old.test.invalid')
    anotherHost = OpsiClient(id='new.test.invalid')

    backend.host_insertObject(host)
    backend.host_insertObject(anotherHost)

    with pytest.raises(BackendError):
        backend.host_renameOpsiClient(host.id, anotherHost.id)
示例#5
0
def testTrackingOfInsertObject(backendAndTracker):
    backend, tracker = backendAndTracker

    host = OpsiClient(id='client1.test.invalid')
    backend.host_insertObject(host)

    modifications = tracker.getModifications()
    assert 1 == len(modifications)
    mod = modifications[0]
    assert mod['objectClass'] == host.__class__.__name__
    assert mod['command'] == 'insert'
    assert mod['ident'] == host.getIdent()
def fillBackendForRenaming(backend):
    group = HostGroup(id='host_group_1')

    client1 = OpsiClient(id='client1.test.invalid')
    client2 = OpsiClient(id='client2.test.invalid')

    client1ToGroup = ObjectToGroup(group.getType(), group.id, client1.id)
    client2ToGroup = ObjectToGroup(group.getType(), group.id, client2.id)

    backend.host_insertObject(client1)
    backend.host_insertObject(client2)
    backend.group_insertObject(group)
    backend.objectToGroup_createObjects([client1ToGroup, client2ToGroup])

    return (group, (client1, client2))
示例#7
0
def testNotChangingUnreferencedClient(backendWithWANConfigs):
    backend = backendWithWANConfigs

    clientIds = ['testclient{0}.test.invalid'.format(num) for num in range(10)]
    singleClient = 'testclient99.test.invalid'
    backend.host_createObjects(
        [OpsiClient(id=clientId) for clientId in clientIds])
    backend.host_createObjects([OpsiClient(id=singleClient)])

    backend.changeWANConfig(True, clientIds)
    backend.changeWANConfig(True, [])

    for clientId in clientIds:
        assert clientHasWANEnabled(backend, clientId)

    assert not clientHasWANEnabled(backend, singleClient)
示例#8
0
def testRenamingOpsiClient(extendedConfigDataBackend):
    backend = extendedConfigDataBackend

    host = OpsiClient(id='jacket.test.invalid')
    backend.host_insertObject(host)

    protagonists = HostGroup("protagonists")
    backend.group_insertObject(protagonists)

    backend.objectToGroup_insertObject(
        ObjectToGroup(protagonists.getType(), protagonists.id, host.id))

    oldId = host.id
    newId = 'richard.test.invalid'

    backend.host_renameOpsiClient(oldId, newId)

    assert not backend.host_getObjects(id=oldId)
    assert backend.host_getObjects(id=newId)

    # We want to make sure that the membership of groups does get
    # changed aswell.
    assert not backend.objectToGroup_getObjects(objectId=oldId)
    memberships = backend.objectToGroup_getObjects(objectId=newId)
    assert memberships
    membership = memberships[0]
    assert membership.objectId == newId
    assert membership.groupId == protagonists.id
示例#9
0
def addServers(backend):
    localHostFqdn = getLocalHostFqdn()
    configServer = OpsiConfigserver(
        id=localHostFqdn, depotRemoteUrl='smb://192.168.123.1/opsi_depot')
    backend.host_createObjects([configServer])

    _, domain = localHostFqdn.split('.', 1)

    def getDepotRemoteUrl(index):
        if index % 2 == 0:
            return 'smb://192.168.123.{}/opsi_depot'.format(index)
        else:
            return 'smb://somename/opsi_depot'

    depots = [
        OpsiDepotserver(id='depot{n}.{domain}'.format(n=index, domain=domain),
                        depotRemoteUrl=getDepotRemoteUrl(index))
        for index in range(10)
    ]
    backend.host_createObjects(depots)

    clients = [
        OpsiClient(id='client{n}.{domain}'.format(n=index, domain=domain))
        for index in range(10)
    ]
    backend.host_createObjects(clients)
示例#10
0
def testAddingHostToBackend():
    originalDhcpdFile = os.path.join(
        os.path.dirname(os.path.abspath(__file__)), 'testdata', 'backend',
        'dhcp_ki.conf')

    client = OpsiClient(
        id='client1.test.invalid',
        hardwareAddress='aa:bb:cc:dd:ee:ff',
        ipAddress='192.168.3.1',
    )

    with createTemporaryTestfile(originalDhcpdFile) as dhcpdFile:
        backend = DHCPDBackend(
            dhcpdConfigFile=dhcpdFile,
            reloadConfigCommand=u'/bin/echo "Reloading dhcpd.conf"')

        with showLogs(8):
            backend.host_insertObject(client)

        optionExists = False
        clientFound = False
        with open(dhcpdFile) as f:
            for line in f:
                print(line)
                if 'option voip-tftp-server code 150 = { ip-address, ip-address };' in line:
                    optionExists = True
                if client.hardwareAddress in line:
                    clientFound = True

        assert clientFound, "Client not found in config file"
        assert '}' in line, 'Expected closing bracket in last line'
        assert optionExists, "Missing option with array"
示例#11
0
def testUpdatingAuditHardware(hardwareAuditBackendWithHistory):
	backend = hardwareAuditBackendWithHistory

	client = OpsiClient(id='foo.bar.invalid')
	backend.host_insertObject(client)

	ahoh = {
		"hostId": client.id,
		"vendor": "Micron",
		"description": "Physikalischer Speicher",
		"tag": "Physical Memory 0",
		"speed": 2400000000,
		"hardwareClass": "MEMORY_MODULE",
		"formFactor": "SODIMM",
		"capacity": "8589934592",
		"name": "DIMM 1",
		"serialNumber": "15E64109",
		"memoryType": "Unknown",
		"type": "AuditHardwareOnHost",
		"deviceLocator": "DIMM 1",
		"dataWidth": 64
	}

	backend.auditHardwareOnHost_createObjects([ahoh])
	backend.auditHardwareOnHost_updateObjects([ahoh])
def testSetProductPropertyHandlingBoolProductProperties(backendManager):
    product = LocalbootProduct('testproduct', '1.0', '2')
    backendManager.product_insertObject(product)

    testprop = BoolProductProperty(productId=product.id,
                                   productVersion=product.productVersion,
                                   packageVersion=product.packageVersion,
                                   propertyId=u"changeMe",
                                   defaultValues=[False])
    backendManager.productProperty_insertObject(testprop)

    client = OpsiClient('testclient.domain.invalid')
    backendManager.host_insertObject(client)

    backendManager.setProductProperty(product.id, testprop.propertyId, True,
                                      client.id)

    result = backendManager.productProperty_getObjects(
        propertyId=testprop.propertyId)
    assert len(result) == 1
    result = result[0]
    assert isinstance(result, BoolProductProperty)
    assert result.getPossibleValues() == [False, True]
    assert result.getDefaultValues() == [False]

    result = backendManager.productPropertyState_getObjects()
    assert len(result) == 1
    result = result[0]
    assert result.getObjectId() == client.id
    assert result.getValues() == [True]
示例#13
0
def testConfigStateCheckFailsOnInvalidDepotSettings(extendedConfigDataBackend,
                                                    configValue):
    backend = extendedConfigDataBackend
    client = OpsiClient(id='client.test.invalid')
    backend.host_insertObject(client)

    configServer = getConfigServer()
    backend.host_insertObject(configServer)

    config = UnicodeConfig(id=u'clientconfig.depot.id',
                           description=u'ID of the opsi depot to use',
                           possibleValues=[configServer.getId()],
                           defaultValues=[configServer.getId()],
                           editable=True,
                           multiValue=False)

    backend.config_insertObject(config)
    configState = {
        'configId': config.id,
        'objectId': client.id,
        'values': configValue,
        'type': 'ConfigState'
    }
    with pytest.raises(ValueError):
        backend.configState_insertObject(configState)
示例#14
0
def testHardwareAuditAcceptingHugeMemoryClockSpeeds(hardwareAuditBackendWithHistory):
	"""
	Testing that the backend accepts a memory speed larger than the size
	of an signed int in MySQL.

	Datatype sizes are:
	* signed INT from -2147483648 to 2147483647
	* signed BIGINT from -9223372036854775808 to 9223372036854775807
	"""
	backend = hardwareAuditBackendWithHistory

	client = OpsiClient(id='foo.bar.invalid')
	backend.host_insertObject(client)

	backend.auditHardwareOnHost_setObsolete([client.id])
	backend.auditHardwareOnHost_updateObjects([
		{
			"hostId": client.id,
			"vendor": "Micron",
			"description": "Physikalischer Speicher",
			"tag": "Physical Memory 0",
			"speed": 2400000000,
			"hardwareClass": "MEMORY_MODULE",
			"formFactor": "SODIMM",
			"capacity": "8589934592",
			"name": "DIMM 1",
			"serialNumber": "15E64109",
			"memoryType": "Unknown",
			"type": "AuditHardwareOnHost",
			"deviceLocator": "DIMM 1",
			"dataWidth": 64
		},
	])
示例#15
0
def opsiClient():
    return OpsiClient(id='test1.test.invalid',
                      description='Test client 1',
                      notes='Notes ...',
                      hardwareAddress='00:01:02:03:04:05',
                      ipAddress='192.168.1.100',
                      lastSeen='2009-01-01 00:00:00',
                      opsiHostKey='45656789789012789012345612340123')
示例#16
0
def testUsingNonBooleanParameters(backendWithWANConfigs, value, expected):
    backend = backendWithWANConfigs

    client = OpsiClient(id='testclient101.test.invalid')
    backend.host_createObjects([client])

    backend.changeWANConfig(value, client.id)
    assert clientHasWANEnabled(backend, client.id) == expected
示例#17
0
def testEnablingSettingForOneHost(backendWithWANConfigs):
    backend = backendWithWANConfigs
    clientId = 'testclient.test.invalid'
    backend.host_createObjects(OpsiClient(id=clientId))

    backend.changeWANConfig(True, clientId)
    assert clientHasWANEnabled(backend, clientId)

    backend.changeWANConfig(False, clientId)
    assert not clientHasWANEnabled(backend, clientId)
示例#18
0
def testEnablingSettingForMultipleHosts(backendWithWANConfigs):
    backend = backendWithWANConfigs

    clientIds = ['testclient{0}.test.invalid'.format(num) for num in range(10)]
    backend.host_createObjects(
        [OpsiClient(id=clientId) for clientId in clientIds])

    backend.changeWANConfig(True, clientIds)

    for clientId in clientIds:
        assert clientHasWANEnabled(backend, clientId)
示例#19
0
def testConfigStateCheckWorksWithInsertedDict(extendedConfigDataBackend):
    backend = extendedConfigDataBackend
    client = OpsiClient(id='client.test.invalid')
    backend.host_insertObject(client)
    config = BoolConfig('license-managment.use')
    backend.config_insertObject(config)
    configState = {
        'configId': config.id,
        'objectId': client.id,
        'values': 'true',
        'type': 'ConfigState'
    }
    backend.configState_insertObject(configState)
示例#20
0
def testGetClientsWithProductsWithSpecificStatus(backendManager, clients,
                                                 desiredStatus,
                                                 expectedClient):
    for client in clients:
        backendManager.host_insertObject(client)

    testclient1 = OpsiClient(id='testclient1.test.invalid')
    backendManager.host_insertObject(testclient1)
    testclient2 = OpsiClient(id='testclient2.test.invalid')
    backendManager.host_insertObject(testclient2)

    product1 = LocalbootProduct('product1', '1.0', '1')
    backendManager.product_insertObject(product1)
    product2 = LocalbootProduct('product2', '2.0', '1')
    backendManager.product_insertObject(product2)

    fillerProducts = [
        LocalbootProduct("filler1", '1', '1'),
        LocalbootProduct("filler2", '2', '2'),
        LocalbootProduct("filler3", '3', '3'),
    ]
    for poc in fillerProducts:
        backendManager.product_insertObject(poc)

    fillerPocs = [
        ProductOnClient(productId=product.getId(),
                        productType=product.getType(),
                        clientId=client.getId(),
                        installationStatus=random.choice(
                            ['installed', 'not_installed', 'unknown']),
                        productVersion=product.getProductVersion(),
                        packageVersion=product.getPackageVersion())
        for client, product in itertools.product(clients, fillerProducts)
    ]

    relevantPocs = [
        ProductOnClient(productId=product1.getId(),
                        productType=product1.getType(),
                        clientId=testclient2.getId(),
                        installationStatus='installed',
                        productVersion=product1.getProductVersion(),
                        packageVersion=product1.getPackageVersion()),
        ProductOnClient(productId=product2.getId(),
                        productType=product2.getType(),
                        clientId=testclient1.getId(),
                        installationStatus='unknown',
                        productVersion=product2.getProductVersion(),
                        packageVersion=product2.getPackageVersion()),
    ]

    for poc in fillerPocs + relevantPocs:
        backendManager.productOnClient_insertObject(poc)

    clientsToCheck = backendManager.getClientsWithProducts(
        [product1.id, product2.id], desiredStatus)

    assert len(clientsToCheck) == 1
    assert clientsToCheck[0] == expectedClient
def testSetProductActionRequestForHostGroup(backendManager):
    testGroup = HostGroup(id='host_group_1')

    client1 = OpsiClient(id='client1.test.invalid')
    client2 = OpsiClient(id='client2.test.invalid')

    client1ToGroup = ObjectToGroup(testGroup.getType(), testGroup.id,
                                   client1.id)
    client2ToGroup = ObjectToGroup(testGroup.getType(), testGroup.id,
                                   client2.id)

    depot = OpsiDepotserver(id='depotserver1.test.invalid')

    product2 = LocalbootProduct(
        id='product2',
        name=u'Product 2',
        productVersion='2.0',
        packageVersion='test',
        setupScript="setup.ins",
    )

    prodOnDepot = ProductOnDepot(productId=product2.getId(),
                                 productType=product2.getType(),
                                 productVersion=product2.getProductVersion(),
                                 packageVersion=product2.getPackageVersion(),
                                 depotId=depot.getId())

    backendManager.host_insertObject(client1)
    backendManager.host_insertObject(client2)
    backendManager.host_insertObject(depot)
    backendManager.group_insertObject(testGroup)
    backendManager.objectToGroup_createObjects(
        [client1ToGroup, client2ToGroup])
    backendManager.config_create(u'clientconfig.depot.id')
    backendManager.configState_create(u'clientconfig.depot.id',
                                      client1.getId(),
                                      values=[depot.getId()])
    backendManager.configState_create(u'clientconfig.depot.id',
                                      client2.getId(),
                                      values=[depot.getId()])
    backendManager.product_insertObject(product2)
    backendManager.productOnDepot_insertObject(prodOnDepot)

    backendManager.setProductActionRequestForHostGroup('host_group_1',
                                                       'product2', 'setup')

    pocs = backendManager.productOnClient_getObjects()
    assert pocs
    assert len(pocs) == 2

    for poc in backendManager.productOnClient_getObjects():
        assert poc.productId == product2.getId()
        assert poc.clientId in (client1.id, client2.id)
示例#22
0
def test_selectProductOnClientsByWildcard(extendedConfigDataBackend):
    client = OpsiClient(id='client.test.invalid')
    extendedConfigDataBackend.host_createObjects(client)

    poc = ProductOnClient(
        productId='product6',
        productType='LocalbootProduct',
        clientId=client.id,
        installationStatus='not_installed',
        actionRequest='setup'
    )
    extendedConfigDataBackend.productOnClient_createObjects(poc)

    productOnClients = extendedConfigDataBackend.productOnClient_getObjects(
        clientId=client.id,
        productId='*6*'
    )
    assert productOnClients == [poc]
示例#23
0
def test_createProductOnClient(extendedConfigDataBackend):
    client = OpsiClient(id='client.test.invalid')
    extendedConfigDataBackend.host_createObjects(client)

    originalPoc = ProductOnClient(
        productId='product6',
        productType='LocalbootProduct',
        clientId=client.id,
        installationStatus='not_installed',
        actionRequest='setup'
    )
    extendedConfigDataBackend.productOnClient_createObjects(originalPoc)

    productOnClients = [poc for poc in
                        extendedConfigDataBackend.productOnClient_getObjects(clientId=client.id)
                        if poc.actionRequest == 'setup']

    assert [originalPoc] == productOnClients
示例#24
0
def testGettingPcpatchCredentials(fakeCredentialsBackend):
    """
    Test reading and decrypting the pcpatch password with per-client encryption.

    This is essentially what is done in the opsi-linux-bootimage.
    """
    backend = fakeCredentialsBackend

    backend.user_setCredentials(username="******", password='******')

    host = OpsiClient("someclient.opsi.test",
                      opsiHostKey=generateOpsiHostKey())
    backend.host_insertObject(host)

    creds = backend.user_getCredentials("pcpatch", host.id)

    password = blowfishDecrypt(host.opsiHostKey, creds['password'])

    assert password == 'somepassword'
def testSetProductPropertyFailingIfMultivalueIsFalse(backendManager):
    product = LocalbootProduct('testproduct', '1.0', '2')
    backendManager.product_insertObject(product)

    testprop = UnicodeProductProperty(productId=product.id,
                                      productVersion=product.productVersion,
                                      packageVersion=product.packageVersion,
                                      propertyId=u"rebootflag",
                                      possibleValues=["0", "1", "2", "3"],
                                      defaultValues=["0"],
                                      editable=False,
                                      multiValue=False)
    backendManager.productProperty_insertObject(testprop)

    client = OpsiClient('testclient.domain.invalid')
    backendManager.host_insertObject(client)

    with pytest.raises(ValueError):
        backendManager.setProductProperty(product.id, testprop.propertyId,
                                          ["1", "2"], client.id)
示例#26
0
def getClients():
    client1 = OpsiClient(id='client1.test.invalid',
                         description='Test client 1',
                         notes='Notes ...',
                         hardwareAddress='00:01:02:03:04:05',
                         ipAddress='192.168.1.100',
                         lastSeen='2009-01-01 00:00:00',
                         opsiHostKey='45656789789012789012345612340123',
                         inventoryNumber=None)

    client2 = OpsiClient(id='client2.test.invalid',
                         description='Test client 2',
                         notes=';;;;;;;;;;;;;;',
                         hardwareAddress='00-ff0aa3:0b-B5',
                         opsiHostKey='59051234345678890121678901223467',
                         inventoryNumber='00000000003',
                         oneTimePassword='******')

    client3 = OpsiClient(id='client3.test.invalid',
                         description='Test client 3',
                         notes='#############',
                         inventoryNumber='XYZABC_1200292')

    client4 = OpsiClient(
        id='client4.test.invalid',
        description='Test client 4',
    )

    client5 = OpsiClient(id='client5.test.invalid',
                         description='Test client 5',
                         oneTimePassword='******')

    client6 = OpsiClient(
        id='client6.test.invalid',
        description='Test client 6',
    )

    client7 = OpsiClient(
        id='client7.test.invalid',
        description='Test client 7',
    )

    return client1, client2, client3, client4, client5, client6, client7
def testSetProductPropertyHandlingMissingObjects(backendManager, productExists,
                                                 propertyExists, clientExists):
    expectedProperties = 0
    productId = 'existence'

    if productExists:
        product = LocalbootProduct(productId, '1.0', '1')
        backendManager.product_insertObject(product)

        if propertyExists:
            testprop = UnicodeProductProperty(
                productId=product.id,
                productVersion=product.productVersion,
                packageVersion=product.packageVersion,
                propertyId=u"changer",
                possibleValues=["True", "False"],
                defaultValues=["False"],
                editable=True,
                multiValue=False)
            backendManager.productProperty_insertObject(testprop)

            expectedProperties += 1

    with pytest.raises(BackendMissingDataError):
        backendManager.setProductProperty(productId, 'nothere', False)

    assert len(
        backendManager.productProperty_getObjects()) == expectedProperties

    if clientExists:
        client = OpsiClient('testclient.domain.invalid')
        backendManager.host_insertObject(client)

    with pytest.raises(BackendMissingDataError):
        backendManager.setProductProperty(productId, 'nothere', False,
                                          'testclient.domain.invalid')

    assert len(
        backendManager.productProperty_getObjects()) == expectedProperties
def client():
    return OpsiClient(id='foo.test.invalid')
def testSetProductPropertiesWithMultipleValues(backendManager):
    product = LocalbootProduct('testproduct', '1.0', '2')
    backendManager.product_insertObject(product)

    testprop = UnicodeProductProperty(productId=product.id,
                                      productVersion=product.productVersion,
                                      packageVersion=product.packageVersion,
                                      propertyId=u"rebootflag",
                                      possibleValues=["0", "1", "2", "3"],
                                      defaultValues=["0"],
                                      editable=False,
                                      multiValue=True)
    donotchange = UnicodeProductProperty(
        productId=product.id,
        productVersion=product.productVersion,
        packageVersion=product.packageVersion,
        propertyId=u"upgradeproducts",
        possibleValues=["firefox", "opsi-vhd-control", "winscp"],
        defaultValues=["firefox", "opsi-vhd-control", "winscp"],
        editable=True,
        multiValue=True)

    backendManager.productProperty_insertObject(testprop)
    backendManager.productProperty_insertObject(donotchange)

    client = OpsiClient('testclient.domain.invalid')
    backendManager.host_insertObject(client)

    depotIds = set()
    for depot in getDepotServers():
        depotIds.add(depot.id)
        backendManager.host_insertObject(depot)

    for depotId in depotIds:
        backendManager.setProductProperties(product.id,
                                            {testprop.propertyId: ["1", "2"]},
                                            depotId)

    result = backendManager.productProperty_getObjects(
        propertyId=donotchange.propertyId)
    assert len(result) == 1
    result = result[0]
    assert isinstance(result, UnicodeProductProperty)
    assert result.getPossibleValues() == [
        "firefox", "opsi-vhd-control", "winscp"
    ]
    assert result.getDefaultValues() == [
        "firefox", "opsi-vhd-control", "winscp"
    ]

    result = backendManager.productProperty_getObjects(
        propertyId=testprop.propertyId)
    assert len(result) == 1
    result = result[0]
    assert isinstance(result, UnicodeProductProperty)
    assert result.getPossibleValues() == ["0", "1", "2", "3"]
    assert result.getDefaultValues() == ["0"]

    results = backendManager.productPropertyState_getObjects()
    assert len(results) == len(depotIds)

    for result in results:
        assert result.getObjectId() in depotIds
        print("Checking {0!r}".format(result))

        if result.propertyId == donotchange.propertyId:
            assert result.getValues() == donotchange.getPossibleValues()
        elif result.propertyId == testprop.propertyId:
            assert result.getValues() == ["1", "2"]
        else:
            raise ValueError("Unexpected property state: {0!r}".format(result))
def testSetProductPropertyNotConcatenatingStrings(backendManager):
    product = LocalbootProduct('testproduct', '1.0', '2')
    backendManager.product_insertObject(product)

    testprop = UnicodeProductProperty(productId=product.id,
                                      productVersion=product.productVersion,
                                      packageVersion=product.packageVersion,
                                      propertyId=u"rebootflag",
                                      possibleValues=["0", "1", "2", "3"],
                                      defaultValues=["0"],
                                      editable=False,
                                      multiValue=False)
    donotchange = UnicodeProductProperty(
        productId=product.id,
        productVersion=product.productVersion,
        packageVersion=product.packageVersion,
        propertyId=u"upgradeproducts",
        possibleValues=["firefox", "opsi-vhd-control", "winscp"],
        defaultValues=["firefox", "opsi-vhd-control", "winscp"],
        editable=True,
        multiValue=True)

    backendManager.productProperty_insertObject(testprop)
    backendManager.productProperty_insertObject(donotchange)

    client = OpsiClient('testclient.domain.invalid')
    backendManager.host_insertObject(client)

    sideeffectPropState = ProductPropertyState(
        productId=product.id,
        propertyId=donotchange.propertyId,
        objectId=client.id,
        values=donotchange.getDefaultValues())
    backendManager.productPropertyState_insertObject(sideeffectPropState)

    backendManager.setProductProperty(product.id, testprop.propertyId, "1",
                                      client.id)

    result = backendManager.productProperty_getObjects(
        propertyId=donotchange.propertyId)
    assert len(result) == 1
    result = result[0]
    assert isinstance(result, UnicodeProductProperty)
    assert result.getPossibleValues() == [
        "firefox", "opsi-vhd-control", "winscp"
    ]
    assert result.getDefaultValues() == [
        "firefox", "opsi-vhd-control", "winscp"
    ]

    result = backendManager.productProperty_getObjects(
        propertyId=testprop.propertyId)
    assert len(result) == 1
    result = result[0]
    assert isinstance(result, UnicodeProductProperty)
    assert result.getPossibleValues() == ["0", "1", "2", "3"]
    assert result.getDefaultValues() == ["0"]

    results = backendManager.productPropertyState_getObjects()
    assert len(results) == 2

    for result in results:
        assert result.getObjectId() == client.id
        print("Checking {0!r}".format(result))

        if result.propertyId == donotchange.propertyId:
            assert result.getValues() == donotchange.getPossibleValues()
        elif result.propertyId == testprop.propertyId:
            assert result.getValues() == ["1"]
        else:
            raise ValueError("Unexpected property state: {0!r}".format(result))